Re: Quickie - Regexp for a string not at the beginning of the line

2012-10-25 Thread Ben Bacarisse
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

2012-10-26 Thread Ben Bacarisse
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 [ ]

2017-09-04 Thread Ben Bacarisse
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 [ ])

2017-09-04 Thread Ben Bacarisse
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 [ ])

2017-09-05 Thread Ben Bacarisse
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 [ ])

2017-09-06 Thread Ben Bacarisse
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 [ ])

2017-09-06 Thread Ben Bacarisse
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 [ ])

2017-09-07 Thread Ben Bacarisse
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

2017-09-08 Thread Ben Bacarisse
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

2017-09-13 Thread Ben Bacarisse
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

2017-09-18 Thread Ben Bacarisse
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

2017-09-18 Thread Ben Bacarisse
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

2017-09-18 Thread Ben Bacarisse
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

2017-09-20 Thread Ben Bacarisse
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

2017-09-20 Thread Ben Bacarisse
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

2017-09-25 Thread Ben Bacarisse
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

2017-10-01 Thread Ben Bacarisse
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

2017-10-01 Thread Ben Bacarisse
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

2017-10-02 Thread Ben Bacarisse
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"

2017-10-04 Thread Ben Bacarisse
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"

2017-10-04 Thread Ben Bacarisse
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"

2017-10-04 Thread Ben Bacarisse
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?

2017-10-04 Thread Ben Bacarisse
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"]

2017-10-05 Thread Ben Bacarisse
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"

2017-10-05 Thread Ben Bacarisse
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"]

2017-10-06 Thread Ben Bacarisse
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"]

2017-10-06 Thread Ben Bacarisse
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"

2017-10-06 Thread Ben Bacarisse
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"

2017-10-06 Thread Ben Bacarisse
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"

2017-10-06 Thread Ben Bacarisse
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"]

2017-10-11 Thread Ben Bacarisse
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"]

2017-10-11 Thread Ben Bacarisse
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"]

2017-10-11 Thread Ben Bacarisse
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"]

2017-10-11 Thread Ben Bacarisse
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"]

2017-10-11 Thread Ben Bacarisse
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"]

2017-10-11 Thread Ben Bacarisse
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"]

2017-10-11 Thread Ben Bacarisse
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"]

2017-10-12 Thread Ben Bacarisse
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"]

2017-10-12 Thread Ben Bacarisse
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"]

2017-10-12 Thread Ben Bacarisse
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"]

2017-10-12 Thread Ben Bacarisse
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"]

2017-10-12 Thread Ben Bacarisse
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"]

2017-10-12 Thread Ben Bacarisse
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"])

2017-10-12 Thread Ben Bacarisse
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"])

2017-10-13 Thread Ben Bacarisse
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"])

2017-10-13 Thread Ben Bacarisse
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"])

2017-10-14 Thread Ben Bacarisse
"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)

2017-10-14 Thread Ben Bacarisse
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)

2017-10-14 Thread Ben Bacarisse
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)

2017-10-15 Thread Ben Bacarisse
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

2017-10-23 Thread Ben Bacarisse
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

2017-10-24 Thread Ben Bacarisse
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

2017-10-24 Thread Ben Bacarisse
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

2017-10-24 Thread Ben Bacarisse
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

2017-10-24 Thread Ben Bacarisse
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

2017-10-26 Thread Ben Bacarisse
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

2017-10-27 Thread Ben Bacarisse
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

2017-10-28 Thread Ben Bacarisse
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

2017-10-29 Thread Ben Bacarisse
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

2017-10-31 Thread Ben Bacarisse
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

2017-10-31 Thread Ben Bacarisse
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

2017-11-01 Thread Ben Bacarisse
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`

2017-11-01 Thread Ben Bacarisse
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`

2017-11-02 Thread Ben Bacarisse
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`

2017-11-02 Thread Ben Bacarisse
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)

2017-12-30 Thread Ben Bacarisse
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)

2017-12-30 Thread Ben Bacarisse
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)

2017-12-31 Thread Ben Bacarisse
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)

2017-12-31 Thread Ben Bacarisse
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)

2017-12-31 Thread Ben Bacarisse
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?

2018-02-17 Thread Ben Bacarisse
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 !

2018-02-20 Thread Ben Bacarisse
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)

2018-02-20 Thread Ben Bacarisse
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

2018-02-23 Thread Ben Bacarisse
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

2018-02-26 Thread Ben Bacarisse
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

2018-02-27 Thread Ben Bacarisse
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

2022-09-01 Thread Ben Bacarisse
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

2023-01-26 Thread Ben Bacarisse
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

2023-01-27 Thread Ben Bacarisse
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

2023-01-28 Thread Ben Bacarisse
"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

2023-01-28 Thread Ben Bacarisse
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

2023-01-29 Thread Ben Bacarisse
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.

2021-01-20 Thread Ben Bacarisse
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

2021-02-15 Thread Ben Bacarisse
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

2021-02-15 Thread Ben Bacarisse
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

2021-02-16 Thread Ben Bacarisse
"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

2021-03-06 Thread Ben Bacarisse
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

2021-07-07 Thread Ben Bacarisse
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

2021-07-07 Thread Ben Bacarisse
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)

2021-11-19 Thread Ben Bacarisse
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)

2021-11-19 Thread Ben Bacarisse
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)

2021-11-19 Thread Ben Bacarisse
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)

2021-11-20 Thread Ben Bacarisse
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)

2021-11-20 Thread Ben Bacarisse
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!

2016-08-17 Thread Ben Bacarisse
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!

2016-08-17 Thread Ben Bacarisse
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

2016-08-21 Thread Ben Bacarisse
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?

2016-08-29 Thread Ben Bacarisse
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

2016-10-04 Thread Ben Bacarisse
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

2016-10-04 Thread Ben Bacarisse
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


  1   2   3   >