Re: Quickie - Regexp for a string not at the beginning of the line
Rivka Miller writes: > On Oct 25, 2:27 pm, Danny wrote: >> Why you just don't give us the string/input, say a line or two, and >> what you want off of it, so we can tell better what to suggest > > no one has really helped yet. Really? I was going to reply but then I saw Janis had given you the answer. If it's not the answer, you should just reply saying what it is that's wrong with it. > I want to search and modify. Ah. That was missing from the original post. You can't expect people to help with questions that weren't asked! To replace you will usually have to capture the single preceding character. E.g. in sed: sed -e 's/\(.\)$hello\$/\1XXX/' but some RE engines (Perl's, for example) allow you specify zero-width assertions. You could, in Perl, write s/(?<=.)\$hello\$/XXX/ without having to capture whatever preceded the target string. But since Perl also has negative zero-width look-behind you can code your request even more directly: s/(? I dont wanna be tied to a specific language etc so I just want a > regexp and as many versions as possible. Maybe I should try in emacs > and so I am now posting to emacs groups also, although javascript has > rich set of regexp facilities. You can't always have a universal solution because different PE implementations have different syntax and semantics, but you should be able to translate Janis's solution of matching *something* before your target into every RE implementation around. > examples > > $hello$ should not be selected but > not hello but all of the $hello$ and $hello$ ... $hello$ each one > selected I have taken your $s to be literal. That's not 100 obvious since $ is a common (universal?) RE meta-character. -- Ben. -- http://mail.python.org/mailman/listinfo/python-list
Re: Quickie - Regexp for a string not at the beginning of the line
Rivka Miller writes: > Thanks everyone, esp this gentleman. Kind of you to single me out, but it was Janis Papanagnou who first posted the solution that you say "works best" for you. -- Ben. -- http://mail.python.org/mailman/listinfo/python-list
Re: meaning of [ ]
Rustom Mody writes: > On Sunday, September 3, 2017 at 5:10:13 PM UTC+5:30, Rick Johnson wrote: >> Andrej Viktorovich wrote: >> > I suppose p becomes array of strings but what [] means in this statement? >> >> Generally, it's an inline form of writing a loop that returns a >> list. There are other types as well. > > Tsk tsk the confusioning continues > > Rewrite > [p for p in sys.path] > as > [p | p ∈ sys.path] > > Is that clearer? > > And then as > > {p | p ∈ sys.path} > And refresh the idea of set-builder notation > http://www.mathwords.com/s/set_builder_notation.htm But [p for p in sys.path] is a list and "set-builder" notation is used for sets. Order is crucial for sys.path. You say exactly that below so I don't see how referring to sets helps anyone understand lists. > As Peter pointed out this is a no-op > ie > [p for p in sys.path] > > could be written as > list(sys.path) Both make a copy -- that's not a no-op. It may be a very-little-op but not nothing. > [Not sure why he didnt say just sys.path] Because he wanted code equivalent to [p for p in sys.path]. > Anyway this is a good example to distinguish > > [p for p in sys.path] > from > {p for p in sys.path} > > Both work in python > But the second is probably not correct because path-searching is order > dependent Right. So i'm puzzled why you suggest that [p for p in sys.path] should be understood by reading about set-builder notation. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Please improve these comprehensions (was meaning of [ ])
Rustom Mody writes: > Here is some code I (tried) to write in class the other day > > The basic problem is of generating combinations > Now thats neat as far as it goes but combinations are fundamentally sets > not lists > > So I thought python would do a better job > I tried translating it to python and sets but it turned out more annoying than > helpful > Can someone improve it?? > > The straightforward translation of the above > Which is ok so far > > > def c(n,r): > if r == 0: > return [[]] > elif len(n) == 0: > return [] > else: > return [[n[0]] + l for l in c(n[1:],r-1)] + c(n[1:],r) > > > Now to go from returning list of lists to set of sets: def cs(n, r): if r == 0: return [set()] elif len(n) == 0: return [] else: return [set([n[0]]) | l for l in cs(n[1:], r-1)] + cs(n[1:], r) ? It's not so neat if you also want n to be a set rather than a list because the set equivalents of n[0] and n[1:] are a but more complex but it's not that bad: def css(n,r): if r == 0: return [set()] elif len(n) == 0: return [] else: rest = n.copy() e = rest.pop() return [set([e]) | l for l in css(rest, r-1)] + css(rest, r) -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Please improve these comprehensions (was meaning of [ ])
Rustom Mody writes: > On Tuesday, September 5, 2017 at 1:44:24 AM UTC+5:30, Ben Bacarisse wrote: >> Rustom Mody writes: >> >> > Here is some code I (tried) to write in class the other day >> > >> > The basic problem is of generating combinations >> >> > Now thats neat as far as it goes but combinations are fundamentally sets >> > not lists >> > >> > So I thought python would do a better job >> > I tried translating it to python and sets but it turned out more annoying >> > than >> > helpful >> > Can someone improve it?? >> > >> > The straightforward translation of the above >> > Which is ok so far >> > >> > >> > def c(n,r): >> > if r == 0: >> > return [[]] >> > elif len(n) == 0: >> > return [] >> > else: >> > return [[n[0]] + l for l in c(n[1:],r-1)] + c(n[1:],r) >> > >> > >> > Now to go from returning list of lists to set of sets: >> >> def cs(n, r): >> if r == 0: >> return [set()] >> elif len(n) == 0: >> return [] >> else: >> return [set([n[0]]) | l for l in cs(n[1:], r-1)] + cs(n[1:], r) >> >> ? >> >> It's not so neat if you also want n to be a set rather than a list >> because the set equivalents of n[0] and n[1:] are a but more complex but >> it's not that bad: >> >> def css(n,r): >> if r == 0: >> return [set()] >> elif len(n) == 0: >> return [] >> else: >> rest = n.copy() >> e = rest.pop() >> return [set([e]) | l for l in css(rest, r-1)] + css(rest, r) > > Trying out your code Ben… > >>>> css({1,2,3,4}, 2) > [set([1, 2]), set([1, 3]), set([1, 4]), set([2, 3]), set([2, 4]), set([3, 4])] > >>>> type(css({1,2,3,4}, 2)) > > > Whereas with the cs I earlier gave: >>>> cs(frozenset([1,2,3,4]), 2) > frozenset([frozenset([2, 4]), frozenset([3, 4]), frozenset([2, 3]), > frozenset([1, 3]), frozenset([1, 2]), frozenset([1, 4])]) If you want a (frozen) sets of sets I'd just the code to def css(n, r): if r == 0: return frozenset({frozenset()}) elif len(n) == 0: return frozenset() else: rest = set(n) e = rest.pop() return frozenset([frozenset([e]) | l for l in list(css(rest, r-1))]) | css(rest, r) >>> css(frozenset({1,2,3,4}), 2) frozenset({frozenset({2, 4}), frozenset({3, 4}), frozenset({2, 3}), frozenset({1, 3}), frozenset({1, 2}), frozenset({1, 4})}) The switch from lists (using +) and frozen sets using | is the most obvious change, but if the top-level argument might itself be a frozenset then the copy must be changed to a set constructor so that pop will work. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Please improve these comprehensions (was meaning of [ ])
Gregory Ewing writes: > Seems to me you're making life difficult for yourself (and > very inefficient) by insisting on doing the whole computation > with sets. If you want a set as a result, it's easy enough > to construct one from the list at the end. Yes, but my intent was to show that the pattern -- derived from counting choices -- transfers to the construction of choices, even when sets are used in place of lists. I was responding to what I thought was the idea that you can't work with sets in the same way. And I see I messed a place where I should have used a set but that's just stylistic. Converting the list-of-list version to a set of (frozen) sets is about twice as fast. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Please improve these comprehensions (was meaning of [ ])
Rustom Mody writes: > I posted it because I genuinely thought I had missed some obvious way > of splitting a set into an (arbitrary) element and a rest without > jumping through hoops. Evidently not Curious, because I posted because I thought you had. Anyway, for speed you probably just want def cs(n, r): return frozenset({frozenset(s) for s in c(n, r)}) as suggested. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Please improve these comprehensions (was meaning of [ ])
Chris Angelico writes: > On Thu, Sep 7, 2017 at 5:59 PM, Marko Rauhamaa wrote: >> Dennis Lee Bieber : >> >>> On Wed, 06 Sep 2017 10:37:42 +0300, Marko Rauhamaa >>> declaimed the following: >>> Which reminds me of this puzzle I saw a couple of days ago: 1 + 4 = 5 2 + 5 = 12 3 + 6 = 21 8 + 11 = ? A mathematician immediately comes up with a "wrong" answer. >>> >>> I'm coming up with "96", on the basis that the "+" is a >>> placeholder for a non-standard operation >> >> That's a mathematician's "wrong" answer. Stefan Ram's answer is the >> intended one. > > Ian's answer has better justification. I'm going to support "banana". Solving puzzles like this should come with a pleasing "ah!" moment which usually comes from finding a simple rule or explanation. An arbitrary answer is always possible, but it is rarely a rule, and although arbitrary rules are also possible, they will rarely be simple. (On average a rule will need at least as many symbols to be described as the puzzle itself[1].) The trouble with this puzzle is that has at least two answers that are simple rules and, to my mind, neither has a pleasing "ah!" associated with it. [1] Obviously this is not formal but it could be made so by reference to algorithmic complexity. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: A question on modification of a list via a function invocation
Steve D'Aprano writes: > On Fri, 8 Sep 2017 12:28 am, Chris Angelico wrote: > >> languages without mutable objects don't >> really care whether they're pass-by-X or pass-by-Y. > > Only if you don't care about efficiency. > > Believe me, the first time you pass a five gigabyte array to a function using > pass-by-value, on a machine with only six gigabytes of memory, you'll care. I think your general idea to separate language semantics from implementation details is a good one, but you've dropped it here. A language with call-by-value semantics need not copy large objects when passing them to a function. The program must behave *as if* there is a copy but there need not actually be one. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: tictactoe script - commented - may have pedagogical value
Ian Kelly writes: > On Thu, Sep 7, 2017 at 2:05 AM, Chris Angelico wrote: >> On Thu, Sep 7, 2017 at 5:11 PM, Steven D'Aprano >>> I don't know why it places *two* pairs of crosses and naughts instead of >>> one. Maybe the page is broken. >> >> I think it is, as part of being on the Internet Archive. To get a >> working version of the game, you may need to download it locally and >> clean it up a bit. > > I was also very confused at first. I found that you need to hide the > Internet Archive header because it covers the current board. It is > also surprising in that the player's move is recorded with 'O' despite > going first, which is contrary to the conventions of the game. Yes, the fact that it's archived is annoying. I thought it was a neat-enough idea to be worth doing cleanly, so I had a go: http://bsb.me.uk/ttt/ The HTML is obviously generated by a program, and one can generate lots of variations (even ones that will loose some games) but that can't be done in HTML -- the complete, fixed, tree of accessible positions must be there in the page before play starts. (I know this is an old thread now, but Real Life got in the way of programming as it so annoyingly does sometimes.) -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Old Man Yells At Cloud
Steve D'Aprano writes: > [...] try something more common: > > 1/2 > > Most people aren't expecting integer division, but true division, and silently > returning the wrong result (0 instead of 0.5) is a silent source of > bugs. I'm the sure that expectation depends on their background and previous programming experience, and since I don't know much about most people when they first write 1/2 in Python, I must conceded that you may be right. But is that really the point? Was the result of 1/2 determined by a poll to find out what most people expected? If so, who were these people -- the result would depend very largely on the selection? But there is a stronger claim (which I think you also made) that a floating point result is the correct one. However, some people with little experience of floating point arithmetic (I certainly can't say most but it must be quite few) will expect 1/10 to return a tenth. For /them/, the floating point result is silently wrong and a source of bugs. If I were aiming a language at beginners, I'd make 1/10 be a rational or a type error. However, I don't think that is Python's main demographic, so 1/10 giving something not quite one tenth may well be the correct design choice. > And 1/2 doesn't have to return an int. Why is this such a big deal? I'm sure it's not deliberate, but 1/2 is a bad example because it can be exactly represented in the most common implementations. To get a more fruitful exchange of views, a division like 1/3 or 1/10 might be a better example. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Old Man Yells At Cloud
Steve D'Aprano writes: > To answer your question, what do I mean by int/int being undefined, I'd have > to > dig into areas of maths that either weren't taught in the undergrad courses I > did, or that I've long since forgotten about. Something > about... fields? > This is a pretty specialised area of maths. You won't learn anything > about it in high school. And possibly not undergrad maths degrees. I > seem to vaguely recall just barely touching on groups, but not rings > or fields. When you said before that you thought that undefined division was rather obscure I was going to mention that it's the basic difference between a ring and a field; the intent being that you'd go "oh, yes, of course it's not obscure at all". I'm glad I didn't now, because you would not have seen it as the simple notion I expected! Teaching rings and fields is (or at least was 30 or so years ago) 1st year undergraduate maths here in the UK. Maybe it's changed. BTW, I don't think this has anything to do with what 1/3 should be in Python. Python as no interest in rings and fields -- it's purely a pragmatic decision. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Old Man Yells At Cloud
bartc writes: > On 18/09/2017 15:04, Gregory Ewing wrote: >> Dennis Lee Bieber wrote: >>> Pascal >>> provides print()/println() [okay, not /statements/ but /procedures/] >> >> Actually write/writeln, and although they used parens like >> procedures, they had special syntax for output formatting >> that wasn't available to user-defined procedures, so they >> were at least as special as the py2 print, maybe more so. > > They HAD to be special, because that language was statically > typed. You couldn't define a user-code procedure or function that took > all possible types. That's not right. It's true of Pascal's specific type system, but you /can/ have a strong, statically-checked type system /and/ a user-written generic print function. There will be compromises and complexities (in both the language design and in the print function) that might, in the end, be considered unacceptable, but the static nature of the typing does not, on its own, preclude it. A former colleague's PhD thesis (about 1978 I think) was about types in programming language design. The central question that was repeatedly asked was whether a universal print function could be written in this or that language. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Old Man Yells At Cloud
bartc writes: > Value-Added-Tax in the UK increased from 17.5% to 20%, ... When it was 17.5% you could shock people not in the know by working it out in your head since it's much simpler than it sounds: take a tenth, halve it, halve it again, and add all three. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Even Older Man Yells At Whippersnappers
Larry Martell writes: > On Tue, Sep 19, 2017 at 12:12 PM, Rhodri James wrote: >> >> Eh, my school never 'ad an electronics class, nor a computer neither. Made >> programming a bit tricky; we 'ad to write programs on a form and send 'em >> off to next county. None of this new-fangled VHDL neither, we 'ad to do our >> simulations with paper and pencil. >> > > We dreamed of writing programs on a form. We had to make Hollerith > punch cards by hand using a dull knife. You tell that to the kids of > today and they won't believe you. Dull knife, was it? Luxury! We had to dab at card wi' tongue 'till it were wet enough to punch with a whittled stick. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Printing a Chunk Of Words
r...@zedat.fu-berlin.de (Stefan Ram) writes: > Cai Gengyang writes: >> Boolean Operators >> >>True and True is True >>True and False is False >>False and True is False >>False and False is False >>True or True is True >>True or False is True >>False or True is True >>False or False is False >>Not True is False >>Not False is True >>If I simply want to print a chunk of words and a paragraph >>like the above, what command should I use ? > > The following has about the same size as the original: > > S=' Boolean Operators//1&1=' +\ > '1/1&0=0/0&1=0/0&0=0//1|1=1/1|0=1/0|1=1/0|0=0//!1=0/!0=1' > def D(x,y):global S; S=S.replace(x,y) > > D('/','\n');D('1','True');D('0','False');D('&',' and '); > D('|',' or ');D('!','Not ');D('=',' is ');D('!','Not '); > print(S) > > I wrote it just as an attempt to create a shorter piece > of source code, but I failed. Think functional! This is 257 characters: def D(x,y,s):return s.replace(x,y) print(D('1','True',D('0','False',D('&',' and ',D('|',' or ',D('!','Not ',D('=',' is ',D('!','Not ',""" Boolean Operators 1&1=1 1&0=0 0&1=0 0&0=0 1|1=1 1|0=1 0|1=1 0|0=0 !1=0 !0=1""" And applying the same idea twice I can get 255: def D(x,y,s):return s.replace(x,y) print(eval(D('"D','D("',D(',','","','''"D-,--,D1,True,D0,False,D&, and ,D|, or ,D!,Not ,D=, is ,D!,Not ,"" Boolean Operators 1&1=1 1&0=0 0&1=0 0&0=0 1|1=1 1|0=1 0|1=1 0|0=0 !1=0 !0=1"""''' -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: on a very slow function
Daniel Bastos writes: > def make_sequence_non_recursive(N, x0 = 2, c = -1): > "What's wrong with this function? It's very slow." > last = x0 > def sequence(): > nonlocal last > next = last > last = last**2 + c > return next % N > return sequence > > It crawls pretty soon. Please advise? A mathematical rather than Python answer... change it to last = (last**2 + c) % N return next -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: on a very slow function
Steve D'Aprano writes: > On Mon, 2 Oct 2017 09:49 am, Ben Bacarisse wrote: > >> Daniel Bastos writes: >> >>> def make_sequence_non_recursive(N, x0 = 2, c = -1): >>> "What's wrong with this function? It's very slow." >>> last = x0 >>> def sequence(): >>> nonlocal last >>> next = last >>> last = last**2 + c >>> return next % N >>> return sequence >>> >>> It crawls pretty soon. Please advise? >> >> A mathematical rather than Python answer... > > Which is the best sort of answer. When possible, simplifying your algorithm is > better than speeding up your code. > >> change it to >> >> last = (last**2 + c) % N >> return next > > Better: > > last = (pow(last, 2, N) + (2 % N)) % N You meant c rather than 2, I think. And I'm not convinced all the %Ns are worth while. Will typical implementations spot that c does not change and calculate c % N only once? Also, a very naive test (I don't know much about how to profile Python) suggests that my line is faster for the specific N being used in the OP's example. > will almost certainly be faster for large values of last. Do you mean for large values of N? If the calculations are mod N, it seems like N will the number that matters. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: on a very slow function
Steve D'Aprano writes: > On Mon, 2 Oct 2017 12:00 pm, Ben Bacarisse wrote: > > >>> Better: >>> >>> last = (pow(last, 2, N) + (2 % N)) % N >> >> You meant c rather than 2, I think. > > Oops, yes, that was a typo. > > >> And I'm not convinced all the %Ns >> are worth while. > > They are all necessary. I meant for the program. It makes no difference to the result if last is left entirely un-reduced (that was the original problem) so there is no need (as far as the program is concerned) to ensure that last is fully reduced. Another naive timing tests suggests that last = (pow(last, 2, N) + (c % N)) % N is measurably slower than last = (pow(last, 2, N) + c) % N and last = pow(last, 2, N) + c is a little faster still. None of these allow last to grow uncontrollably. Obviously we need to know more about the potential range of N and c to do any realistic measurements. >>> will almost certainly be faster for large values of last. >> >> Do you mean for large values of N? If the calculations are mod N, it >> seems like N will the number that matters. > > No, I meant "last". Although on testing, I think you might need so really big > values before you'll see a difference. Like hundreds of digits or > more. Ah, again I meant for the program. Any large value of last will exist for one call only. Obviously there will be /some/ point at which a single call to the the three arg version of pow is better than ** and %, but for that to sustained (in the program), N must be huge too. Another simple test suggests that last * last is faster than last**2 so the best so far (for the N and c originally posted) is the simpler: last = (last * last + c) % N Again I mean in the program as posted, not as a line on its own with arbitrary values of 'last'. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
Steve D'Aprano writes: > On Wed, 4 Oct 2017 04:45 am, Rhodri James wrote: > >> On 03/10/17 18:29, Stefan Ram wrote: >>>Is this the best way to write a "loop and a half" in Python? >> >> Define "best". > > I'd start with "define loop and a half". What it means to me is this pattern: while True: ... statements that don't exit the loop ... if condition: break ... more statements that don't exit the loop ... When the first set of statements is null, it's just a while loop. When the second is null, it's just a do ... while (in languages that have it). Where both sets are present some languages encourage putting the first set into the condition of the loop. For example, in Algol 68 an expression can be replaced by a statement sequence that ends in an expression. C encourages the same, provided the first set of statements is very simple. The classic example being while ((some_var = some_input_function()) != some_error_value) { ... process some_var ... } In Pascal, you sometimes had to duplicate the first set of statements: ... statements that don't exit the loop ... while condition begin ... more statements that don't exit the loop ... ... statements that don't exit the loop ... end -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
r...@zedat.fu-berlin.de (Stefan Ram) writes: > Steve D'Aprano writes: >>For-each loops are MUCH easier to understand, and should be taught first. > > I prefer a bottom-up approach. > > For loops are based on iterators. > > So, "bottom-up" in this case means: iterators should be > taught before for-loops. > > But iterators are too abstract to be taught very early. I think this may be a problem with your style. From your other postings, I think you value precision and exactness over broad understanding, and maybe you teach like that. I my view, it's possible to explain enough about iterators to understand a huge range of for loops without having to go into the gory details. I find the image of a conjurer pulling knotted hankies out of a hat a good one -- they may go on forever and you don't know if there is rabbit in there knotting them and deciding which colour comes next. > But I will teach iterators and for loops not much later than > while-loop. > > Maybe this way: Use a while-loop and try-catch to get values > from an iterator until exhausted, and then introduce the > for-loop as an abbreviation for that. That sounds very complicated, but I think I favour the other extreme to you. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
r...@zedat.fu-berlin.de (Stefan Ram) writes: > bartc writes: >>Note that your reverse-indentation style is confusing! > > In Python, indentation can be significant. > > Sometimes, some lines in Python must be indented by 0. > > This dictates that Python code cannot be indented > in posts to differentiate it from the natural-language > body of the post. Therefore, it's rather the > natural-language body that has to be indented. It does not /dictate/ it. It just makes it convenient for people with certain news readers. If you posted def f(x): return x*x I can select the block starting in column 2 and paste it into a python REPL quite easily. I prefer software that copes with existing conventions rather than have the conventions change to make it easy for the software. But if I felt I should not indent my python code, I would certainly not indent my text commentary. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Easier way to do this?
20/20 Lab writes: > Looking for advice for what looks to me like clumsy code. > > I have a large csv (effectively garbage) dump. I have to pull out > sales information per employee and count them by price range. I've got > my code working, but I'm thinking there must be a more refined way of > doing this. I second the suggestion to use the CSV module. It's very simple to use. > ---snippet of what I have--- > > EMP1 = [0,0] > EMP2 = [0,0] > EMP3 = [0,0] > > for line in (inputfile): > content = line.split(",") > if content[18] == "EMP1": > if float(content[24]) < 99.75: > EMP1[0] += 1 > elif float(content[24]) > 99.74: > EMP1[1] += 1 > if content[18] == "EMP2": > if float(content[24]) < 99.75: > EMP2[0] += 1 > elif float(content[24]) > 99.74: > EMP2[1] += 1 > if content[18] == "EMP3": > if float(content[24]) < 99.75: > EMP3[0] += 1 > elif float(content[24]) > 99.74: > EMP3[1] += 1 > > and repeat if statements for the rest of 25+ employees. Eek! When you have named objects selected using a string that is the object's name you know you want a dict. You'd have a single dict for all employees, keyed by the tag in field 18 of the file. Does that help? I'm deliberately not saying more because this looks like a learning exercise and you probably want to do most of it yourself. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Pedagogical style [was Re: The "loop and a half"]
Steve D'Aprano writes: > There's no link to the original paper, only to secondary sources that discuss > it, e.g.: > > http://phys.org/pdf128266927.pdf > [1] Anecdotes are not data, but for what it is worth, just in the last two > days I came across two examples of this. Teaching a boy in Year 10 maths > about logarithms, he struggled with purely algebraic questions involving > solving exponential equations by using logs, but when given a concrete > problem involving an investment he was able to solve it immediately. > > The second example involved a girl in Year 8 maths, who again struggled with > abstract questions about adding and multiplying fractions. In particular, she > overgeneralised from fraction multiplication to addition, thinking that 1/4 + > 1/4 must add to 2/8. But when put into concrete geometric terms, showing > physical shapes divided into quarters, she could instantly tell that 1/4 plus > 1/4 must be 1/2. > > As I said, anecdotes are not data, but when research claims to show that > apples fall upwards in contradiction to anecdotal evidence that they fall > downwards, we would be wise to be cautious before accepting the research as > fact. I think the paper is this one: http://faculty.psy.ohio-state.edu/sloutsky/pdf/KSH-published.pdf (You can find more recent papers by searching the Ohio State University site.) >From what I've read, your anecdotes are not in contradiction to the paper's claims. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
Steve D'Aprano writes: > On Fri, 6 Oct 2017 09:57 am, Marko Rauhamaa wrote: > > [quoting Bart] Yes, I tried typing 'sort' in Linux, where it apparently hangs (same on Windows actually). The reason: because it might have killed someone to have added a message saying what you are expected to type and how to end it. (Namely, press Ctrl-D start at the start of a line in Linux, and Ctrl-Z followed by Enter, I think also at the start, in Windows.) > > Waiting for input isn't "hangs". That's an ignorant and foolish thing to say, > more suited for a wet-behind-the-ears newbie than somebody who claims to be a > long-time old-school programmer. I suspect it's a wind-up. > [Marko] >> As for informational messages, it is part of deep-seated Unix culture to >> have quiet commands. The purpose of the silence is so you can easily >> compose new commands out of existing commands via pipelines and scripts. >> It would be inconvenient if you typed the command: >> >> grep ython message.txt | sort >> >> and the sort command instructed you to press Ctrl-D. > > Indeed it would. > > But in fairness, if the author of the `sort` command had a commitment to > friendliness in their programs, they could have `sort` only print a message > when it is reading from stdin and writing to stdout, I think you mean "when reading from a terminal". In the example given sort /is/ reading from stdin and writing to stdout. > much as `ls` defaults to > outputting control characters but automatically swaps to replacing them > with ? when writing to a terminal. ls often behaves completely differently when writing to a terminal. The main one is that it tabulates the file names into columns! That's very old behaviour. A more modern innovation is coloured output. > I believe that even Unix experts would be more effective with a judicious > amount of not so much hand-holding as gentle guidance. Even experts aren't > expert on every single command line tool. That's true. Some of it is here already. I am addicted to tab completion, especially when it is command-aware. And there's a flip side. I've come across a few too many programs lately clearly written by people who want to be helpful, but the wordy output is hard to parse when using the program in a script. Some programs offer a flag to simplify the output so it can be processed more easily, but not all... > But the OS is what it is, and the culture has a certain level of commandline > machismo, so that's unlikely to change. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Interactive scripts (back on topic for once) [was Re: The "loop and a half"]
Chris Angelico writes: > On Fri, Oct 6, 2017 at 7:09 PM, Steve D'Aprano > wrote: >> What are the right ways for a Python script to detect these sorts of >> situations? >> >> (1) Standard input is coming from a pipe; >> >> (2) Stdin is being read from a file; >> >> (3) Stdin is coming from a human at a terminal; >> >> I get these. How did I do? >> >> # 3 detect a terminal, hopefully with a human typing at it >> if os.isatty(0): >> print("Oy noddy, wake up and type something, I'm waiting for you!") > > This ought to be the only one that matters. It's the closest thing you > have to "we're working in interactive mode". Generally speaking, you > shouldn't care about the difference between a pipe and a file; and > remember, you can have stdin be anything else, too (eg a Unix or TCP > socket). Yes. I'd say the key differences is whether the input is seekable or not. A program might legitimately choose different algorithms based on that property of the input, but whether it's an actual file or an actual pipe is less likely to be interesting. >> I feel a bit weird about using the magic constant 0 here. Is that guaranteed >> to be stdin on all platforms? Or should I be using >> sys.stdin.fileno()? A general solution to the (rather odd) complaint about silent waiting should really check any input fileno to see if a prompt is needed. You could argue, though, that anyone who's re-arranged a program's input so that some non-zero input fileno is attached to a terminal won't need the prompt! -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Interactive scripts (back on topic for once) [was Re: The "loop and a half"]
Steve D'Aprano writes: > On Fri, 6 Oct 2017 09:33 pm, Ben Bacarisse wrote: > >> A general solution to the (rather odd) complaint about silent waiting >> should really check any input fileno to see if a prompt is needed. You >> could argue, though, that anyone who's re-arranged a program's input so >> that some non-zero input fileno is attached to a terminal won't need the >> prompt! > > I'm afraid I don't quite know if I'm understanding you or not. > > I think you mean to say I should look at sys.stdin.fileno(), and if it is 0, > then write a prompt, and if not, just read from stdin (possibly blocking, > waiting for input). > > Is that right? > > But aren't there circumstances where fileno 0 isn't attached to a terminal, > and writing a prompt would be inappropriate? No. The point was that other file descriptors might be associated with a terminal. I could, for example, switch the input to an interactive program that interprets command to be done on some data file so that the supposedly interactive commands come form a file and I type the data at a terminal. The second point was anyone doing this probably does not need a hint about tying something. But this detail about other inputs opened by the program aside, it seems to me that what BartC (and others who want this) needs is a beginners shell that prints a helpful text whenever it starts a program (or pipeline of programs) with stdin attached to the terminal. It's not really something that every individual program should have to tackle. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
bartc writes: > On 06/10/2017 14:35, Paul Moore wrote: >> On 6 October 2017 at 13:56, bartc wrote: >>> If you don't like the word 'crude', try 'lazy'. Take this example of the gcc >>> C compiler: >>> >>> > gcc -E program.c >>> >>> This preprocesses the code and shows the result. Typical programs will have >>> many thousands of lines of output, but it just dumps it to the console. You >>> /have/ to use '>' to use it practically (Windows doesn't really have a >>> working '|' system.) Does the Windows version of gcc not support the -o file option? >> No you don't. Ignoring the fact that "windows doesn't really have a >> working '|' system" (which is an oversimplification, by the way) the >> following all work: >> >> Python: >> data = subprocess.check_output(["gcc", "-E", "program.c"]) >> Powershell: >> $x = (gcc -E program.c) >> cmd: >> for /f %i in ('gcc -E program.c') do ... >> >> If gcc -E wrote its output to a file, you'd have to read that file, >> manage the process of deleting it after use (and handle possible >> deletion of it if an error occurred), etc. > > But if I use the -S option (show assembly listing) that DOES output to > a file (program.s). And a good system lets you alter that. How many labels are generated for some code? Let's see: gcc -S -o /dev/stdout t.c | grep -c '^\.L' Now gcc also permits -o - (it's a common Unix convention) but you can almost always get round less helpful programs using /dev/sdout. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
bartc writes: > It is anyway not really acceptable these days for a long list of data > to simply be typed in like that without any feedback at all. And 100% > dependent on your typing Ctrl-D at the end and not Ctrl-C by > mistake. This is not still the 1970s. It was not acceptable in the 1970s either. No one did it then and no one does it now. What you are actually saying is that it is not acceptable that the option of unprompted input even exists. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
bartc writes: > On 07/10/2017 01:14, Ben Bacarisse wrote: >> bartc writes: >> >>> On 06/10/2017 14:35, Paul Moore wrote: >>>> On 6 October 2017 at 13:56, bartc wrote: >>>>> If you don't like the word 'crude', try 'lazy'. Take this example of the >>>>> gcc >>>>> C compiler: >>>>> >>>>>> gcc -E program.c >>>>> >>>>> This preprocesses the code and shows the result. Typical programs will >>>>> have >>>>> many thousands of lines of output, but it just dumps it to the console. >>>>> You >>>>> /have/ to use '>' to use it practically (Windows doesn't really have a >>>>> working '|' system.) >> >> Does the Windows version of gcc not support the -o file option? > > I never thought of trying it. But OK, you have to use -o or > to stop > the output from swamping the console. (| might work if I could find a > program that captured the piped output for the purpose of browsing.) >> And a good system lets you alter that. How many labels are generated >> for some code? Let's see: >> >>gcc -S -o /dev/stdout t.c | grep -c '^\.L' >> >> Now gcc also permits -o - (it's a common Unix convention) but you can >> almost always get round less helpful programs using /dev/sdout. > > I'm not really arguing against this. I'm disputing the suggestion that > because these utilities, which are rarely given data actually typed > from the keyboard, work by reading from stdin using an eof-checking > loop, that the same method must always be used in programs that really > are reading data from the keyboard. And I'm not arguing about that -- I know there is no point. The way Usenet works is that I reply to the parts I want to comment on. No one can see what made me make the above remark because you cut it, but the combined effect of the two remarks of yours that I commented on was to suggest that gcc makes arbitrary choices about output destinations (and I assume gcc was just an example). I was simply saying that a good OS can finesse such matters. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Bill writes: > Mikhail V wrote: > [...] I'm not here to "cast stones", I like Python. I just think > that you shouldn't cast stones at C/C++. Not while PHP exists. There aren't enough stones in the world... >>> PHP seems (seemed?) popular for laying out web pages. Are their vastly >>> superior options? >> Python? Superior syntax for sure > > I believe that. What accounts for the popularity of PHP then? Two things, probably. First, it was almost always pre-installed even on low-cost hosting. Second, you could start very simply because it was designed to be used embedded. Tiny little bits of code could so something -- not need for a "framework". Other languages were not always installed (I'm sure it's better these days) and those that were (Perl almost always was) could not, by default, be used embedded -- you had to generate the whole page. What is (or are) the Python way (or ways) to do it? -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Chris Angelico writes: > On Thu, Oct 12, 2017 at 7:42 AM, Ben Bacarisse wrote: >> Bill writes: >> >>> Mikhail V wrote: >>>>>>> [...] I'm not here to "cast stones", I like Python. I just think >>>>>>> that you shouldn't cast stones at C/C++. >>>>>> Not while PHP exists. There aren't enough stones in the world... >>>>>> >>>>> PHP seems (seemed?) popular for laying out web pages. Are their vastly >>>>> superior options? >>>> Python? Superior syntax for sure >>> >>> I believe that. What accounts for the popularity of PHP then? >> >> Two things, probably. First, it was almost always pre-installed even on >> low-cost hosting. Second, you could start very simply because it was >> designed to be used embedded. Tiny little bits of code could so >> something -- not need for a "framework". >> >> Other languages were not always installed (I'm sure it's better these >> days) and those that were (Perl almost always was) could not, by >> default, be used embedded -- you had to generate the whole page. >> >> What is (or are) the Python way (or ways) to do it? > > Check out Django and Flask, the two most popular ways. I quite like > Flask. I see. Both appear to be frameworks (I'd heard of Django). Do you know if they widely available on low-cost hosting packages? (I don't think they are on mine, but that's dirt-cheap because I don't use it for anything important!) One thing that helped PHP was that it could be used (and learned) in an incremental way. You could add a "this page last updated on..." text in a line or two to an existing page. Then a button to change the layout or theme. Then a simple form and so on. Many professionals started that way. In the early days, there ware few other routes into the technical side of web authoring. That helped to cement PHP as the dominant technology because it was what they knew. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Gregory Ewing writes: > bartc wrote: > >> tokenrec * (*)[] >> >> the original source and that type is written like this: >> >> ref [] ref tokenrec > > The idiomatic way to write that type in C would be > >tokenrec ** That's a different type. I think you mean that a human writing C (rather than bartc's code generator) would probably design the code to use tokenrec ** then I agree, but the latter is not just a different way to write the former. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
r...@zedat.fu-berlin.de (Stefan Ram) writes: > Ben Bacarisse writes: >>That's a different type. I think you mean that a human writing C >>(rather than bartc's code generator) would probably design the code to >>use tokenrec ** then I agree, but the latter is not just a different way >>to write the former. > > That most difficult thing in C in the realm of type > declarations for me is: > > Define a function »g« with a parameter »x« of type »int«, so > that this function »g« returns a pointer to another function. > This other function has a parameter of type »char« and returns > a double value. > > /Without/ a typedef. You read a C type from the "inside out", going right if you can and left when you can't. That rule can be reversed to built up the type: You know it has (read "g is a function taking an int") g(int x) and since g returns a pointer you will have *g(int x) But it returns a pointer to a function taking a char so we must add (char) on the right but the brackets can't go here: *g(int x)(char) because then you would be read "function taking a char" before the pointer to. We need extra brackets to stop us reading right until we've read left: (*g(int x))(char) This forces "g is a function taking int returning a pointer to...". Finally, we just need the type of the function whose pointer is being returned: double (*g(int x))(char) Check with you finger on the name and reading right when you can and left when you can't (because of brackets). And then you re-write it using a typedef. Knowing how is simply interesting, not useful. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Chris Angelico writes: > On Thu, Oct 12, 2017 at 9:44 AM, Ben Bacarisse wrote: >> Chris Angelico writes: >>> Check out Django and Flask, the two most popular ways. I quite like >>> Flask. >> >> I see. Both appear to be frameworks (I'd heard of Django). Do you know >> if they widely available on low-cost hosting packages? (I don't think >> they are on mine, but that's dirt-cheap because I don't use it for >> anything important!) > > Generally, low-cost hosting will offer Python, and then you can > install Flask/Django from there. For example, you can deploy to Heroku > (zero-dollar hosting for small sites), and as long as you provide a > file called "requirements.txt", they'll install whatever you depend > on. > >> One thing that helped PHP was that it could be used (and learned) in an >> incremental way. You could add a "this page last updated on..." text in >> a line or two to an existing page. Then a button to change the layout >> or theme. Then a simple form and so on. >> >> Many professionals started that way. In the early days, there ware few >> other routes into the technical side of web authoring. That helped to >> cement PHP as the dominant technology because it was what they knew. > > Yeah. The trouble is that this is a really REALLY bad way to design > something. Yes, I know that's the way of the devil, just I'm explaining why PHP is popular! > Have you seen a city that grew one house at a time, and had > streets added to service those houses? Not good. The end result is > that PHP is still bound by this "just a bit of scripting inside your > HTML" structure, which has annoying consequences in certain areas > (like whitespace before the first " situations, and the way "include" works), plus it binds your URLs to > the concrete file system. That may not seem like too much of a > problem, but it's a pretty big limitation; you can't have URLs like > "https://en.wikipedia.org/wiki/Foo"; without some help from the web > server, eg Apache's mod_rewrite. I don't follow this. Your "can't" and "big limitation" suggests something inevitable, but I don't see it as an intrinsic problem with the language. I'm sure PHP is not as flexible as the frameworks you mention, but you are not tied to URLs mapping to files. Maybe you meant that this is what often happens, or what most people do, with PHP. > In contrast, Python and Flask would > handle that like this: > > @app.route("/wiki/") > def show_article(article): > ... > > Have a think about what the PHP setup implies. Arbitrary files in your > web server tree are not just automatically available (as they'd be if > you use flat-file hosting like GitHub Pages), but they are > *executable*. You don't have to set the file mode to say "this is > executable", you just have to have the file there with the appropriate > name. So PHP-based web sites end up having to monitor their uploads > and downloads lest someone slip something in and then run it on the > server... with full permissions. With Flask, in contrast, you can make > an uploads directory that's automatically downloadable, but nothing in > it will ever be executed. Yes, it's fraught with security issues. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Chris Angelico writes: > On Thu, Oct 12, 2017 at 11:55 AM, Ben Bacarisse wrote: >> Chris Angelico writes: >>> it binds your URLs to >>> the concrete file system. That may not seem like too much of a >>> problem, but it's a pretty big limitation; you can't have URLs like >>> "https://en.wikipedia.org/wiki/Foo"; without some help from the web >>> server, eg Apache's mod_rewrite. >> >> I don't follow this. Your "can't" and "big limitation" suggests >> something inevitable, but I don't see it as an intrinsic problem with >> the language. I'm sure PHP is not as flexible as the frameworks you >> mention, but you are not tied to URLs mapping to files. Maybe you meant >> that this is what often happens, or what most people do, with PHP. > > How would you, with PHP itself, handle database-provided URLs? The > only way I've ever seen it done is at an external level - such as > mod_rewrite - which means that someone else, *not* the PHP script, is > managing your URLs. They're pushed to some external config file > somewhere. That's okay for just one URL pattern, but it doesn't scale > well, which is why (for example) Wikipedia's editing pages are > "/w/index.php?" instead of, say, "/wiki/Foo/edit" or > "/wiki/edit/Foo". > > Unless you know something I don't? Provided some early part of the URL is handled by PHP, the rest of the URL path is provided to PHP in $_SERVER["PATH_INFO"]. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Steve D'Aprano writes: > On Thu, 12 Oct 2017 02:43 am, Marko Rauhamaa wrote: > >> Chris Angelico : >> >>> The places where C++ is not a superset of C are mostly things you >>> wouldn't want to be doing anyway. You can generally take C code and >>> compile it with a C++ compiler, and it'll have the same semantics. >> >> Here's a C/C++ program: It's not a C program in the sense that it's undefined in C. A struct with no members is a constraint violation. >> >> #include >> >> int main() >> { >> struct {} s; >> printf("%d\n", (int) sizeof 'a'); >> printf("%d\n", (int) sizeof s); >> return 0; >> } >> >> >> When compiled (with gcc) as a C program, the output is: >> >> 4 >> 0 >> >> When the same program is compiled (with gcc) as a C++ program, the >> output is: >> >> 1 >> 1 >> >> That is not immediately all that significant but points to subtle >> incompatibilities between the data models of C and C++. > > I don't think anyone should expect that platform specific details like the > size of a char should be precisely the same between C and C++. Even two > different C compilers could return different values. The size of (in the sense of sizeof) an expression of type char is defined to be 1. All conforming C and C++ compilers must return 1 in such a case. The difference being highlighted here is that, in C, 'a' is an integer expression. In C++ it's of type char. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Chris Angelico writes: > On Thu, Oct 12, 2017 at 12:19 PM, Ben Bacarisse wrote: >> Chris Angelico writes: >> >>> On Thu, Oct 12, 2017 at 11:55 AM, Ben Bacarisse >>> wrote: >>>> Chris Angelico writes: >>>>> it binds your URLs to >>>>> the concrete file system. That may not seem like too much of a >>>>> problem, but it's a pretty big limitation; you can't have URLs like >>>>> "https://en.wikipedia.org/wiki/Foo"; without some help from the web >>>>> server, eg Apache's mod_rewrite. >>>> >>>> I don't follow this. Your "can't" and "big limitation" suggests >>>> something inevitable, but I don't see it as an intrinsic problem with >>>> the language. I'm sure PHP is not as flexible as the frameworks you >>>> mention, but you are not tied to URLs mapping to files. Maybe you meant >>>> that this is what often happens, or what most people do, with PHP. >>> >>> How would you, with PHP itself, handle database-provided URLs? The >>> only way I've ever seen it done is at an external level - such as >>> mod_rewrite - which means that someone else, *not* the PHP script, is >>> managing your URLs. They're pushed to some external config file >>> somewhere. That's okay for just one URL pattern, but it doesn't scale >>> well, which is why (for example) Wikipedia's editing pages are >>> "/w/index.php?" instead of, say, "/wiki/Foo/edit" or >>> "/wiki/edit/Foo". >>> >>> Unless you know something I don't? >> >> Provided some early part of the URL is handled by PHP, the rest of the >> URL path is provided to PHP in $_SERVER["PATH_INFO"]. > > Is it possible to do that without having ".php" visible in the path? Yes, though because that will depend on how the server is configured I should perhaps say "usually yes"! -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Gregory Ewing writes: > Ben Bacarisse wrote: >> That's a different type. I think you mean that a human writing C >> (rather than bartc's code generator) would probably design the code to >> use tokenrec ** then I agree, but the latter is not just a different way >> to write the former. > > Yes, I was translating his English description of the type > into C, using C's meaning of the word "array". It seems that > arrays in the original language (Algol? One of Bart's > inventions?) are somewhat richer things. Probably, but you can have pointers to array types in C which is what the posted type used. Humans pass arrays in C by passing a pointer to the first element. Pointers to arrays therefore crop up when passing 2D (or higher) arrays, even when the code is hand written by a person. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Chris Angelico writes: > On Thu, Oct 12, 2017 at 7:32 PM, Thomas Jollans wrote: >> On 2017-10-12 07:31, Chris Angelico wrote: >>> On Thu, Oct 12, 2017 at 12:19 PM, Ben Bacarisse >>> wrote: >>>> Provided some early part of the URL is handled by PHP, the rest of the >>>> URL path is provided to PHP in $_SERVER["PATH_INFO"]. >>> >>> Is it possible to do that without having ".php" visible in the path? >> >> Just like with Python-based frameworks, this requires a few lines of web >> server configuration. >> >> On Apache, you might use mod_wsgi to tell the server how to run the code >> in one case, and a combination of mod_php and mod_rewrite in the other. >> If you're using FastCGI with nginx or lighttpd, I believe the >> configuration would look pretty similar in both cases. >> >> Then again, I don't do much web programming any more and generally stay >> away from PHP, so I may be misremembering. > > Normally, with a Python-based framework, you don't need _any_ web > server configuration. You simply define your URL routing within the > Python code. The only thing the web server needs to know is where to > find the web app, and that's sufficiently standard that it can be done > off-the-shelf; for instance, you push your code to Heroku, and they > set everything up to pass requests to your app. Not possible with PHP, > since you need *custom* web server config to manage your rewrite > rules. That's at odds with what I've read online which admittedly may be all junk. I wanted to try Flask so I installed the Ubuntu packages but then got stuck on a huge document that suggested I needed to install things called Nginx and Gunicorn. You've now mentioned another: Heroku. I'm sure the complex instructions I found are not really required -- it was probably just the usual "this is what I did so this is how it's done" document, but I'm having trouble finding the simpler way to do it. Since no web server configuration is needed (I have a working Apache installation that mirrors, as closely as possible, what my hosting provider uses) it should be relatively easy. Can you tell me, or can you point me to a resource that tells me, where to put the app? I don't yet know what "push your code to Heroku" means. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Jon Ribbens writes: > On 2017-10-12, Ben Bacarisse wrote: >> Chris Angelico writes: >>> Normally, with a Python-based framework, you don't need _any_ web >>> server configuration. You simply define your URL routing within the >>> Python code. The only thing the web server needs to know is where to >>> find the web app, and that's sufficiently standard that it can be done >>> off-the-shelf; for instance, you push your code to Heroku, and they >>> set everything up to pass requests to your app. Not possible with PHP, >>> since you need *custom* web server config to manage your rewrite >>> rules. >> >> That's at odds with what I've read online which admittedly may be all >> junk. I wanted to try Flask so I installed the Ubuntu packages but then >> got stuck on a huge document that suggested I needed to install things >> called Nginx and Gunicorn. You've now mentioned another: Heroku. I'm >> sure the complex instructions I found are not really required -- it was >> probably just the usual "this is what I did so this is how it's done" >> document, but I'm having trouble finding the simpler way to do it. >> >> Since no web server configuration is needed (I have a working Apache >> installation that mirrors, as closely as possible, what my hosting >> provider uses) it should be relatively easy. Can you tell me, or can >> you point me to a resource that tells me, where to put the app? I don't >> yet know what "push your code to Heroku" means. > > "don't need _any_ web server configuration" is rather, er, optimistic. It did seem so. I could not imagine any way it would "just" work unless it was already set up to "just work". > For Apache you'd need the mod_proxy_uwsgi module installed, and the > config would be something like this: > > DocumentRoot /srv/www/appname/appname > > ProxyPass uwsgi://127.0.0.1:3031/ > > > ProxyPass ! > > > and you need an app container listening on the port defined above, > e.g. uwsgi with config like: > > /etc/uwsgi/apps-available/appname.ini: > > [uwsgi] > plugin = python3 > socket = 127.0.0.1:3031 > threads = 4 > master = 1 > chdir = /srv/www/appname > module = appname:app > # https://github.com/unbit/uwsgi/issues/1126 > wsgi-disable-file-wrapper = true > > and you'll need something to run uwsgi on system startup. I see. If I'm reading this right, the app requests are passed through to another server -- uWSGI. How does this typically work on low-cost hosting? I may be able to set up the ProxyPass locally (i.e. in .htaccess) but I won't be able to write /etc/uwsgi/apps-available/appname.ini. Maybe there are a locally defined .ini files that uwsgi reads? As for running something on startup... I suppose I can ask. Maybe it's usual to run it anyway. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Thomas Jollans writes: > On 2017-10-12 15:16, Ben Bacarisse wrote: >> Gregory Ewing writes: >> >>> Ben Bacarisse wrote: >>>> That's a different type. I think you mean that a human writing C >>>> (rather than bartc's code generator) would probably design the code to >>>> use tokenrec ** then I agree, but the latter is not just a different way >>>> to write the former. >>> >>> Yes, I was translating his English description of the type >>> into C, using C's meaning of the word "array". It seems that >>> arrays in the original language (Algol? One of Bart's >>> inventions?) are somewhat richer things. >> >> Probably, but you can have pointers to array types in C which is what >> the posted type used. Humans pass arrays in C by passing a pointer to >> the first element. Pointers to arrays therefore crop up when passing 2D >> (or higher) arrays, even when the code is hand written by a person. >> > > No, actually. Multi-dimensional arrays in C are not arrays of arrays. That's exactly what they are (in their simplest form). Other structures using pointers can be accessed in the same way so some people call those multi-dimensional arrays, but that can be a bit confusing. > They look very similar, but when the dimensions of the array are known > at compile time, arrays of any rank are a continuous region of memory > with the data, and a pointer to the start. > > Casting int[3][3] to int** will not do what you want it to do. Exactly. This is why I raised this as an example where you get a pointer to an array type. int ** is something else altogether. When you pass an int[3][3] to a function, it pops up in the function as an int (*)[3]. You can (due to another of C's odd rules) write the parameter as int a[][3], or int a[3][3], but the first array in the declarator is replaced by a pointer (and the size is ignored). > If, say, you have variables of the types: > > int a[M][N], **b; > > then a[i][j] is equivalent to *(a+(i*M)+j), No it isn't. That expression does not even have type int. In fact you will be surprised to learn that a[i][j] it is equivalent to *(*(a+i)+j). > while b[i][j] is equivalent to *(*(b+i)+j). That much is true. The fact that the genuine 2D array access (a[i][j]) is equivalent an expression of the same form as the pointer to pointer access (b[i][j]) looks odd because, as you know, they are doing different things. But they do different things because the types are different. > Observe: > short multi_array[3][3] = { > {1, 0, 0}, > {0, 1, 0}, > {0, 0, 1} > }; > short *array_array[3]; I would not have used that name. This is an array of pointers. > /* fill array_array elements of multi_array */ > for(i=0; i<3; ++i) { > array_array[i] = calloc(3, sizeof(short)); > /* This works because C arrays are row-major */ > memcpy(array_array[i], &multi_array[i][0], 3*sizeof(short)); Some people would find array_array[i] = malloc(sizeof multi_array[i]); memcpy(array_array[i], multi_array[i], sizeof multi_array[i]); to be clearer and more maintainable. You don't repeat the element type and there's no need to reference the (possibly arbitrary) size 3. It makes it very clear that enough space is being allocated for what is being copied. > } > > /* print out the arrays */ > puts("multi_array:"); > for (i=0; i<3; ++i) { > for (j=0; j<3; ++j) { > printf("%d ", multi_array[i][j]); Try *(multi_array+(i*3)+j) here to see what happens (that's your re-write with 'a' and 'M' substituted). > } > puts(""); > } -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Jon Ribbens writes: > On 2017-10-12, Ben Bacarisse wrote: >> I see. If I'm reading this right, the app requests are passed through >> to another server -- uWSGI. > > Yes. It doesn't have to be uWSGI; it could be gunicorn, or you could > probably use Apache's mod_fcgid. As a last resort you could use CGI, > which wouldn't involve any long-running processes, which has the > benefit of not requiring any special support from your host but the > disadvantage of most likely being very slow indeed. > >> How does this typically work on low-cost hosting? I may be able to set >> up the ProxyPass locally (i.e. in .htaccess) but I won't be able to >> write /etc/uwsgi/apps-available/appname.ini. Maybe there are a locally >> defined .ini files that uwsgi reads? > > You need to choose a host that supports one of the relevant systems > mentioned above. If you already have a host then it's possible they > already do, otherwise you may need to choose another. Ah, thanks. You've cleared up some of miasma of terms that seems to surround the various Python-for-the-web options. I'd like to try it, but not enough to switch hosting and, probably, spend more money. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
Chris Angelico writes: > On Fri, Oct 13, 2017 at 1:09 AM, Ben Bacarisse wrote: >> Chris Angelico writes: >> >>> On Thu, Oct 12, 2017 at 7:32 PM, Thomas Jollans wrote: >>>> On 2017-10-12 07:31, Chris Angelico wrote: >>>>> On Thu, Oct 12, 2017 at 12:19 PM, Ben Bacarisse >>>>> wrote: >>>>>> Provided some early part of the URL is handled by PHP, the rest of the >>>>>> URL path is provided to PHP in $_SERVER["PATH_INFO"]. >>>>> >>>>> Is it possible to do that without having ".php" visible in the path? >>>> >>>> Just like with Python-based frameworks, this requires a few lines of web >>>> server configuration. >>>> >>>> On Apache, you might use mod_wsgi to tell the server how to run the code >>>> in one case, and a combination of mod_php and mod_rewrite in the other. >>>> If you're using FastCGI with nginx or lighttpd, I believe the >>>> configuration would look pretty similar in both cases. >>>> >>>> Then again, I don't do much web programming any more and generally stay >>>> away from PHP, so I may be misremembering. >>> >>> Normally, with a Python-based framework, you don't need _any_ web >>> server configuration. You simply define your URL routing within the >>> Python code. The only thing the web server needs to know is where to >>> find the web app, and that's sufficiently standard that it can be done >>> off-the-shelf; for instance, you push your code to Heroku, and they >>> set everything up to pass requests to your app. Not possible with PHP, >>> since you need *custom* web server config to manage your rewrite >>> rules. >> >> That's at odds with what I've read online which admittedly may be all >> junk. I wanted to try Flask so I installed the Ubuntu packages but then >> got stuck on a huge document that suggested I needed to install things >> called Nginx and Gunicorn. You've now mentioned another: Heroku. I'm >> sure the complex instructions I found are not really required -- it was >> probably just the usual "this is what I did so this is how it's done" >> document, but I'm having trouble finding the simpler way to do it. >> >> Since no web server configuration is needed (I have a working Apache >> installation that mirrors, as closely as possible, what my hosting >> provider uses) it should be relatively easy. Can you tell me, or can >> you point me to a resource that tells me, where to put the app? I don't >> yet know what "push your code to Heroku" means. > > I abbreviated that down to nothing, but since you ask, here's a really > REALLY simple run-down of how to use Heroku: I think I see what you mean now. You meant no configuration is needed because you use (or buy?) a cloud service that's all set up for it already? >From this and other posts I think the position is that I do need to do some server configuration (and essentially install a proxy server) to run Python web applications on my typical Apache set-up. And I would then have to shop around for suitable hosting that is already set up for running them. Thanks. That's not quite what I was after but it's good to know how to do that should I want to that later. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
Chris Angelico writes: > On Fri, Oct 13, 2017 at 10:14 AM, Ben Bacarisse wrote: >> Chris Angelico writes: >>> I abbreviated that down to nothing, but since you ask, here's a really >>> REALLY simple run-down of how to use Heroku: >> >> I think I see what you mean now. You meant no configuration is needed >> because you use (or buy?) a cloud service that's all set up for it >> already? > > Correct - because the setup needed is completely generic. > >> From this and other posts I think the position is that I do need to do >> some server configuration (and essentially install a proxy server) to >> run Python web applications on my typical Apache set-up. And I would >> then have to shop around for suitable hosting that is already set up for >> running them. >> >> >> >> Thanks. That's not quite what I was after but it's good to know how to >> do that should I want to that later. > > Yep, it's not too hard. > > And that's why it's cleaner to work with Python than PHP. To use > custom URL routing in PHP, you have to use custom server rules; to use > custom URL routing in Python, you use "@app.route(...)" lines inside > your app, and perfectly standard server rules. That's one way to put it. Another is that to use Python I need to buy a new service that is already configured. If that's the way it's done, fine, but this sub-thread started with someone being surprised by the success of PHP. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
Chris Angelico writes: > On Sat, Oct 14, 2017 at 8:42 AM, Ben Bacarisse wrote: >> Chris Angelico writes: >> >>> On Fri, Oct 13, 2017 at 10:14 AM, Ben Bacarisse >>> wrote: >>>> Chris Angelico writes: >>>>> I abbreviated that down to nothing, but since you ask, here's a really >>>>> REALLY simple run-down of how to use Heroku: >>>> >>>> I think I see what you mean now. You meant no configuration is needed >>>> because you use (or buy?) a cloud service that's all set up for it >>>> already? >>> >>> Correct - because the setup needed is completely generic. >>> >>>> From this and other posts I think the position is that I do need to do >>>> some server configuration (and essentially install a proxy server) to >>>> run Python web applications on my typical Apache set-up. And I would >>>> then have to shop around for suitable hosting that is already set up for >>>> running them. >>>> >>>> >>>> >>>> Thanks. That's not quite what I was after but it's good to know how to >>>> do that should I want to that later. >>> >>> Yep, it's not too hard. >>> >>> And that's why it's cleaner to work with Python than PHP. To use >>> custom URL routing in PHP, you have to use custom server rules; to use >>> custom URL routing in Python, you use "@app.route(...)" lines inside >>> your app, and perfectly standard server rules. >> >> That's one way to put it. Another is that to use Python I need to buy a >> new service that is already configured. If that's the way it's done, >> fine, but this sub-thread started with someone being surprised by the >> success of PHP. > > Thing is, that's exactly the same for both languages these days. You > can get cheap (even zero-dollar) hosting that's preconfigured to be > able to support either. There USED to be a difference, and everyone's > acknowledged this - PHP built up some inertia - but there's now no > real reason for it other than "it's popular, therefore people use it". That's good to know, but of course the current success of PHP is based exactly on what used to be the case. It will take a while for the inherent inertia of people, skills, processes and so on to be overcome. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
"Peter J. Holzer" writes: > On 2017-10-13 21:42, Ben Bacarisse wrote: >> That's one way to put it. Another is that to use Python I need to buy a >> new service that is already configured. > > That's exactly the same for PHP. You can't use that either unless > somebody configured to server to use it. I was not using "I" generically. *I* don't need to buy a service configured to use PHP because: > The difference is that lots of providers started configuring their > servers for use of PHP in the late 1990s, but didn't do that for Python. > >> If that's the way it's done, fine, but this sub-thread started with >> someone being surprised by the success of PHP. > > Which probably boils down to the question: Why did providers offer PHP > and not Python? One reason might be that at the time no suitable web > framework for Python existed (Zope was released in 1999, and I remember > it to be rather heavy-weight). One reason might be that providers didn't > see PHP as a "real" programming language and therefore deemed it > safer. That would be deeply ironic, given the security pain that it has turned out to be! -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Python 2 -> 3, urllib.urlopen (corrected the case)
Irv Kalb writes: Lots of detail snipped. I hope it won't matter... > (_ssl.c:749)> > > Huh??? > > I've read a bunch of documentation, and it looks like I'm doing > everything right, but I cannot get this to work. Any other > suggestions to get this 3 line program to work correctly? Just a data point... It works here: $ python3 t.py Response is: b'156.99\n' $ cat t.py import urllib.request fullURLWithParameters = 'http://finance.yahoo.com/d/quotes.csv?s=aapl&f=l1' # read all the data response = urllib.request.urlopen(fullURLWithParameters).read() print('Response is: ', response) $ python3 --version Python 3.5.2 Maybe you are missing some crucial certificates? Presumably Python finds them is standard paces, so it would be worth trying other accesses of the URL. For example, here: $ wget -q -O - 'http://finance.yahoo.com/d/quotes.csv?s=aapl&f=l1' 156.99 Finally, wget -S shows that the resource has moved. It is now at Location: http://download.finance.yahoo.com/d/quotes.csv?s=aapl&f=l1 I don't think this has anything to do with your problem, but it's worth noting. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Python 2 -> 3, urllib.urlopen (corrected the case)
Irv Kalb writes: > Thank you! You're welcome. >> Just a data point... It works here: >> >> $ python3 t.py >> Response is: b'156.99\n' >> $ cat t.py >> import urllib.request >> fullURLWithParameters = 'http://finance.yahoo.com/d/quotes.csv?s=aapl&f=l1' >> # read all the data >> response = urllib.request.urlopen(fullURLWithParameters).read() >> >> print('Response is: ', response) >> $ python3 --version >> Python 3.5.2 > > I have not tried this on anything but my Mac. I'm running 3.6.1 >> For example, here: >> >> $ wget -q -O - 'http://finance.yahoo.com/d/quotes.csv?s=aapl&f=l1' >> 156.99 >> >> Finally, wget -S shows that the resource has moved. It is now at >> >> Location: http://download.finance.yahoo.com/d/quotes.csv?s=aapl&f=l1 >> >> I don't think this has anything to do with your problem, but it's worth >> noting. > > That DID fix it. I changed the URL to add 'download/' and it worked > perfectly. That's... interesting. > Apparently, Python 3 differs from Python 2 in the way that it is > handling a missing/forwarding URL, because the original code in Python > 2.7 works perfectly. Python 3 works for me. I still suspect it's some system difference rather than being, say, a 3.6.1 vs 3.5.2 difference. What happens if you change the URL to use https rather than http? -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Python 2 -> 3, urllib.urlopen (corrected the case)
Irv Kalb writes: >> On Oct 14, 2017, at 6:46 PM, Ben Bacarisse wrote: >>>> Finally, wget -S shows that the resource has moved. It is now at >>>> >>>> Location: http://download.finance.yahoo.com/d/quotes.csv?s=aapl&f=l1 >>>> >>>> I don't think this has anything to do with your problem, but it's worth >>>> noting. >>> >>> That DID fix it. I changed the URL to add 'download/' and it worked >>> perfectly. >> >> That's... interesting. >> >>> Apparently, Python 3 differs from Python 2 in the way that it is >>> handling a missing/forwarding URL, because the original code in Python >>> 2.7 works perfectly. >> >> Python 3 works for me. I still suspect it's some system difference >> rather than being, say, a 3.6.1 vs 3.5.2 difference. What happens if >> you change the URL to use https rather than http? >> > > Trying https (with and without the "download." part) results in the > same traceback as I was seeing earlier. It looks like there may be something amiss with your local certificates, at least as far as Python's SSL code in concerned. That's a Dark Art to me so I can't really help (and it might be Mac specific). The error might have showed up in the first test because the redirection was to an https: URL. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Compression of random binary data
danceswithnumb...@gmail.com writes: > ... First let me clarify before you lump this in with > perpetual motion, or cold fusion. It is a mapping solution to compress > ANY i repeat ANY random file with numbers of only 0 - 9 such as are in > the million rand numbers page. Entirely possible. Of course it is. I have half a dozen programs on this machine that do it. I don't need yours. It's possible you want to claim something beyond what you stated, but no one is going to get excited until you actually claim such a thing. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Compression of random binary data
danceswithnumb...@gmail.com writes: > Finally figured out how to turn this into a random binary compression > program. Since my transform can compress more than dec to binary. Then > i took a random binary stream, Forget random data. For one thing it's hard to define, but more importantly no one cares about it. By its very nature, random data is not interesting. What people want is a reversible compression algorithm that works on *arbitrary data* -- i.e. on *any* file at all, no matter how structured and *non-random* it is. For example, run the complete works of Shakespeare through your program. The result is very much not random data, but that's the sort of data people want to compress. If you can compress the output of your compressor you have made a good start. Of course what you really want to be able to do is to compress the output that results from compressing your compressed out. And, of course, you should not stop there. Since you can compress *any* data (not just the boring random stuff) you can keep going -- compressing the compressed output again and again until you end up with a zero-length file. Then you publish in a major journal. Post the link to the journal article when you are done. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Compression of random binary data
Paul Moore writes: > On 24 October 2017 at 11:23, Ben Bacarisse wrote: >> For example, run the complete works of Shakespeare through your program. >> The result is very much not random data, but that's the sort of data >> people want to compress. If you can compress the output of your >> compressor you have made a good start. Of course what you really want >> to be able to do is to compress the output that results from compressing >> your compressed out. And, of course, you should not stop there. Since >> you can compress *any* data (not just the boring random stuff) you can >> keep going -- compressing the compressed output again and again until >> you end up with a zero-length file. > > Oh, and just for fun, if you are able to guarantee compressing > arbitrary data, then It's a small point, but you are replying to a post of mine and saying "you". That could make people think that /I/ am claiming to have a perfect compression algorithm. > 1. Take a document you want to compress. > 2. Compress it using your magic algorithm. The result is smaller. > 3. Compress the compressed data. The result is still smaller. > 4. Repeat until you hit 0 bytes. Isn't this just repeating what I said? I must has not written is clearly enough. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Compression of random binary data
Steve D'Aprano writes: > On Tue, 24 Oct 2017 09:23 pm, Ben Bacarisse wrote: > >> Forget random data. For one thing it's hard to define, > > That bit is true. > >> but more importantly no one cares about it. > > But that's wrong. All generalisations are false. I was being hyperbolic. > For instance: > > - Encrypted data looks very much like random noise. With more and more data > traversing the internet in encrypted form, the ability to compress random > noise would be worth billions. > > - Compressed data looks somewhat like random noise (with a bit of structure). > The more it is compressed, the more random it looks. If you could compress > random noise, you could take already compressed data, and compress it again, > saving even more space. > > - Many multimedia formats (images, sound, video) are compressed using > dedicated encoders. The better the encoder, the more it compresses the data > (whether lossy or not) the harder it is to compress it further. If you could > compress random noise, you could compress JPGs, MP3s, h265-encoded MKVs, > etc, saving even more storage and transmission costs. But these are not random data. We care about these because they are are highly structured, non-random data. > And most importantly: > > - Random data is a superset of the arbitrary structured data you mention > below. If we could compress random data, then we could compress any data > at all, no matter how much or little structure it contained. Yes, that's part of my point. Arbitrary data includes random data but it avoids arguments about what random means. > This is why the ability to compress random data (if it were possible, which it > is not) is interesting. Its not because people want to be able to compress > last night's lottery numbers, or tables of random digits. The trouble is a pedagogic one. Saying "you can't compress random data" inevitably leads (though, again, this is just my experience) to endless attempts to define random data. My preferred way out of that is to talk about algorithmic complexity but for your average "I've got a perfect compression algorithm" poster, that is step too far. I think "arbitrary data" (thereby including the results of compression by said algorithm) is the best way to make progress. >> Then you publish in a major journal. Post the link to the journal >> article when you are done. > > These days there are plenty of predatory journals which will be happy to take > Dancerswithnumber's money in return for publishing it in a junk > journal. Sure, but you usually get a huge advantage -- a text to criticise. Your average Usenet crank will keep changing what they say to avoid being pinned down. Plus you get to note the fact that the journal is junk. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Compression of random binary data
Steve D'Aprano writes: > On Tue, 24 Oct 2017 06:46 pm, danceswithnumb...@gmail.com wrote: > >> Greg, you're very smart, but you are missing a big key. I'm not padding, >> you are still thinking inside the box, and will never solve this by doing >> so. Yes! At least you see my accomplishment, this will compress any random >> file. > > Talk is cheap. But highly prized. Most Usenet cranks only want to be talked to (they see it as being taken seriously, no matter how rude the respondents are) so for the cost of something cheap (a little babbling) they get an endless stream of highly prized attention. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Compression of random binary data
Gregory Ewing writes: > Ben Bacarisse wrote: >> The trouble is a pedagogic one. Saying "you can't compress random data" >> inevitably leads (though, again, this is just my experience) to endless >> attempts to define random data. > > It's more about using terms without making sure everyone agrees > on the definitions being used. > > In this context, "random data" really means "uniformly distributed > data", i.e. any bit sequence is equally likely to be presented as > input. *That's* what information theory says can't be compressed. But that has to be about the process that gives rise to the data, not the data themselves. No finite collection of bits has the property you describe. If I say: "here is some random data..." you can't tell if it is or is not from a random source. I can, as a parlour trick, compress and recover this "random data" because I chose it. A source of random can be defined but "random data" is much more illusive. >> I think "arbitrary data" (thereby including the results of compression >> by said algorithm) is the best way to make progress. > > I'm not sure that's much better, because it doesn't home in > on the most important thing, which is the probability > distribution. I think the argument that you can't compress arbitrary data is simpler to make. You don't have to define it (except in the very simplest terms) and it's obvious that it includes the results of previous compressions. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Compression of random binary data
Marko Rauhamaa writes: > Ben Bacarisse : > >>> In this context, "random data" really means "uniformly distributed >>> data", i.e. any bit sequence is equally likely to be presented as >>> input. *That's* what information theory says can't be compressed. >> >> But that has to be about the process that gives rise to the data, not >> the data themselves. No finite collection of bits has the property you >> describe. > > Correct. Randomness is meaningful only in reference to future events. > Once the events take place, they cease to be random. > > A finite, randomly generated collection of bits can be tested against a > probabilistic hypothesis using statistical methods. But beware of parlour tricks. You can't reliably test for random looking data that are, in fact, carefully crafted. If the claim is about compressing arbitrary data, then the claimant won't mind testing inputs chosen by me! The only reason this matters is that such people usually won't reveal the algorithm. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Compression of random binary data
Steve D'Aprano writes: > On Fri, 27 Oct 2017 09:53 am, Ben Bacarisse wrote: > >> A source of random can be defined but "random data" is much more >> illusive. > > Random data = any set of data generated by "a source of random". (I had an editing error there; it should be "a source of random data".) Yes, that's a fine definition, but it has the disadvantage of not being a verifiable property of the thing defined -- you can't know, from the data themselves, if they constitute random data. You would not care about a compression program that worked on some data that looks random, you'd want to present your own data for compression (and then you can use a random source with confidence because the data are yours). That's the big win (for me) of talking about "arbitrary data". -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Compression of random binary data
Gregory Ewing writes: > Ben Bacarisse wrote: >> But that has to be about the process that gives rise to the data, not >> the data themselves. > >> If I say: "here is some random data..." you can't tell if it is or is >> not from a random source. I can, as a parlour trick, compress and >> recover this "random data" because I chose it. > > Indeed. Another way to say it is that you can't conclude > anything about the source from a sample size of one. > > If you have a large enough sample, then you can estimate > a probability distribution, and calculate an entropy. > >> I think the argument that you can't compress arbitrary data is simpler >> ... it's obvious that it includes the results of previous >> compressions. > > What? I don't see how "results of previous compressions" comes > into it. The source has an entropy even if you're not doing > compression at all. Maybe we are taking at cross purposes. A claim to be able to compress arbitrary data leads immediately to the problem that iterating the compression will yield zero-size results. That, to me, is a simpler argument that talking about data from a random source. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Report on non-breaking spaces in posts
r...@zedat.fu-berlin.de (Stefan Ram) writes: > r...@zedat.fu-berlin.de (Stefan Ram) writes: >>|od -c tmp.txt >>|... >>|0012620 s u l a t e i t : \n \n   >>|0012640  d e f w r a p p e d _ >>|... >>| >>|od -x tmp.txt >>|... >>|0012620 7573 616c 6574 6920 3a74 0a0a c220 c2a0 >>|0012640 c2a0 20a0 6564 2066 7277 7061 6570 5f64 >>|... > > PS: > > Oh, the byte order of »od -x« did not match my expectations! You might like http://www.bsb.me.uk/software/utf-8-dump/ I use it all the time (but then I would!). -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Report on non-breaking spaces in posts
Rhodri James writes: > On 31/10/17 17:23, Stefan Ram wrote: >> Ned Batchelder writes: >>>    def wrapped_join(values, sep): >> >>Ok, here's a report on me seing non-breaking spaces in >>posts in this NG. I have written this report so that you >>can see that it's not my newsreader that is converting >>something, because there is no newsreader involved. >> >>Here are some relevant lines from Ned's above post: >> >> |From: Ned Batchelder >> |Newsgroups: comp.lang.python >> |Subject: Re: How to join elements at the beginning and end of the list >> |Message-ID: > > Hm. That suggests the mail-to-news gateway has a hand in things. > >> |Content-Type: text/plain; charset=utf-8; format=flowed >> |Content-Transfer-Encoding: 8bit >> |    def wrapped_join(values, sep): > > [snippety snip] > >> |od -c tmp.txt >> |... >> |0012620 s u l a t e i t : \n \n   >> |0012640  d e f w r a p p e d _ >> |... >> | >> |od -x tmp.txt >> |... >> |0012620 7573 616c 6574 6920 3a74 0a0a c220 c2a0 >> |0012640 c2a0 20a0 6564 2066 7277 7061 6570 5f64 >> |... >> >>And you can see, there are two octet pairs »c220« and >>»c2a0« in the post (directly preceding »def wrapped«). >>(Compare with the Content-Type and Content-Transfer-Encoding >>given above.) (Read table with a monospaced font:) >> >> corresponding >> Codepoint UTF-8ISO-8859-1 interpretation >> >> U+0020?c2 2020? SPACE? >> U+00A0 c2 a0a0 NON-BREAKING SPACE >> >>This makes it clear that there really are codepoints >>U+00A0 in what I get from the server, i.e., non-breaking >>spaces directly in front of »def wrapped«. > > And? Why does that bother you? A non-breaking space is a perfectly > valid thing to put into a UTF-8 encoded message. But it's an odd thing to put into Python code (at least there). If the Usenet client is doing it that's surely bad as the code won't run without editing. > The 0xc2 0x20 byte > pair that you misidentify as a space is another matter entirely. > > 0xc2 0x20 is not a space in UTF-8. It is an invalid code sequence. I > don't know how or where it was generated, but it really shouldn't have > been. It wasn't there. It was down to a misreading of the byte-order in the hex dump. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Code Snippets
r...@zedat.fu-berlin.de (Stefan Ram) writes: > Wolfgang Maier writes: >>If you're worried bout having things on separate lines, you could write: >>import os; os.getcwd() >>,etc., which is actually saving a few characters :) > > Yes, but there still is the risk of the identifier »os« > already being used in the sorrounding code. While > > __import__( "os" ).getcwd() > > does not seem to "leak" names into the enclosing scope. Also it's an expression which may be important in your "quick and dirty" scripts. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: replacing `else` with `then` in `for` and `try`
Steve D'Aprano writes: > On Thu, 2 Nov 2017 08:12 am, Alexey Muranov wrote: > >> what do you think about the idea of replacing "`else`" with "`then`" in >> the contexts of `for` and `try`? > > Yes, this, exactly!!! > > (For while and for loops, but not try -- see below.) > > I have argued this for many years. The current choice of "else" is painfully > misleading, and it causes people (including myself) to wrongly guess that > the "else" block runs only if the for/while block doesn't run at all: > > > # This is wrong! > for x in sequence: > ... > else: > print("sequence is empty") > > > The actually semantics of "else" is that the block is UNCONDITIONALLY run > after the for/while loop completes, unless you jump out of the loop using > return, raise or break. That makes it a "then" block, not "else". > > >> It seems clear that it should be rather "then" than "else." Compare >> also "try ... then ... finally" with "try ... else ... finally". > > I disagree about the try block though. The semantics of the try block are: > > try: >A > except: >B > else: >C > finally: >D > > (1) code block A is attempted; > > (2) IF an exception occurs, jump to code block B; > > (3) otherwise (else), no exception occurs, so jump to code block C; > > (4) finally run code block D on your way out, regardless of which blocks are > executed and how you exit them. > > > So I think "else" is correct here. The else block only gets called if there is > no exception. > > >> Currently, with "else", it is almost impossible to guess the meaning >> without looking into the documentation. > > It is worse than that: it is easy to guess the WRONG meaning, namely that the > else block runs when the for/while loop doesn't execute at all (the for-loop > sequence is empty, or the while-loop condition is initially false). > > >> Off course, it should not be changed in Python 3, maybe in Python 4 or >> 5, but in Python 3 `then` could be an alias of `else` in these contexts. > > Unfortunately, this is almost certainly not going to happen. It would require > adding a new keyword, and unless Guido changes his mind, he doesn't think > this change is worthwhile. Re-using finally would not need a new keyword and might be close enough in meaning. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: replacing `else` with `then` in `for` and `try`
Steve D'Aprano writes: > On Thu, 2 Nov 2017 12:50 pm, Ben Bacarisse wrote: > >> Steve D'Aprano writes: >> >>> On Thu, 2 Nov 2017 08:12 am, Alexey Muranov wrote: >>> >>>> what do you think about the idea of replacing "`else`" with "`then`" in >>>> the contexts of `for` and `try`? > [...] >> Re-using finally would not need a new keyword and might be close enough >> in meaning. > > Reusing finally would be *completely* wrong. > > The semantics of `finally` is that it should be executed no matter[1] how you > exit the previous block. E.g. if we write: > > > try: > return 1 > finally: > print("exiting") > > > then "exiting" is printed. Replace the return with a raise, and the same > applies. Reusing `finally` in for and while loops would imply the similar > behaviour: > > > for i in range(100): > return i > finally: > print("exiting") > > > should print "exiting", when in fact it does not. Likewise if you replace the > return with a break. Sure, but your argument seemed to that else has entirely the wrong meaning (I certainly to a double take when I have to remember what it means) and, in that context, finally has a meaning closer to what you want. The problem that it carries different meanings when added to different statements is already the case with else -- it's an alternative to an if and not an alternative to a loop. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: replacing `else` with `then` in `for` and `try`
Steve D'Aprano writes: > On Thu, 2 Nov 2017 10:09 pm, Ben Bacarisse wrote: > >> Sure, but your argument seemed to that else has entirely the wrong >> meaning (I certainly to a double take when I have to remember what it >> means) and, in that context, finally has a meaning closer to what you >> want. > > That's an argument about whether "yellow" or "purple" is closer in meaning to > the word we actually want, "spicy" :-) I note the smiley, but it was in fact an argument that "finally" is closer to "and afterwards" than "else" is :-) -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Goto (Posting On Python-List Prohibited)
bartc writes: > On 30/12/2017 16:53, mm0fmf wrote: >> On 30/12/2017 14:41, bartc wrote: >>> it looks a bit naff >> >> Understatement of 2017. > > I'm honest about my own ideas, but my remarks were about the use of > special symbols such as "::" and "@". > > Before completely dismissing it however, you should look at how > another language such as Python can achieve the same thing. > > Namely, take any block of code within a function, and allow it to be > executed or shared from anywhere else in the function, with the > minimum of disruption. That's what a local function does and it does it with the clean semantics of a function call. When this idea came up in comp.lang.c you could not see the point, yet you appear to have a use-case common enough that you have a solution worked out using gotos. > If it looks better than what I'd come up with, then I'll use that instead. What looks better is always going to be an unreliable and subjective measure, but calling a named function almost certainly scales better and will allow for better structuring (such as when one block needs to use another one). -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Goto (Posting On Python-List Prohibited)
bartc writes: > On 30/12/2017 20:36, Ben Bacarisse wrote: >> bartc writes: >> >>> On 30/12/2017 16:53, mm0fmf wrote: >>>> On 30/12/2017 14:41, bartc wrote: >>>>> it looks a bit naff >>>> >>>> Understatement of 2017. >>> >>> I'm honest about my own ideas, but my remarks were about the use of >>> special symbols such as "::" and "@". >>> >>> Before completely dismissing it however, you should look at how >>> another language such as Python can achieve the same thing. >>> >>> Namely, take any block of code within a function, and allow it to be >>> executed or shared from anywhere else in the function, with the >>> minimum of disruption. >> >> That's what a local function does and it does it with the clean >> semantics of a function call. >> >> When this idea came up in comp.lang.c you could not see the point, yet >> you appear to have a use-case common enough that you have a solution >> worked out using gotos. > > C doesn't in general have local functions. My own languages don't > implement them properly. So I tend not to use them. But now you have good reason to change that. Properly implemented they do exactly what you want very neatly. You can stick with gotos, of course, but at least I hope you won't pour scorn on the idea of local function if it comes up again. >>> If it looks better than what I'd come up with, then I'll use that instead. >> >> What looks better is always going to be an unreliable and subjective >> measure, but calling a named function almost certainly scales better and >> will allow for better structuring (such as when one block needs to use >> another one). > > Using a local (or even non-local) function is what I'm trying to > avoid, as I prefer to keep the code inline, and not disrupt it too > much. That's what used to be called hacking. You write it one way and then spot that that block over there can be used here, but you don't tidy up the code, you just jump to it! In general, it is exactly the sort of goto use that gave gotos a bad name. Anyway, by their very nature, the blocks you are talking about should not be inline since they don't belong to any one execution path. (I hope you don't mind this annotation -- over at comp.lang.c I just remove text from my replies to you as is your preference, but people here will not have seen that exchange and I prefer to mark edits.) -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Goto (Posting On Python-List Prohibited)
bartc writes: > On 31/12/2017 12:41, Chris Angelico wrote: >> On Sun, Dec 31, 2017 at 11:33 PM, bartc wrote: >>> On 30/12/2017 23:54, Chris Angelico wrote: > I've written code that uses dirty tricks like that to avoid duplication. It's at least as much of a problem as actual duplication is. Generally, the 'goto' solution results in subsequent programmers (such as my future selves) staring at the code for 30-60 seconds to figure out what it's doing. I don't like to do that to myself, much less to people I actually admire and respect. >>> >>> The problem is having to stare at the code for even longer to figure out the >>> even dirtier tricks you had to use to avoid gotos. >> >> Dirtier tricks like... named functions? > > I like to write clean and readable code. If I thought introducing > functions, whether local or not, as a way of avoiding goto was worth > doing, I would do so. I think there's a problem with that. Standard C does not have them, you said your language does not implement them properly and I think you are new(ish) to Python. What language did you try them in? It may be that it was overly complex in that language. The idea is clean and simple. > So in this case I disagree with dragging in named functions and > introducing an extra level of control flow just to avoid duplicating > half a dozen lines of code. I would just duplicate those lines (with a > comment that they have to match the other set so that they are > maintained in sync). The suggestion was to use them to avoid gotos. If duplicating is a good idea (and it's a hard line to draw) then we are not talking about the same cases. Given the choice of "dragging in named functions" and dragging in named blocks and gotos, I would choose the functions every time. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Goto (Posting On Python-List Prohibited)
bartc writes: > On 31/12/2017 15:02, Ben Bacarisse wrote: >> bartc writes: > >> I think there's a problem with that. Standard C does not have them, you >> said your language does not implement them properly > > (The real problem is I don't remember local functions being used > anywhere else. It's an idiom I'm not used to and that apparently few > other people use. Except perhaps in Python where they do to use > advanced features over simpler ones.) > > and I think you are >> new(ish) to Python. What language did you try them in? It may be that >> it was overly complex in that language. The idea is clean and simple. > > It's not simple to implement. Not if you want full access to the > non-static variables of the containing function(s). It doesn't sound > that efficient either. No, you missed the point and did not address the question. You said (now cut) | If I thought introducing functions, whether local or not, as a way of | avoiding goto was worth doing, I would do so. but I'm not sure you know if it's worth it or not. So here's my question again: what language (or languages) were you using when you concluded that it was not worth using local functions to avoid gotos? Maybe you had a bad experience from some language that did it badly. >>> So in this case I disagree with dragging in named functions and >>> introducing an extra level of control flow just to avoid duplicating >>> half a dozen lines of code. I would just duplicate those lines (with a >>> comment that they have to match the other set so that they are >>> maintained in sync). >> >> The suggestion was to use them to avoid gotos. If duplicating is a good >> idea (and it's a hard line to draw) then we are not talking about the >> same cases. Given the choice of "dragging in named functions" and >> dragging in named blocks and gotos, I would choose the functions every >> time. > > The blocks don't need to be dragged; they are already in place! > > It's funny because in c.l.c you're always advocating keep declarations > as close to the point of use as possible. Here you appear to be saying > the opposite: taking code away from the primary point of use. If a language allowed me to declare a local function at the point of first use, I'd do that, but there are special reasons why that is not a reasonable thing to do in most cases. None the less, it's not inconsistent to prefer one less than perfect option to another much less than perfect option. However, we're debating an entirely abstract notion. What is a typical use for this "re-use" goto idiom? Maybe I'll prefer the goto version over any of the alternatives when I see an actual use. > (Which is likely to cause problems if the code includes breaks, or > gotos if the language has them.) Good grief! That is exactly the sort of code you should not re-use by jumping to it. There are myriad potential problems and putting the code into a function will allow the compiler to diagnose lots of them. If you really are jumping to re-use code that includes gotos I suggest the whole thing needs re-design. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Goto (Posting On Python-List Prohibited)
bartc writes: > On 31/12/2017 22:09, Ben Bacarisse wrote: > >> No, you missed the point and did not address the question. You said (now >> cut) >> >> | If I thought introducing functions, whether local or not, as a way of >> | avoiding goto was worth doing, I would do so. >> >> but I'm not sure you know if it's worth it or not. So here's my >> question again: what language (or languages) were you using when you >> concluded that it was not worth using local functions to avoid gotos? >> Maybe you had a bad experience from some language that did it badly. > > What makes you think I had a bad experience? Nothing. I was asking what experience you had that led to your conclusion. Knowing the language might explain the conclusion you came to. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Are the critiques in "All the things I hate about Python" valid?
Marko Rauhamaa writes: > Many people think static typing is key to high quality. I tend to think > the reverse is true: the boilerplate of static typing hampers > expressivity so much that, on the net, quality suffers. I don't find that with Haskell. It's statically typed but the types are almost always inferred. If you see an explicit type, it's usually because the author thinks it helps explain something. (I don't want to start a Haskell/Python thread -- the only point is that static typing does not inevitably imply lots of 'boilerplate'.) -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: could use some help with this problem! I've been working on it for days but cant seem to get it right !
Marc Cohen writes: > USING PYTHON 2: Why is that? > Write a program to play this game. This may seem tricky, so break it > down into parts. Like many programs, we have to use nested loops (one > loop inside another). In the outermost loop, we want to keep playing > until we are out of stones. You almost never /have/ to use nested loops. Has the course got this far without introducing the idea of a function? > So, the basic outline of the program should be something like this: > > totalStones = 100 > > maxStones = 5 maxTake or maxMove might be a more helpful name. > pile = TOTAL # all stones are in the pile to start > > while [pile is not empty]: > > while [player 1's answer is not valid]: > > [ask player 1] > > [execute player1’s move] > > Do the same for player 2…. (this can be achieved by a for loop) Is the idea for the program to play an optimal strategy for player 2, or is the program simply doing the housekeeping -- verifying moves and tracing the pile of stones? -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: could use some help with this problem! (Posting On Python-List Prohibited)
Lawrence D’Oliveiro writes: > On Wednesday, February 21, 2018 at 3:10:25 AM UTC+13, Ben Bacarisse wrote: >> You almost never /have/ to use nested loops. Has the course got this >> far without introducing the idea of a function? > > If you are using a function to avoid a nested loop, perhaps that’s not > such a smart use of a function... Agreed. And yet it /might/ be a smart use of one. Nothing about simply avoiding a loop is sufficient to make the assessment. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: How to make Python run as fast (or faster) than Julia
Steven D'Aprano writes: > On Fri, 23 Feb 2018 00:26:33 +, bartc wrote: > >> The point of the article was Julia vs. Python. You can't make Python >> faster by switching to a faster algorithm; you have to use the same one >> on both. > > No, the point of the article was to write Python code that is as fast as > the Julia code. I did not get that impression. In fact I was not really sure what the point was. At the start, the authors says "My take on this kind of cross language comparison is that the benchmarks should be defined by tasks to perform, then have language experts write the best code they can to perform these tasks." but if that is the point (rather the one on you picked up on) then the article could be, at best, only half the story. > I don't know why the Julia programmers chose to use such a poor > algorithm: It's odd indeed, but given that they did, what you take to be the point of the article -- to write a good Python algorithm as fast as the terrible Julia one -- seems a bit pointless. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: How to make Python run as fast (or faster) than Julia
bartc writes: > A C version is given below. (One I may have messed around with, which > I'm not sure works properly. For an original, google for Marsaglia and > KISS64 or SUPRKISS64.) The version I know uses unsigned integers. Did you change then to signed? For a Python version, go back to the original C and work from there. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: How to make Python run as fast (or faster) than Julia
Christian Gollwitzer writes: > George Marsaglia is a researcher who invented a couple of PRNGs which > are both simple (one of the first was called KISS) yet surprisingly > good. s/is/was/ Sadly, he died a few years ago (2011). -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Local variable definition in Python list comprehension
James Tsai writes: > I find it very useful if I am allowed to define new local variables in > a list comprehension. For example, I wish to have something like > [(x, y) for x in range(10) for y := x ** 2 if x + y < 80], or > [(x, y) for x in range(10) with y := x ** 2 if x + y < 80]. > > For now this functionality can be achieved by writing > [(x, y) for x in range(10) for y in [x ** 2] if x + y < 80]. x and y are, to a first approximation, new local variables defined in a list comprehension. I think you need to restate what it is you want. > Is it worthwhile to add a new feature like this in Python? If so, how > can I propose this to PEP? To make any sort of case you'd need to give an example that does not have a clearer way to write it already. Your working version is, to me, clearer that the ones you want to be able to write. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: bool and int
Chris Angelico writes: > On Thu, 26 Jan 2023 at 08:19, Dino wrote: >> >> On 1/23/2023 11:22 PM, Dino wrote: >> > >>> b = True >> > >>> isinstance(b,bool) >> > True >> > >>> isinstance(b,int) >> > True >> > >>> >> >> ok, I read everything you guys wrote. Everyone's got their reasons >> obviously, but allow me to observe that there's also something called >> "principle of least surprise". >> >> In my case, it took me some time to figure out where a nasty bug was >> hidden. Letting a bool be a int is quite a gotcha, no matter how hard >> the benevolent dictator tries to convince me otherwise! >> > > Try this (or its equivalent) in as many languages as possible: > > x = (1 > 2) > x == 0 > > You'll find that x (which has effectively been set to False, or its > equivalent in any language) will be equal to zero in a very large > number of languages. Thus, to an experienced programmer, it would > actually be quite the opposite: having it NOT be a number would be the > surprising thing! I think the programmer's experience would have to have been rather narrow to be surprised by x not being treated as a number. I started with Fortran, Lisp, Pascal and two variants of Algol so I started out un-surprised by Boolean being a non-arithmetic type. To be surprised by x (above) /not/ being treated as a number, an experienced programmer would have had to have avoided a lot of strictly typed languages. I've just tried Scheme, Haskell, Common Lisp, Ada, Algol-68, go, ML, Rust, Ruby, Java, Lua, Prolog and Fortran and they all either say "no way!" or give false for x == 0. Of course these are not random choices, but it shows that Python's design is very far from universal. But then this is not a numbers game, anyway. A programmer need only to have used one or two languages that are rather more strict about types to find such a thing unsurprising in future. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: evaluation question
mutt...@dastardlyhq.com writes: > Hi It looks like you posted this question via Usenet. comp.lang.python is essentially dead as a Usenet group. It exists, and gets NNTP versions of mail sent to the mailing list, but nothing posted to the group via NNTP get send on the mailing list. I prefer Usenet and dislike mailing lists but that just means I can't really contribute to this "group" The "python-list" an an excellent resource (if you like the email interface) and you can subscribe here: https://mail.python.org/mailman/listinfo/python-list>, > This is probably a dumb newbie question but I've just started to learn > python3 and eval() isn't behaving as I'd expect in that it works for > some things and not others. eg: > eval("1+1") > 2 eval("print(123)") > 123 eval("for i in range(1,10): i") > Traceback (most recent call last): > File "", line 1, in > File "", line 1 > for i in range(1,10): i > ^ > SyntaxError: invalid syntax > > Why did the 3rd one fail? Does it not handle complex expressions? It handles only expressions, and "for i in range(1,10): i" is not an expression. You can use >>> exec("for i in range(1,10): i") or, to confirm that something is happening: >>> exec("for i in range(1,10): print(i)") 1 2 3 4 5 6 7 8 9 See: https://docs.python.org/3/library/functions.html?highlight=eval#eval and the immediately following entry. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Usenet vs. Mailing-list
"Peter J. Holzer" writes: > On 2023-01-27 21:04:58 +, Ben Bacarisse wrote: >> mutt...@dastardlyhq.com writes: >> >> > Hi >> >> It looks like you posted this question via Usenet. comp.lang.python is >> essentially dead as a Usenet group. It exists, and gets NNTP versions >> of mail sent to the mailing list, but nothing posted to the group via >> NNTP get send on the mailing list. > > This is wrong. I did get Muttley's any your postings via the > mailing-list. Ah, OK. I thought that was the case but I am obviously wrong. Has there been a change, or have I been wrong for a long time!? There may be a timing issue because I tried to find a reply a Usenet injected post from a mailing-list user and, at the time I looked, I could not find one. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Usenet vs. Mailing-list
Jon Ribbens writes: > On 2023-01-29, Ben Bacarisse wrote: >> "Peter J. Holzer" writes: >> >>> On 2023-01-27 21:04:58 +, Ben Bacarisse wrote: >>>> mutt...@dastardlyhq.com writes: >>>> >>>> > Hi >>>> >>>> It looks like you posted this question via Usenet. comp.lang.python is >>>> essentially dead as a Usenet group. It exists, and gets NNTP versions >>>> of mail sent to the mailing list, but nothing posted to the group via >>>> NNTP get send on the mailing list. >>> >>> This is wrong. I did get Muttley's any your postings via the >>> mailing-list. >> >> Ah, OK. I thought that was the case but I am obviously wrong. Has >> there been a change, or have I been wrong for a long time!? > > I'm not aware of any significant period in the last twenty-one years > that it hasn't been working. Although sometimes it does feel like it > isn't, in that I reply to a post with an answer and then several > other people reply significantly later with the same answer, as if > my one had never existed... but whenever I check into it, my message > has actually always made it to the list. I have had the same experience and, as a result, I rarely post. Maybe what I have to say is simply not interesting! -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Usenet vs. Mailing-list
Igor Berger writes: > On Saturday, January 28, 2023 at 10:02:57 PM UTC-5, Ben Bacarisse wrote: >> Jon Ribbens writes: >> >> > On 2023-01-29, Ben Bacarisse wrote: >> >> "Peter J. Holzer" writes: >> >> >> >>> On 2023-01-27 21:04:58 +, Ben Bacarisse wrote: >> >>>> mut...@dastardlyhq.com writes: >> >>>> >> >>>> > Hi >> >>>> >> >>>> It looks like you posted this question via Usenet. comp.lang.python is >> >>>> essentially dead as a Usenet group. It exists, and gets NNTP versions >> >>>> of mail sent to the mailing list, but nothing posted to the group via >> >>>> NNTP get send on the mailing list. >> >>> >> >>> This is wrong. I did get Muttley's any your postings via the >> >>> mailing-list. >> >> >> >> Ah, OK. I thought that was the case but I am obviously wrong. Has >> >> there been a change, or have I been wrong for a long time!? >> > >> > I'm not aware of any significant period in the last twenty-one years >> > that it hasn't been working. Although sometimes it does feel like it >> > isn't, in that I reply to a post with an answer and then several >> > other people reply significantly later with the same answer, as if >> > my one had never existed... but whenever I check into it, my message >> > has actually always made it to the list. >> >> I have had the same experience and, as a result, I rarely post. Maybe >> what I have to say is simply not interesting! >> > > If I remember correctly, multiple regulars that use the mailing list > mentioned that they "killfiled" posts originating from Google groups. > This may contribute to such situations. Ah, that may explain most of my confusion. I know I stopped posting because there didn't seem to be much engagement, but maybe it was just many list members choosing not to see my posts rather than all list members not being able to see my posts. As I said, I did check to see if I could find a reply to a Usenet-originated post from a list member but my not being able to find one could just be down to many list members filtering Usenet posts. It's clearly not universal. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: sqlite3 cannot detect the version of compiled sqlite version at some point in runtime.
panfei writes: > 4. Test sqlite3 > Python 3.9.1 (default, Jan 20 2021, 14:32:50) > [GCC 10.2.0] on linux > Type "help", "copyright", "credits" or "license" for more information. import sqlite3 conn = sqlite3.connect(':memory:') conn.create_function('f', 2, lambda *args: None, deterministic=True) > Traceback (most recent call last): > File "", line 1, in > sqlite3.NotSupportedError: deterministic=True requires SQLite 3.8.3 or higher sqlite3.sqlite_version > '3.34.0' sqlite3.version > '2.6.0' > > It reports "deterministic=True requires SQLite 3.8.3 or higher", but > when execute sqlite3.sqlite_version it returns 3.34.0 which higher > than 3.8.3. > > Is there any advice on this issue? thanks. Sorry, no, but I can add a data point. It works for me on my Ubuntu system with these versions: $ python3 Python 3.8.5 (default, Jul 28 2020, 12:59:40) [GCC 9.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import sqlite3 >>> sqlite3.sqlite_version '3.31.1' >>> sqlite3.version '2.6.0' >>> conn = sqlite3.connect(':memory:') >>> conn.create_function('f', 2, lambda *args: None, deterministic=True) >>> -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Mr. Flibble
Mr Flibble writes: > On 15/02/2021 18:09, Ethan Furman wrote: >> Thank you to those who pointed out this individual to the >> moderators. As Mr. Flibble accurately noted, he is not on the mailing >> list -- so his posts won't be here either. > > ORLY? You said you used Usenet (and your reply here was via Usenet). Usenet posts to comp.lang.python don't go to the mailing list (the "here" that Ethan is talking about). Mails to the list /are/ sent here, but it's one-way traffic. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Mr. Flibble
Ethan Furman writes: > On 2/15/21 2:02 PM, Grant Edwards wrote: >> On 2021-02-15, Ben Bacarisse wrote: >> >>> You said you used Usenet (and your reply here was via Usenet). >>> Usenet posts to comp.lang.python don't go to the mailing list (the >>> "here" that Ethan is talking about). Mails to the list /are/ sent >>> here, but it's one-way traffic. >> >> That's new -- it always used to be two-way. When did it change? > > It is two-way still (or we wouldn't have seen his posts to begin > with). Ah, my mistake. Sorry for the confusion. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: New Python implementation
"Avi Gross" writes: > Thanks for sharing. I took a look and he does have a few schemas for Ada and > C from TWO YEARS ago. Nothing about the infinite number of other languages > he plans on supporting, let alone Python. And what he has is likely not > enough to do what he claims he can do easily and rapidly. The C schema says almost nothing about C. It lists one kind of comment and a few type names. Significantly, it says almost nothing about the semantics of even the tiny fragment of C presented. Attempts at a universal compiler stalled in the 1980s (though there may have been some new developments since I stopped looking) because expressing the semantics of different languages is so very hard. In fact, much of the interest in pursuing the idea came from benefits that would be derived simply from having a language's semantics formally described. I don't think there is anything to see here. If the author had come up with some new ways to tackle any of the problems, he would be telling people about these, not saying "be patient" (and bad-mouthing CPython). -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: neonumeric - C++ arbitrary precision arithmetic library
Mr Flibble writes: >> Someone who says that he is capable of writing a compiler that >> translates every language has megalomania. No one can do this. > > Just because you can't make one it doesn't follow that nobody else > can. True, but lots of very knowledgeable people have tried and failed. And although you use the present tense "my universal compiler, neos, that /can/ compile any programming language" (emphasis mine) you currently have nothing to show -- no compiler for any language, no paper outlining how you plan to overcome the problems that stumped others, nothing but what appears to be a false claim about neos can do. If you want this project to be taken seriously, you are going about it the wrong way. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Help with gaussian filter from scipy
Arak Rachael writes: > this time I am stuck on gaussian_filter scipy returns none instead of some > valid gaussian filtered image, can someone help me please. > > Here is the full code: > https://www.dropbox.com/s/18ylpiwmhlu5n62/test_filter_xdog.ipynb?dl=0 It might help to link to the code itself so people can look at it without having to load up a project. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Help with gaussian filter from scipy
Arak Rachael writes: > On Wednesday, 7 July 2021 at 12:47:40 UTC+2, Arak Rachael wrote: >> On Wednesday, 7 July 2021 at 12:41:44 UTC+2, Ben Bacarisse wrote: >> > Arak Rachael writes: >> > >> > > this time I am stuck on gaussian_filter scipy returns none instead of >> > > some valid gaussian filtered image, can someone help me please. >> > > >> > > Here is the full code: >> > > https://www.dropbox.com/s/18ylpiwmhlu5n62/test_filter_xdog.ipynb?dl=0 >> > It might help to link to the code itself so people can look at it >> > without having to load up a project. >> > >> > -- >> > Ben. >> Sorry I don't have this option. >> >> I loaded it in PyCharm and this is what I got: >> >> /home/yordan/anaconda3/envs/testing/bin/python >> /home/yordan/pycharm/plugins/python-ce/helpers/pydev/pydevd.py --multiproc >> --qt-support=auto --client 127.0.0.1 --port 36321 --file >> /home/yordan/devel/python.assignments/topgis-viz/topgisviz/xdog.py >> Connected to pydev debugger (build 211.7442.45) >> Usage: python xdog.py FILE OUTPUT >> >> I tried creating "'./textures/hatch.jpg" image, but it did not work. > > Sorry for taking your time, this turns to be a dum question, I needed > to supply in file and out file in the command line. No worries. Sometimes just posting the question make you look at it differently. If you can post code, it's much better to do that. Had it been a little bit more obscure a problem, someone might have spotted it but they may not have wanted to load a project file. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Unexpected behaviour of math.floor, round and int functions (rounding)
Chris Angelico writes: > On Sat, Nov 20, 2021 at 5:08 AM ast wrote: >> >>> 0.3 + 0.3 + 0.3 == 0.9 >> False > > That's because 0.3 is not 3/10. It's not because floats are > "unreliable" or "inaccurate". It's because the ones you're entering > are not what you think they are. > > When will people understand this? > > (Probably never. Sigh.) Most people understand what's going on when it's explained to them. And I think that being initially baffled is not unreasonable. After all, almost everyone comes to computers after learning that 3/10 can be written as 0.3. And Python "plays along" with the fiction to some extent. 0.3 prints as 0.3, 3/10 prints as 0.3 and 0.3 == 3/10 is True. The language (a language, not Python) could tell you that you were not getting the value you asked for. Every 0.3 could come with a warning that 0.3 can not be represented exactly as a floating point value. To avoid the warning, the programmer would write ~0.3 meaning, exactly, the binary (or whatever the base really is) floating point number closest to 0.3. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Unexpected behaviour of math.floor, round and int functions (rounding)
Chris Angelico writes: > On Sat, Nov 20, 2021 at 9:07 AM Ben Bacarisse wrote: >> >> Chris Angelico writes: >> >> > On Sat, Nov 20, 2021 at 5:08 AM ast wrote: >> >> >> >>> 0.3 + 0.3 + 0.3 == 0.9 >> >> False >> > >> > That's because 0.3 is not 3/10. It's not because floats are >> > "unreliable" or "inaccurate". It's because the ones you're entering >> > are not what you think they are. >> > >> > When will people understand this? >> > >> > (Probably never. Sigh.) >> >> Most people understand what's going on when it's explained to them. And >> I think that being initially baffled is not unreasonable. After all, >> almost everyone comes to computers after learning that 3/10 can be >> written as 0.3. And Python "plays along" with the fiction to some >> extent. 0.3 prints as 0.3, 3/10 prints as 0.3 and 0.3 == 3/10 is True. > > In grade school, we learn that not everything can be written that way, > and 1/3 isn't actually equal to 0.33. Yes. We learn early on that 0.33 means 33/100. We don't learn that 0.33 is a special notation for machines that have something called "binary floating point hardware" that does not mean 33/100. That has to be learned later. And every generation has to learn it afresh. > Yet somehow people > understand that computers speak binary ("have you learned to count > yet, or are you still on zeroes and ones?" -- insult to a machine > empire, in Stellaris), but don't seem to appreciate that floats are > absolutely accurate and reliable, just in binary. Yes, agreed, but I was not commenting on the odd (and incorrect) view that floating point operations are not reliable and well-defined, but on the reasonable assumption that a clever programming language might take 0.3 to mean what I was taught it meant in grade school. As an old hand, I know it won't (in most languages), and I know why it won't, and I know why that's usually the right design choice for the language. But I can also appreciate that it's by no means obvious that, to a beginner, "binary" implies the particular kind of representation that makes 0.3 not mean 3/10. After all, the rational 3/10 can be represented exactly in binary in many different ways. > But lack of knowledge is never a problem. (Or rather, it's a solvable > problem, and I'm always happy to explain things to people.) The > problem is when, following that lack of understanding, people assume > that floats are "unreliable" or "inaccurate", and that you should > never ever compare two floats for equality, because they're never > "really equal". That's what leads to horrible coding practices and > badly-defined "approximately equal" checks that cause far more harm > than a simple misunderstanding ever could on its own. Agreed. Often, the "explanations" just make things worse. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Unexpected behaviour of math.floor, round and int functions (rounding)
Chris Angelico writes: > On Sat, Nov 20, 2021 at 12:43 PM Ben Bacarisse wrote: >> >> Chris Angelico writes: >> >> > On Sat, Nov 20, 2021 at 9:07 AM Ben Bacarisse wrote: >> >> >> >> Chris Angelico writes: >> >> >> >> > On Sat, Nov 20, 2021 at 5:08 AM ast wrote: >> >> >> >> >> >>> 0.3 + 0.3 + 0.3 == 0.9 >> >> >> False >> >> > >> >> > That's because 0.3 is not 3/10. It's not because floats are >> >> > "unreliable" or "inaccurate". It's because the ones you're entering >> >> > are not what you think they are. >> >> > >> >> > When will people understand this? >> >> > >> >> > (Probably never. Sigh.) >> >> >> >> Most people understand what's going on when it's explained to them. And >> >> I think that being initially baffled is not unreasonable. After all, >> >> almost everyone comes to computers after learning that 3/10 can be >> >> written as 0.3. And Python "plays along" with the fiction to some >> >> extent. 0.3 prints as 0.3, 3/10 prints as 0.3 and 0.3 == 3/10 is True. >> > >> > In grade school, we learn that not everything can be written that way, >> > and 1/3 isn't actually equal to 0.33. >> >> Yes. We learn early on that 0.33 means 33/100. >> We don't learn that 0.33 is a special notation for machines that >> have something called "binary floating point hardware" that does not >> mean 33/100. That has to be learned later. And every >> generation has to learn it afresh. > > But you learn that it isn't the same as 1/3. That's my point. You > already understand that it is *impossible* to write out 1/3 in > decimal. Is it such a stretch to discover that you cannot write 3/10 > in binary? > > Every generation has to learn about repeating fractions, but most of > us learn them in grade school. Every generation learns that computers > talk in binary. Yet, putting those two concepts together seems beyond > many people, to the point that they feel that floating point can't be > trusted. Binary is a bit of a red herring here. It's the floating point format that needs to be understood. Three tenths can be represented in many binary formats, and even decimal floating point will have some surprises for the novice. >> Yes, agreed, but I was not commenting on the odd (and incorrect) view >> that floating point operations are not reliable and well-defined, but on >> the reasonable assumption that a clever programming language might take >> 0.3 to mean what I was taught it meant in grade school. > > It does mean exactly what it meant in grade school, just as 1/3 means > exactly what it meant in grade school. Now try to represent 1/3 on a > blackboard, as a decimal fraction. If that's impossible, does it mean > that 1/3 doesn't mean 1/3, or that 1/3 can't be represented? As you know, it is possible, but let's say we outlaw any finite notation for repeated digits... Why should I convert 1/3 to this particular apparently unsuitable representation? I will write 1/3 and manipulate that number using factional notation. The novice programmer might similarly expect that when they write 0.3, the program will manipulate that number as the faction it clearly is. They may well be surprised by the fact that it must get put into a format that can't represent what those three characters mean, just as I would be surprised if you insisted I write 1/3 as a finite decimal (with no repeat notation). I'm not saying your analogy would not help someone understand, but you first have to explain why 0.3 is not treated as three tenths -- why I (to use your analogy) must not keep 1/3 as a proper fraction, but I must instead write it using a finite number of decimal digits. Neither is, in my view, obvious to the beginner. >> > But lack of knowledge is never a problem. (Or rather, it's a solvable >> > problem, and I'm always happy to explain things to people.) The >> > problem is when, following that lack of understanding, people assume >> > that floats are "unreliable" or "inaccurate", and that you should >> > never ever compare two floats for equality, because they're never >> > "really equal". That's what leads to horrible coding practices and >> > badly-defined "approximately equal" checks that cause far more harm >> > than a simple misunderstanding
Re: Unexpected behaviour of math.floor, round and int functions (rounding)
Chris Angelico writes: > On Sat, Nov 20, 2021 at 3:41 PM Ben Bacarisse wrote: >> >> Chris Angelico writes: >> >> > On Sat, Nov 20, 2021 at 12:43 PM Ben Bacarisse >> > wrote: >> >> >> >> Chris Angelico writes: >> >> >> >> > On Sat, Nov 20, 2021 at 9:07 AM Ben Bacarisse >> >> > wrote: >> >> >> >> >> >> Chris Angelico writes: >> >> >> >> >> >> > On Sat, Nov 20, 2021 at 5:08 AM ast wrote: >> >> >> >> >> >> >> >>> 0.3 + 0.3 + 0.3 == 0.9 >> >> >> >> False >> >> >> > >> >> >> > That's because 0.3 is not 3/10. It's not because floats are >> >> >> > "unreliable" or "inaccurate". It's because the ones you're entering >> >> >> > are not what you think they are. >> >> >> > >> >> >> > When will people understand this? >> >> >> > >> >> >> > (Probably never. Sigh.) >> >> >> >> >> >> Most people understand what's going on when it's explained to them. >> >> >> And >> >> >> I think that being initially baffled is not unreasonable. After all, >> >> >> almost everyone comes to computers after learning that 3/10 can be >> >> >> written as 0.3. And Python "plays along" with the fiction to some >> >> >> extent. 0.3 prints as 0.3, 3/10 prints as 0.3 and 0.3 == 3/10 is True. >> >> > >> >> > In grade school, we learn that not everything can be written that way, >> >> > and 1/3 isn't actually equal to 0.33. >> >> >> >> Yes. We learn early on that 0.33 means 33/100. >> >> We don't learn that 0.33 is a special notation for machines that >> >> have something called "binary floating point hardware" that does not >> >> mean 33/100. That has to be learned later. And every >> >> generation has to learn it afresh. >> > >> > But you learn that it isn't the same as 1/3. That's my point. You >> > already understand that it is *impossible* to write out 1/3 in >> > decimal. Is it such a stretch to discover that you cannot write 3/10 >> > in binary? >> > >> > Every generation has to learn about repeating fractions, but most of >> > us learn them in grade school. Every generation learns that computers >> > talk in binary. Yet, putting those two concepts together seems beyond >> > many people, to the point that they feel that floating point can't be >> > trusted. >> >> Binary is a bit of a red herring here. It's the floating point format >> that needs to be understood. Three tenths can be represented in many >> binary formats, and even decimal floating point will have some surprises >> for the novice. > > Not completely a red herring; binary floating-point as used in Python > (IEEE double-precision) is defined as a binary mantissa and a scale, > just as "blackboard arithmetic" is generally defined as a decimal > mantissa and a scale. (At least, I don't think I've ever seen anyone > doing arithmetic on a blackboard in hex or octal.) You seem to be agreeing with me. It's the floating point part that is the issue, not the base itself. >> >> Yes, agreed, but I was not commenting on the odd (and incorrect) view >> >> that floating point operations are not reliable and well-defined, but on >> >> the reasonable assumption that a clever programming language might take >> >> 0.3 to mean what I was taught it meant in grade school. >> > >> > It does mean exactly what it meant in grade school, just as 1/3 means >> > exactly what it meant in grade school. Now try to represent 1/3 on a >> > blackboard, as a decimal fraction. If that's impossible, does it mean >> > that 1/3 doesn't mean 1/3, or that 1/3 can't be represented? >> >> As you know, it is possible, but let's say we outlaw any finite notation >> for repeated digits... Why should I convert 1/3 to this particular >> apparently unsuitable representation? I will write 1/3 and manipulate >> that number using factional notation. > > If you want that, the fractions module is there for you. Yes, I know. The only point of disagreement (as far as can s
Re: Unexpected behaviour of math.floor, round and int functions (rounding)
Grant Edwards writes: > On 2021-11-20, Ben Bacarisse wrote: > >> You seem to be agreeing with me. It's the floating point part that is >> the issue, not the base itself. > > No, it's the base. Floating point can't represent 3/10 _because_ it's > base 2 floating point. Floating point in base 10 doesn't have any > problem representing 3/10. Every base has the same problem for some numbers. It's the floating point part that causes the problem. Binary and decimal stand out because we write a lot of decimals in source code and computers use binary, but if decimal floating point were common (as it increasingly is) different fractions would become the oft quoted "surprise" results. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: I am new to python. I have a few questions coming from an armature!
MRAB writes: > On 2016-08-17 18:19, Jussi Piitulainen wrote: >> MRAB writes: >> >>> On 2016-08-17 12:24, Jussi Piitulainen wrote: BartC writes: > On 17/08/2016 07:39, Steven D'Aprano wrote: >> Rather than ask why Python uses `trueval if cond else falseval`, you >> should ask why C uses `cond ? trueval : falseval`. Is that documented >> anywhere? > > I'm not fond of C's a ? b : c but the principle is sound. I generally [- -] > Anyway a?b:c was existing practice. At least the order of a,b,c could > have been retained if not the exact syntax. The original was (c1 -> e1, c2 -> e2, ..., cn -> en) in John McCarthy's 1960 paper on symbolic expressions, with an actual arrow glyph in place of hyphen-greater-than. >>> [snip] >>> >>> BCPL, the ancestor of C, had: >>> >>> a -> b, c >> >> Nice. Add a redundant pair of parentheses and it's the same. (When used >> as an expression, a final else-branch is mandatory-ish.) >> >> But C uses -> for something else, I think. And other languages use it >> for lambda expressions (succesfully, I think, but then they don't have >> it available for this purpose). >> > C uses "->" for dereferencing a pointer to the member of a struct. Slightly better wording: it uses -> to access a struct member via a pointer to the struct. > If "p" points to a struct (record), then "*p" is that struct, and if > that struct has a member (field) "m", then that member can be accessed > by "(*p)->m" (the parens are necessary because of the operator > precedence). I think you meant (*p).m here because you go on to correct say that -> offers a shorthand for this rather messy access: > This can be abbreviated to "p->m". > > Pascal, on the other hand, dereferences with a postfixed "^", so that > would be "p^.m". > -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: I am new to python. I have a few questions coming from an armature!
Jussi Piitulainen writes: > BartC writes: > >> On 17/08/2016 07:39, Steven D'Aprano wrote: >>> Rather than ask why Python uses `trueval if cond else falseval`, you >>> should ask why C uses `cond ? trueval : falseval`. Is that documented >>> anywhere? >> >> I'm not fond of C's a ? b : c but the principle is sound. I generally > > [- -] > >> Anyway a?b:c was existing practice. At least the order of a,b,c could >> have been retained if not the exact syntax. > > The original was (c1 -> e1, c2 -> e2, ..., cn -> en) in John McCarthy's > 1960 paper on symbolic expressions, with an actual arrow glyph in place > of hyphen-greater-than. And BCPL (Martin Richards 1967) took the same arrow and comma syntax. BCPL spawned B which led to C, but in B Thompson used ? and : but kept the right-to-left binding. I think the change was unfortunate because the arrow works well in various layouts and looks much better when chained (though that might just be my bias from being a BCPL coder from way back). -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: The Joys Of Data-Driven Programming
Tim Chase writes: > On 2016-08-21 04:53, Rustom Mody wrote: >> 2. Basic computing theory shows that re-s and dfas are equivalent. >> Which would one prefer to write/debug? [Thats not a rhetorical >> question] > > I'm curious where REs and DFAs are shown to be equivalent (serious, > not trying to be snarky). I can see with no trouble that all REs are > DFAs, but can't convince myself that *all* DFAs are REs. All NFAs as well -- the don't have to be deterministic in either direction. > Though this > might also depend on the RE engine. Yes. Due to their use in real systems, lots of RE engines have acquired many bells and whistles. Some bells so fancy that the resulting "REs" can recognise whole new classes of language. In this context, though, "regular expression" means the expression form of regular grammars (level 3 in the Chomsky hierarchy). > Do you have links to resources > on such an "all REs have equivalent DFAs and all DFAs have equivalent > REs" logic/argument? Or maybe my understanding of DFAs is flawed. This is called Kleene's Theorem. Searching for that will bring up all sorts of proofs in various styles. Here's one of the direction you are asking about: http://www.cs.may.ie/staff/jpower/Courses/Previous/parsing/node6.html The other direction is covered all over the place because it it so often used inside an RE matching engine to "compile" the RE. > And as for which I prefer to write, for simple text-processing that > doesn't involve nesting, I generally prefer REs; but for more complex > processing, a custom DFA tends to expand a bit more cleanly in my > experience. You may be confusing DFAs and pushdown automata. I say this because of your reference to nesting. PDAs can be thought of as either DFAs or NFAs with a stack so they can recognise languages with nested structure. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: What's the best way to minimize the need of run time checks?
Steve D'Aprano writes: > On Mon, 29 Aug 2016 10:31 pm, Chris Angelico wrote: > >> On Mon, Aug 29, 2016 at 10:13 PM, BartC wrote: >>> In C, you can write this: >>> >>> int x; >>> >>> x = 5; >>> x = "hello"; >>> >>> With certain compilers (eg. gcc) you only get a warning. (And since I >>> don't show warnings to avoid inundation, that seems to compile fine for >>> me!) >> >> That's because strings, in C, are really pointers-to-char, They are really arrays of char, but array values convert to pointers to the first element in so many situations that people end up thinking that they are pointers. The trouble is, once you start thinking they really are pointers-to-char you have a harder time understanding things like &"hello" and sizeof "hello". >> and for >> hysterical raisins, pointers can be assigned to integers with just a >> warning. (Good code should have an explicit cast here.) The code is wrong without a cast. Many compilers, in their default setting, are very generous about this situation, but the code is as wrong a C code can be. The assignment violates a language constraint and the compiler would be permitted to refuse to generate any code at all. Given all that, it's something of an understatement to say that good code should use a cast (which is always explicit). (I'd go further and say that good code should try to avoid doing this at all, and when it absolutely must, it should use intptr_t rather than int.) > Let me see if I've got this straight... Bart's second assignment will > allocate a block of memory at least five bytes in size, stuff the ASCII > codes for 'h', 'e', 'l', 'l' and 'o' in that block (possibly with a null > byte at the end?) and then assign x to the address of that block. Close, but the array of char is not generated by the assignment. String literals give rise to arrays with static storage duration (in effect they exist before the start of the execution). It will be 6 bytes in size. The assignment might do nothing at all because it violates a language constraint about permitted types in an assignment. But if it does do something, a good bet will be to do the usual array to pointer conversion and then try to convert that pointer to an int for assignment. > Am I right? > > That's better than my first thought, which was that it would write either > > 0x6865 ('he', if int is 16 bits) > > or > > 0x68656c6c ('hell', if int is 32 bits) > > to x, and either discard the rest of the characters or just blindly write > them over the top of whatever variable (if any) happens to follow x in > memory. Well, your first thought is not actually wrong. In fact, a compiler would be allowed to do that since the behaviour of a program that violates a constraint is undefined by the language standard. It would not sell or get used much because people expect the traditional lax treatment of pointers as integers, but it could do that. >> Getting inundated with warnings would be a major code smell. > > "The low oil warning light in my car was always on, so I put some masking > tape over it so it wasn't bothering me any more." Yup. Gcc lets you put masking tape on (-Wno-int-conversion) but, in fairness, it also lets you treat all or selected warnings as hard errors (-Werror=int-conversion). Unfortunately there is no single option that treats all serious situations as hard errors, presumably because no two people agree on what should be considered serious for a particular architecture. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Assignment versus binding
Marko Rauhamaa writes: > dieter : >> The concept "assignment" comes from an operational semantics based on >> some form of "RAM" machine. Such a machine has storage cells where you >> can assign values to which remain there until overridden with a new >> value. >> >> The concept "binding" comes from a denotational semantics based on >> some form of functions where parameter names are bound to values on >> function "application" and do not change inside the function. > > I wonder if such pure-bred functional programming languages exist. I'd put Haskell in that that class. > Lisp, > Scheme and Python don't belong to them, at least. Object-oriented > programming is not really possible without assignment. Even Scheme's > "letrec" appeals to assignment semantics. Haskell defines let (it's version of multiple mutually recursive bindings) in terms of the least fix point of a lambda function whose (pattern) parameter binds the expressions in the definitions. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Assignment versus binding
Steve D'Aprano writes: > On Tue, 4 Oct 2016 11:27 pm, Ben Bacarisse wrote: > >> Haskell defines let (it's version of multiple mutually recursive >> bindings) in terms of the least fix point of a lambda function whose >> (pattern) parameter binds the expressions in the definitions. > > It binds *the expression* itself? Not the value of the expression? Yes and no. The result is as if the value is bound, but (a) Haskell is lazy so in some sense it is the expression that is bound and (b) this is a definition of the semantics, not Haskell itself. The least fixed point operator has the effect of binding all the names in the expression to the result of binding all the names in expression to the result of binding all the names in the expression to the result of... In effect I'm not entirely sure how to answer your question (but I repeat that this is how a syntactic feature is defined, not how you write Haskell). > So Haskell uses some form of pass by name? No, just lazy evaluation. > And (shamelessly using Python syntax) if I have a function: > > > def spam(x): > print(x) > print(x+1) > > > and then call it: > > spam(time.sleep(60) or 1) > > > it will sleep for 60 seconds, print 1, then sleep for another 60 seconds, > then print 2. Is that right? Because Haskell is a Lazy language, the argument is not evaluated at the point of call -- it's only evaluated when x is needed. That part is like call by name and "binding the expression and not the value". But because it is also a purely function language, the result of an evaluation must always be the same, so the expression, once evaluated is not evaluated again, and in that sense it's not like call by name. The question came up because (I paraphrase) "even Scheme uses assignment to explain mutually recursive definitions". Haskell defines them using the fixed point operator. It's not really about Haskell programs so much as how the language features are defined. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list