Re: Python Interview Questions

2012-07-10 Thread BartC



"Peter"  wrote in message 
news:35e7a860-fd41-4018-82f6-aabc32610...@googlegroups.com...
One of my favourite questions when interviewing - and it was 100% reliable 
:-) - "what are your hobbies?"


If the answer included programming then they were hired, if not, then they 
went to the "B" list.


In my experience, anybody who is really interested in programming will 
have it as a hobby (and is keen to learn even if they don't currently have 
the knowledge you require) - otherwise it is "just a job".


Won't they be tempted to work on their pet project instead of what they're 
being paid for? There's also the risk of mixing up software created at home, 
with that done at work, with all the intellectual property issues that might 
arise.


--
Bartc 


--
http://mail.python.org/mailman/listinfo/python-list


Re: Encapsulation, inheritance and polymorphism

2012-07-18 Thread BartC
"Lipska the Kat"  wrote in message 
news:c76dnv778_sw4zvnnz2dnuvz8ukdn...@bt.com...

On 18/07/12 01:46, Andrew Cooper wrote:



if not (you are permitted to do this):
 return -EPERM
if not (you've given me some valid data):
 return -EFAULT
if not (you've given me some sensible data):
 return -EINVAL
return actually_try_to_do_something_with(data)

How would you program this sort of logic with a single return statement?
  This is very common logic for all routines for which there is even the
remotest possibility that some data has come from an untrusted source.




someType result = -EINVAL //or your most likely or 'safest' result

if not (you are permitted to do this):
  result = -EPERM
if not (you've given me some valid data):
  result = -EFAULT
if not (you've given me some sensible data):
  result = -EINVAL
else
  result = -EDSOMETHING

  return result
}
//cohesive, encapsulated, reusable and easy to read


But, it works differently from the above. Perhaps replace some of those "if" 
statements with "elif".


The "return" version is handy because it provides a quick escape mechanism 
without cluttering up the rest of code with extra variables.


--
Bartc 


--
http://mail.python.org/mailman/listinfo/python-list


Re: Encapsulation, inheritance and polymorphism

2012-07-20 Thread BartC

"Erik Max Francis"  wrote in message
news:gskdnwoqpkoovztnnz2dnuvz5s2dn...@giganews.com...

On 07/20/2012 01:11 AM, Steven D'Aprano wrote:

On Thu, 19 Jul 2012 13:50:36 -0500, Tim Chase wrote:



I'm reminded of Graham's Number, which is so large that there aren't
enough molecules in the universe to write it out as a power tower
a^b^c^d^..., or even in a tower of hyperpowers a^^b^^c^^d^^... It was the
provable upper bound to a question to which experts in the field thought
the most likely answer was ... six.

(The bounds have since been reduced: the lower bound is now 13, and the
upper bound is *much* smaller than Graham's Number but still
inconceivably ginormous.)


You don't even need to go that high.  Even a run-of-the-mill googol
(10^100) is far larger than the total number of elementary particles in
the observable Universe.


But you can write it down, even as a straightforward number, without any 
problem. Perhaps a googolplex (10^10^100 iirc) would be difficult to write 
it down in full, but I have just represented it as an exponent with little 
difficulty.


These bigger numbers can't be written down, because there will never be
enough material, even using multiple systems of exponents.

(A few years ago the biggest number I'd heard of was Skewes' Number
(something like 10^10^10^34), but even that is trivial to write using
conventional exponents as I've just shown. Graham's Number is in a different
class altogether.)

--
Bartc 


--
http://mail.python.org/mailman/listinfo/python-list


Re: simplified Python parsing question

2012-08-03 Thread BartC
"Eric S. Johansson"  wrote in message 
news:mailman.2752.1343700723.4697.python-l...@python.org...

On 7/30/2012 9:54 PM, Steven D'Aprano wrote:


It would please me greatly if you would be willing to try an experiment. 
live my life for a while. Sit in a chair and tell somebody what to type 
and where to move the mouse without moving your hands. keep your hands 
gripping the arms or the sides of the chair. The rule is you can't touch 
the keyboard you can't touch the mice, you can't point at the screen. I 
suspect you would have a hard time surviving half a day with these 
limitations. no embarrassment in that, most people wouldn't make it as far 
as a half a day.


Just using speech? Probably more people than you might think have had such 
experiences: anyone who's done software support over the telephone for a 
start! And in that scenario, they are effectively 'blind' too.


--
Bartc 


--
http://mail.python.org/mailman/listinfo/python-list


Re: f python?

2012-04-08 Thread BartC

"Kaz Kylheku"  wrote in message
news:20120408114313...@kylheku.com...


Worse, the one byte Unix mistake being covered is, disappointingly, just a
clueless rant against null-terminated strings.

Null-terminated strings are infinitely better than the ridiculous
encapsulation of length + data.

For one thing, if s is a non-empty null terminated string then, cdr(s) is
also
a string representing the rest of that string without the first character,
where cdr(s) is conveniently defined as s + 1.


If strings are represented as (ptr,length), then a cdr(s) would have to
return (ptr+1,length-1), or (nil,0) if s was one character. No big deal.

(Note I saw your post in comp.lang.python; I don't about any implications of
that for Lisp.)

And if, instead, you want to represent all but the last character of the
string, then it's just (ptr,length-1). (Some checking is needed around empty
strings, but similar checks are needed around s+1.)

In addition, if you want to represent the middle of a string, then it's also
very easy: (ptr+a,b).


Not only can compilers compress storage by recognizing that string
literals are
the suffixes of other string literals, but a lot of string manipulation
code is
simplified, because you can treat a pointer to interior of any string as a
string.


Yes, the string "bart" also contains "art", "rt" and "t". But with counted
strintgs, it can also contain "bar", "ba", "b", etc

There are a few advantages to counted strings too...


length + data also raises the question: what type is the length field? One
byte? Two bytes? Four?


Depends on the architecture. But 4+4 for 32-bits, and 8+8 bytes for 64-bits,
I would guess, for general flex strings of any length.

There are other ways of encoding a length.

(For example I use one short string type of maximum M characters, but the
current length N is encoded into the string, without needing any extra count
byte (by fiddling about with the last couple of bytes). If you're trying to
store a short string in an 8-byte field in a struct, then this will let you
use all 8 bytes; a zero-terminated one, only 7.)


And then you have issues of byte order.


Which also affects every single value of more than one byte.


Null terminated
C strings can be written straight to a binary file or network socket and
be
instantly understood on the other end.


But they can't contains nulls!


Null terminated strings have simplified all kids of text manipulation,
lexical
scanning, and data storage/communication code resulting in immeasurable
savings over the years.


They both have their uses.

--
Bartc


--
http://mail.python.org/mailman/listinfo/python-list


Re: f python?

2012-04-10 Thread BartC
"Shmuel (Seymour J.)Metz"  wrote in 
message news:4f8410ff$2$fuzhry+tra$mr2...@news.patriot.net...

In <20120409111329@kylheku.com>, on 04/09/2012
  at 06:55 PM, Kaz Kylheku  said:



If we scan for a null terminator which is not there, we have a
buffer overrun.


You're only thinking of scanning an existing string; think of
constructing a string. The null only indicates the current length, not
the amount allocated.


If a length field in front of string data is incorrect, we also have
a buffer overrrun.


The languages that I'm aware of that use a string length field also
use a length field for the allocated storage. More precisely, they
require that attempts to store beyond the allocated length be
detected.


I would have thought trying to *read* beyond the current length would be an
error.

Writing beyond the current length, and perhaps beyond the current allocation
might be OK if the string is allowed grow, otherwise that's also an error.

In any case, there is no real need for an allocated length to be passed
around with the string, if you are only going to be reading it, or only
modifying the existing characters. And depending on the memory management
arrangements, such a length need not be stored at all.

--
Bartc


--
http://mail.python.org/mailman/listinfo/python-list


Re: Newbie, homework help, please.

2012-04-21 Thread BartC
"someone"  wrote in message 
news:32945367.2045.1335029313436.JavaMail.geo-discussion-forums@ynjn4...


6) Display the SHI data read from the file in the interpreter with a 
border around the SHI data (include a buffer of 1 line/space between the 
border and SHI data). An example might look like:


***
* *
* First Name and Last *
* ENGR 109-X  *
* Fall 2999   *
* Format Example  *
* *
***


I'm not a Python programmer, but I'll have a go at the text formatting bit:

text=["First Name and Last","ENGR 109-X","Fall 2999","Format Example"]

maxwidth=0
for s in text:
if len(s)>maxwidth: maxwidth=len(s)

vertinchlines=6# assume 6 lines/inch
hozinchchars=10# assume 10 chars/inch

hozmargin=" "*hozinchchars

newtext=[]
for i in range(vertinchlines):
newtext.append("")

newtext.append(hozmargin+"*"*(maxwidth+4)+hozmargin)
newtext.append(hozmargin+"* "+" "*maxwidth+" *"+hozmargin)

for s in text:
newtext.append(hozmargin+"* "+s+" "*(maxwidth-len(s))+" *"+hozmargin)

newtext.append(hozmargin+"* "+" "*maxwidth+" *"+hozmargin)
newtext.append(hozmargin+"*"*(maxwidth+4)+hozmargin)

for i in range(vertinchlines):
newtext.append("")

for s in newtext:
print (s)

--
Bartc  
--

http://mail.python.org/mailman/listinfo/python-list


Re: Newbie, homework help, please.

2012-04-21 Thread BartC

"someone"  wrote in message
news:4068590.2196.1335038608255.JavaMail.geo-discussion-forums@ynjn4...



textTuple = border(SHI)
for lines in textTuple:
print (lines)


Thanks your Bart for trying, I don't understand how it works or if you
tried to place my script in python to see if it would work, unfortunately,
I tried 10 different ways plus yours, and I don't see the connection.
Unless you were trying to help me see the way and I did not, sorry, but
thanks for trying. The characters did show me a little more.


Did you run my code fragment on it's own to see if it did the job?

The code can be packaged into a function border() just like you already 
have:


def border(text):
maxwidth=0
for s in text:
 if len(s)>maxwidth: maxwidth=len(s)

vertinchlines=6# assume 6 lines/inch
hozinchchars=10# assume 10 chars/inch

hozmargin=" "*hozinchchars

newtext=[]
for i in range(vertinchlines):
 newtext.append("")

newtext.append(hozmargin+"*"*(maxwidth+4)+hozmargin)
newtext.append(hozmargin+"* "+" "*maxwidth+" *"+hozmargin)

for s in text:
 newtext.append(hozmargin+"* "+s+" "*(maxwidth-len(s))+" *"+hozmargin)

newtext.append(hozmargin+"* "+" "*maxwidth+" *"+hozmargin)
newtext.append(hozmargin+"*"*(maxwidth+4)+hozmargin)

for i in range(vertinchlines):
 newtext.append("")

return newtext

And can be tested like this (obviously you will need to obtain SHI from the
input file):

SHI=["First Name and Last","ENGR 109-X","Fall 2999","Format Example"]

textTuple = border(SHI)

for lines in textTuple:
print (lines)

The text handling is clunky (I had to learn the Python as I went along), but
with these things you just want to get something working first, then you can
tweak.

--
Bartc 


--
http://mail.python.org/mailman/listinfo/python-list


Re: Newbie, homework help, please.

2012-04-21 Thread BartC

"someone"  wrote in message
news:9071485.2215.1335040139144.JavaMail.geo-discussion-forums@yniw15...


Thanks Bart for trying, it helped me out a little more by showing me a
little more than I knew, but I tried and I am not sure if it does fit my
example due to it was too many stars in between the lines, and not match
up, but if you see any more help, that would be great, or see something I
am doing wrong, or figure something out, let me know, have a great day,
again, thanks


Here's the example you posted:

***
* *
* First Name and Last *
* ENGR 109-X  *
* Fall 2999   *
* Format Example  *
* *
***

And here's the output from both bits of code I posted, which has 'one inch' 
of white space all around; both examples must be viewed with a fixed-pitch 
font (or in 'code' mode):







 ***
 * *
 * First Name and Last *
 * ENGR 109-X  *
 * Fall 2999   *
 * Format Example  *
 * *
 ***





Please post the output you're getting that has too many asterisks.

--
Bartc


--
http://mail.python.org/mailman/listinfo/python-list


Re: Newbie, homework help, please.

2012-04-21 Thread BartC

"someone"  wrote in message
news:9533449.630.1335042672358.JavaMail.geo-discussion-forums@ynmf4...

On Saturday, April 21, 2012 3:44:49 PM UTC-5, BartC wrote:



Hi, Bart: Thank you, your post is working now, maybe, I did something
wrong, unfortunately, you are right, my setup for getting the file to pull
up correctly now is an issue, At first, I got a Vertical line with it
working, then I tried to tinker with it, and it fratched, lol
def border(text):
maxwidth=0
for s in text:
 if len(s)>maxwidth: maxwidth=len(s)
vertinchlines=6# assume 6 lines/inch
hozinchchars=10# assume 10 chars/inch
hozmargin=" "*hozinchchars
newtext=[]
for i in range(vertinchlines):
 newtext.append("")
newtext.append(hozmargin+"*"*(maxwidth+4)+hozmargin)
newtext.append(hozmargin+"* "+" "*maxwidth+" *"+hozmargin)
for s in text:
 newtext.append(hozmargin+"* "+s+" "*(maxwidth-len(s))+" *"+hozmargin)
newtext.append(hozmargin+"* "+" "*maxwidth+" *"+hozmargin)
newtext.append(hozmargin+"*"*(maxwidth+4)+hozmargin)
for i in range(vertinchlines):
 newtext.append("")
return newtext
x=textfile;indat=open(x,'r');SHI=indat.read()
textTuple = border(SHI)
for lines in textTuple:
print ("%s\n" %textTuple)


The issue is trying to get the SHI to work right, but omg, this is the
closes I have gotten, you are awsome, thank you very much, i guess i will
just keep messing with it till i get it


I had to use this code to make this work right from a file (in additon to 
the border() function):


textfile="kkk4" # (don't use this; this was my test input)

x=textfile;indat=open(x,'r');

SHI=indat.readlines()
indat.close()

for i in range(len(SHI)):# remove trailing '\n' from each line
s=SHI[i]
SHI[i]=(s[0:len(s)-1])

textTuple = border(SHI)

for lines in textTuple:
print (lines)

Your indat.read() seemed to read all the lines as one long string. I used
indat.readlines() instead. However each line has a newline char '\n' at the
end. I put in a loop to get rid of that (I'm sure there's a one-line fix to
do that, but as I said don't know Python).

The input file I used had to have this format:

First Name and Last
ENGR 109-X
Fall 2999
Format Example

--
Bartc 


--
http://mail.python.org/mailman/listinfo/python-list


Re: auto increment

2011-03-04 Thread BartC



"Chris Rebert"  wrote in message 
news:mailman.596.1299215244.1189.python-l...@python.org...

On Thu, Mar 3, 2011 at 9:05 PM, Dan Stromberg  wrote:

On Thu, Mar 3, 2011 at 8:48 PM, Chris Rebert  wrote:

On Thu, Mar 3, 2011 at 8:41 PM, monkeys paw  wrote:
> Does python have an analogy to c/perl incrementer?
>
> e.g.
>
> i = 0
> i++

i += 1

If you're doing this for a list index, use enumerate() instead.


There's been discussion of adding i++ to python, but it was felt that the
small number of saved keystrokes didn't justify the resulting bugs.  I
agree.


Out of curiosity, what resulting bugs?


Probably things like i=(++i)+(--i), although more of being indeterminate 
than a bug.


That assumes that ++i was intended for use in an expression, rather than 
just be a statement.


--
Bartc 


--
http://mail.python.org/mailman/listinfo/python-list


Re: having both dynamic and static variables

2011-03-04 Thread BartC


"Steven D'Aprano"  wrote in message 
news:4d6f26a5$0$30003$c3e8da3$54964...@news.astraweb.com...

On Wed, 02 Mar 2011 19:45:16 -0800, Yingjie Lan wrote:


Hi everyone,

Variables in Python are resolved dynamically at runtime, which comes at
a performance cost. However, a lot of times we don't need that feature.
Variables can be determined at compile time, which should boost up
speed.

[...]

This is a very promising approach taken by a number of projects.

Cython and Pyrex are compilers that take Python-like code with static
type declarations and use it to produce compiled C code.


I got the impression the OP was talking about simply pinning down certain 
variables, so that a runtime name lookup (if that's in fact what Python 
does) was not necessary.


Declaring the *type* of such variables is a different matter I think (and 
probably is not considered 'pythonic'; certainly it's a crude, if effective, 
way of getting extra performance).


--
Bartc 


--
http://mail.python.org/mailman/listinfo/python-list


Re: having both dynamic and static variables

2011-03-09 Thread BartC



"Steven D'Aprano"  wrote in message
news:4d743f70$0$29984$c3e8da3$54964...@news.astraweb.com...

On Sun, 06 Mar 2011 12:59:55 -0800, Westley Martínez wrote:


I'm confused. Can someone tell me if we're talking about constant as in
'fixed in memory' or as in 'you can't reassign' or both?


Python already has fixed in memory constants. They are immutable objects
like strings, ints, floats, etc. Once you create a string "spam", you
cannot modify it. This has been true about Python forever.

What Python doesn't have is constant *names*. Once you bind an object to
a name, like this:

s = "spam"

you can't modify the *object*, but you can rebind the name:

s = "Nobody expects the Spanish Inquisition!"

and now your code that expects s to be "spam" will fail. So the only new
feature under discussion is a way to bind-once names, which many people
call constants.


Another example:

pi=3.141592654

print ("pi is:",pi)

pi=42

print ("pi is now:",pi)

which is clearly undesirable.

Many languages just don't 'get' constants; C is one (the closest it comes is
'#define' and 'enum', while what it calls 'const' is really 'read-only
variable'), and perhaps Python is another.

But then, the dividing line between constants and 'variables' can get 
confused when the values involved are complex (strings and such), so might 
be understandable up to a point.



--
bartc 


--
http://mail.python.org/mailman/listinfo/python-list


Re: Python CPU

2011-04-02 Thread BartC



"Brad"  wrote in message 
news:01bd055b-631d-45f0-90a7-229da4a9a...@t19g2000prd.googlegroups.com...

Hi All,

I've heard of Java CPUs. Has anyone implemented a Python CPU in VHDL
or Verilog?


For what purpose, improved performance? In that case, there's still plenty 
of scope for that on conventional CPUs.


The Java VM is fairly low level (I would guess, not being too familiar with 
it), while the Python VM seems much higher level and awkward to implement 
directly in hardware.


I don't think it's impossible, but the benefits probably would not match 
those of improving, say, Cpython on conventional hardware. And if a Python 
CPU couldn't also run non-Python code efficiently, then on a typical 
workload with mixed languages, it could be much slower!


However, wasn't there a Python version that used JVM? Perhaps that might run 
on a Java CPU, and it would be interesting to see how well it works.


--
Bartc 


--
http://mail.python.org/mailman/listinfo/python-list


Re: Fibonacci series recursion error

2011-05-01 Thread BartC

"Steven D'Aprano"  wrote in message
news:4dbbb7b6$0$29991$c3e8da3$54964...@news.astraweb.com...

On Sat, 30 Apr 2011 08:32:55 +0200, Peter Otten wrote:


harrismh777 wrote:


Ian Kelly wrote:

since the fact is that if
the function were properly coded, the call stack for fib(20) would
never be more than 20 entries deep at any one time.



Not so much... and much more !


...  because each recursion level 'return' calls fib() twice, and each
of those calls fib() twice, and you get the point...


I don't understand what you are trying to say -- but it's wrong ;)



I don't know what M Harris thinks he is trying to say either, but the
*naive* Fibonacci recursive algorithm is particularly badly performing
and should be avoided. It's ironic that of the two classic algorithms
used for teaching beginner programmers about recursion, neither is useful
in practice.


Yes, it generates lots of calls.

About 22000 for fib(20), and 330 million for fib(40).

That's why it's popular for benchmarks that measure performance of function
calls. Using an iterative algorithm wouldn't work quite so well...

--
Bartc 


--
http://mail.python.org/mailman/listinfo/python-list


Re: += and =+

2017-09-13 Thread bartc

On 13/09/2017 14:25, Andrej Viktorovich wrote:

Hello,

I have done mistake while trying to increment int

i=1
i=+

this left i unchangeable and I got no error. But what =+ means at all?


Did you mean i=+1 ?

This means i is set to the value +1. Usually just written 1.

Try:

  i=88
  i=+1

and see if i now changes.

--
bartc


--
https://mail.python.org/mailman/listinfo/python-list


Re: Old Man Yells At Cloud

2017-09-17 Thread bartc

On 17/09/2017 02:09, Steve D'Aprano wrote:

On Sun, 17 Sep 2017 04:00 am, Stefan Ram wrote:


Steve D'Aprano  writes:

"Hi, I've been programming in Python for what seems like days now, and here's
all the things that you guys are doing wrong.


   I never ever have written a line of Python 2. I started with
   Python 3.6.0. Yet a very frequent mistake of mine is the
   imission of parentheses after »print«.


That's remarkable.

Do you also forget the parentheses around `len`, and `iter`, and `math.sin()`?
If not, what's so special about print?


It was thought of as a statement or command, not a function where you 
you give it one value and it returns another.


print() is used for its side-effects; what relevant value does it return?

print can also be used for debugging, when it might be written, deleted 
and added again hundreds of times. So writing all those brackets becomes 
irksome. 'print' needs to be easy to write.



Javascript (at least the Rhino interpreter, if not others) includes a print
function. It too requires parentheses:

js> print 21
js: "", line 5: missing ; before statement
js: print 21
js: ...^
js> print(21)


Javascript I believe uses C-like syntax. C syntax is also fond of 
unnecessary punctuation, and its 'printf' requires a format string full 
of format codes. Even more of a nuisance.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Old Man Yells At Cloud

2017-09-17 Thread bartc

On 17/09/2017 15:42, Steve D'Aprano wrote:

On Sun, 17 Sep 2017 11:51 pm, Tim Golden wrote:


Print-as-a-function removed one small simplicity


Presumably you've never wanted to print to something other than std.out.


Actually, no. (stderror is either a Unix-ism or C-ism, or some combination).

 The

syntax in Python 2 is horrid:

print >>sys.stderr, args


But I have wanted to print to a file. I wasn't aware of Py2 syntax for 
it, but that's not so different to what I normally use which is "@" in 
place of "<<". And the @, which used to be #, I think came from '#' in 
Basic or somewhere.


I understand from your example below that in Py3, the file is specified 
somewhere in a list of keyword parameters.


But since the print destination is quite important, it benefits from 
being stated up-front rather than buried somewhere near the end of all 
the main print operands.



Presumably you've never wanted to print using a separator other than space. You
simply can't do it at all in Python 2.

Presumably you've never wanted to print and suppress the newline at the end of
the line.


With the languages I normally use, newline isn't automatically written 
in the first place! (I'd write either print or println.)


However controlling the separator between items has been and still is a 
nuisance (if not using a formatting string, but this is about being able 
to write quick, throwaway prints).


Py3's 'sep' parameter is usable, mainly by requesting no separator and 
adding them manually as required. So if (a,b,c,d,e) have the values 
("(",10,20,30,")") and you wanted output of '(10 20 30)' I guess you 
would write:


 print (a,b," ",c," ",d,e, sep="")

(The scheme I currently use is to always add a space unless suppressed 
with ',,', so the same requirement is written as:


 println a,,b,c,d,,e

But they're /both/ ugly!)


Presumably you've never wanted to pass print to something as a function. It
can't be done in Python 2:

something.register(callback=print)  # SyntaxError


And again, no. It has happened, and this was not in Python, that I 
wanted to print to a string (appending to one), or to the current 
location in a window or image. Then, you need a clear way specifying 
such a destination.



Presumably you've never wanted to control when the output buffer is flushed.
That's another thing you can't do in Python 2.


Once more, no. I suppose it would be necessary to call a separate 
function, which is handier in not cluttering up the main print.



Presumably you've never wanted to monkey-patch an existing function that used
print by shadowing the built-in. You can't do that in Python 2, since print
isn't a regular name, it can't be mocked or shadowed or replaced.


Sorry, no.


I've wanted to do all those things, and more. I love the new print function. For
the cost of one extra character, the closing bracket, it gives you much, much
more than the old print statement ever did.

print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)


OK, in that case why not have both? Of course they would need to be 
given different names to make things easier.


Then there wouldn't be any argument.


No more cryptic and ugly syntax for printing to a file. Setting the argument
separator is easy. Instead of an obscure and easy to miss trick to suppress the
end of line, you use an obvious and self-explanatory keyword argument.


  movedata(a, b, action='copy', depth='shallow')

Self-explanatory keyword arguments, tick; as simple as just writing:

  a = b

probably not!


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Old Man Yells At Cloud

2017-09-18 Thread bartc

On 18/09/2017 04:23, Steve D'Aprano wrote:

On Mon, 18 Sep 2017 11:11 am, Rick Johnson wrote:


Speaking in _keystrokes_, and that's what really matters
here, a print function is always three more keystrokes than
a print statement.


Keystrokes only matter if you are hunt'n'peck typing and need to pause between
holding down the shift key and pressing the 9 key. Otherwise typing ( is little
different than typing 9, its pretty much all the same regardless of what
character you type. For an even half-arsed typist like myself, hitting the
shift and 9 keys happens almost simultaneously. Technically it might involve
two fingers but its effectively a single movement.

If you micro-analyse this, not all keystrokes are equivalent. They use different
fingers, different hands, the movements are different. The fact that some
characters need two simultaneous keypresses is not so important.


I don't hunt&peck but my typing accuracy is very poor.

Shifted keys are harder (in having poorer success outcomes) because two 
keys are involved, the keys are somewhat outside the Qwerty zone so need 
a longer reach, and some synchronisation is needed (the shift must be 
pressed before the '(').


It's not as bad as it sounds but just means that unnecessary shifted 
punctuation is more of a PITA than if it wasn't necessary.


It's a lot worse doing this in C however; compare:

   print a

with:

   printf ("%d\n",a);

8 extra punctuation characters, of which half are shifted (on my 
keyboard). /And/ you have to select a suitable format code. Suddenly, 
having to type:


   print (a)

doesn't seem so bad.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Old Man Yells At Cloud

2017-09-18 Thread bartc

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 doesn't apply in Python, but it is still useful for print to be a 
little special.


--
bartc

--
https://mail.python.org/mailman/listinfo/python-list


Re: Old Man Yells At Cloud

2017-09-19 Thread bartc

On 19/09/2017 11:46, Larry Martell wrote:

On Mon, Sep 18, 2017 at 11:23 PM, Dan Sommers  wrote:

How relevant is the "people use calculators to do arithmetic" argument
today?  Okay, so I'm old and cynical, but I know [young] people who
don't (can't?) calculate a gratuity without an app or a web page.


I use a calculator all the time - not for calculating a tip though.
Sometimes I use bc (when I can't find my calculator in the morass of
my desk).

True story - the other day I was in a store and my total was $10.12. I
pulled out a $20, and the cashier (probably age 23 or so) immediately
entered $20 as the amount tendered. Then I said "Let me see if I have
the $0.12." I did not, but I had $0.15 so I handed her $20.15. She
literally froze in place with a classic deer in the headlights stare.
I said "$10.03" She said "What?" I said "$10.03 is my change." She
said "What?" I said "Just give me $10." She did not reply, opened the
drawer below her register, rummaged around and came out with one of
those giant key calculators, and with a look of dogged determination,
did the calculation, looked at me and said proudly "$10.03 is your
change."


My bill in a store came to £3.20 (GBP3.20), so I handed over £10.20.

I was given back £16.90 in change!

It turned out the cashier had entered £20.10 as the amount tendered. It 
was sorted out in the end.


Sometimes its easier not to be bother making the figures come out better.

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Old Man Yells At Cloud

2017-09-19 Thread bartc

On 19/09/2017 17:30, Steve D'Aprano wrote:

On Tue, 19 Sep 2017 05:56 am, Roel Schroeven wrote:


I do prefer Python 3's print-as-a-function because "special cases aren't
special enough to break the rules", but I feel there's a case to be made
   for Python 2's print-as-a-statement because "(although) practicality
beats purity" sometimes.


Nobody has successfully made the argument that print was *better* as a
statement, or given any convincing reason why print *should* be a statement.

(For example, del needs to be a statement, not a function, because it needs to
operate on *names* not the objects bound to the names.)

All they have managed to successfully argue is that they're used to print
without parens and can't unlearn the habit.

The one advantage of print statement is that you save a single character when
typing it. Be still my beating heart.

Compared to that, the disadvantages:

- it makes print a special thing that can't be treated as a first-class
   value, it can't be passed to functions or used as a callback or bound
   to a name;

- because it is special, beginners have to unlearn the practice of using
   parens for calling functions, and stop writing print(x);

- it suffers a silent failure if you inadvertently parenthesise multiple
   arguments: `print(x, y)` is *not* the same as `print x, y`;

- it has bizarre syntax that nobody would find normal if it wasn't for
   long-experience; I mean, really, you end the argument list with a
   comma to suppress printing newlines? who thought that was a good idea?

- it is difficult to control the print statement, since you can't
   pass keyword arguments; it's one size fits all;

- which is why we ended up with that awful `print >>file, args` hack;

- it can't be mocked, shadowed, monkey-patched or replaced for testing;

- and you can't even write help(print) in the interactive interpreter
   because its a syntax error.


Can't you get around all those with things like sys.stdout.write?

If so, what was the point of having a discrete print statement/function 
at all?


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Old Man Yells At Cloud

2017-09-19 Thread bartc

On 19/09/2017 17:26, Larry Martell wrote:

On Tue, Sep 19, 2017 at 10:30 AM, D'Arcy Cain  wrote:

On 09/19/2017 06:46 AM, Larry Martell wrote:


True story - the other day I was in a store and my total was $10.12. I



One time I was at a cash with three or four items which were taxable. The
cashier rung each one up and hit the total button.  She turned to me and
said something like "$23.42 please."  She was surprised to see that I was
already standing there with $23.42 in my hand.  "How did you do that" she
asked.  She must have thought it was a magic trick.


I was just in a clothing store this weekend and there was a rack of
clothes that was 50%. The sales clerk said everything on that rack was
an additional 25% off, so it's 75% off the original price. I asked is
it 75% off the original price or 25% off the 50% of the price. Said
it's the same thing. I said no it's not. She insisted it was. I said
no, let's take a simple example. If it was $100 and it was 75% off it
would be $25. But if it's 50% off and then 25% off that it will be
$37.50. She looked totally dumbfounded.



Most people (in the general population, doubtless not in this group) 
seem to be confused about things like that.


Your house has gone down in value by 30% this year; it will need to 
increase by 43% to be back where it was last year, not 30%.


Value-Added-Tax in the UK increased from 17.5% to 20%, everyone was 
talking about a 2.5% increase in prices. The increase would actually be 
just over 2.1% (a £100 ex-VAT price increases from £117.50 to £120.00).


Etc.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: [Tutor] beginning to code

2017-09-21 Thread bartc

On 20/09/2017 02:31, Bill wrote:

Rick Johnson wrote:

I think for most languages an intuitive syntax is not
important -- C is such a language, Lisp is such a language,
Perl is such a language, and there are many more -- but
for Python, intuitiveness is very important.

I guess it depends on what you mean by "important" ("important to the 
compiler", is a legitimate concern, for instance). From an intuition 
perspective, C++ allowing you to separate the interface of a class from 
it's implementation, I would say that C++ has it all over Python from 
the point of view of "intuitiveness".   It's much easier to tell what's 
going on, at a glance, in a C++ program.


You're being serious, aren't you?

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: [Tutor] beginning to code

2017-09-22 Thread bartc

On 22/09/2017 10:23, Marko Rauhamaa wrote:

Bill :


I figure that, internally, an address, a pointer, is being passed by
value to implement pass by reference. Why do you say "they are right"
above? Are you saying it's not pass by reference?


"Pass by reference" could be "pass by reference to object" (Python,
Java, JavaScript, Lisp) or "pass by reference to memory slot" (available
to Pascal and C++).

Memory slots (or lvalues, as they are known in C) are not first class
objects in Python, which makes "pass by reference to memory slot" a bit
tricky in Python. Python *could* add memory slots to its sanctioned
collection of object types, and it *could* add special syntax to express
a memory slot reference and dereference ("&" and "*" in C).

However, Python doesn't need any language changes to implement memory
slots. A memory slot could be defined as any object that implements
"get()" and "set(value)" methods:


I didn't understand your examples.

Can Python be used to write, say, a swap() function that works with any 
argument types (not just classes or lists)? Example:


def swap(&a,&b):# made up syntax
a, b = b, a

x=10
y="Z"
swap(x,y)
print (x,y) # "Z" and "10"

If not, then it doesn't have reference passing as it is normally understood.

A simpler example:

def set(&a,value):
   a = value

set(x,100)

Here the type of x is irrelevant anyway. It doesn't even need to be 
initialised to anything first (that might violate something in Python, I 
don't know what).


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: [Tutor] beginning to code

2017-09-22 Thread bartc

On 22/09/2017 12:47, Chris Angelico wrote:

On Fri, Sep 22, 2017 at 9:24 PM, Marko Rauhamaa  wrote:



Yes, following my recipe:

def swap(ref_a, ref_b):
a, b = ref_a.get(), ref_b.get()
ref_a.set(b)
ref_b.set(a)

x = 10
y = "Z"
swap(slot_ref(locals(), "x"), slot_ref(locals(), "y"))
print(x, y) # "Z" and 10


Sure, let me just put that into a function. CPython 3.7, although I'm
pretty sure most CPython versions will do the same, as will several of
the other Pythons.

(Side point: Your slot_ref function is rather bizarre. It's a closure
AND a class, just in case one of them isn't sufficient. The following
code is copied and pasted from two of your posts and is unchanged
other than making try_swapping into a function.)


def slot_ref(dict_or_array, key_or_index):

...class SlotRef:
...def get(self): return dict_or_array[key_or_index]
...def set(self, value): dict_or_array[key_or_index] = value
...return SlotRef()
...

def swap(ref_a, ref_b):

...a, b = ref_a.get(), ref_b.get()
...ref_a.set(b)
...ref_b.set(a)
...

def try_swapping():

...x = 10
...y = "Z"
...swap(slot_ref(locals(), "x"), slot_ref(locals(), "y"))
...print("x, y =", x, y)
...

try_swapping()

x, y = 10 Z

Strange... doesn't seem to work. Are you saying that Python is
pass-by-reference outside of a function and pass-by-value inside?
Because that'd be just insane.

Or maybe what you have here isn't a real reference at all.


It also looks too complicated to be really useful. And I'm not sure it 
would work (when it does work), with more complex terms. For simple given:


 A = [10,20,30]
 B = ["X","Y","Z"]

and wanting to swap A[0] and B[2]. Although these being list elements, 
they /could/ be exchanged via a function:


 def swapelems(a,i,b,j):
 a[i],b[j]=b[j],a[i]

 swapelems(A,0,B,2)

Just not using a general-purpose swap function.

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: [Tutor] beginning to code

2017-09-22 Thread bartc

On 22/09/2017 13:34, Steve D'Aprano wrote:

On Fri, 22 Sep 2017 09:24 pm, Marko Rauhamaa wrote:



Yes, following my recipe:

def swap(ref_a, ref_b):
a, b = ref_a.get(), ref_b.get()
ref_a.set(b)
ref_b.set(a)

x = 10
y = "Z"
swap(slot_ref(locals(), "x"), slot_ref(locals(), "y"))
print(x, y) # "Z" and 10



No, you failed to follow Bart's instructions and answered a different question.



You have to pass x and y, not strings 'x' and 'y'. The swap procedure needs to
accept any variable, given as ordinary bare names swap(x, y), not written as
strings, or by hard-coding x and y as the variables to swap, or by using a
string and passing it to exec, or any other loophole.


And being able to pass any lvalue expression, not just simple variable 
names. Such as a[i] or x.y, provided the term is mutable.


(To make it work would require a new reference type. And extra versions 
of the byte-codes or whatever is used to evaluate terms such as:


a, a[i], x.y

that evaluate a reference rather than the value. So LOADFASTREF as well 
as LOADFAST)


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Call by binding [was Re: [Tutor] beginning to code]

2017-09-24 Thread bartc

On 24/09/2017 15:49, Steve D'Aprano wrote:

On Mon, 25 Sep 2017 12:35 am, Stefan Ram wrote:


   WRT to assertions about Python, I try to base them on the
   "The Python Language Reference, Release 3.6.0" (PRL).

   So, WRT to parameter passing, I would use this part of the PRL:

   »The following constructs bind names: formal parameters
   to functions,« PRL 4.2.1

   . Therefore, what Python does, I'd call »call by binding«.


I am not aware of "call by binding" being a well-known or recognised term. Did
you make it up?

Also, the problem is that *any* form of function call binds *something* to the
function parameters. If we consider the Pascal declaration:

procedure proc(x: integer; var y: integer);


and then we call it:

var
   a, b: integer;
begin
   a := 1;
   b := 2;
   proc(a, b);
end.


then 1 is bound to x and 2 is bound to y. They happen to exist in different
scopes (x is local to proc, the *name* y is local to proc, but the variable is
bound to y is global) but that's not important.

The point I am making is that we could describe just about any and all languages
with functions "call by binding", whether they are call by value like C, call
by reference like Fortran, call by need like Haskell, or call by sharing like
Python.

Then 'binding' is either ill-defined or used wrongly.

Imagine that each name (a,b,x,y) is a little box.

In Pascal, the boxes for a and b contain 1 and 2 respectively. For x and 
y, they contain pointers (dereferenced behind the scenes). Fortran is 
similar (or Fortran IV was; I don't know modern ones). C works the same 
way: every variable has a box, and that box directly contains a value.


In Python, those boxes don't contain anything, except one end of a piece 
of string. The other end is attached to an object.


When you pass a variable to a function like this:

 def fn(X):

 A=1
 fn(A)

Then X gets set up with a string which has the same object at the other 
end as A. (And the object might have a reference count to reflect that 
extra string.)


This is why you can't change A in the caller as there is no way to get 
from X's box to A's box. And the strings to the object are one-way.


In the case of fn(A+2), a new object is created (with value '3', or an 
existing '3' might be used), a new string is attached to it, and the 
other is attached to X.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Beginners and experts (Batchelder blog post)

2017-09-28 Thread bartc

On 28/09/2017 03:33, Stefan Ram wrote:

Larry Hudson  writes:

Hopefully NOT like this person...

Since I teach nights at a local community college



a programmer who couldn't program


   It is not clear what »this person« refers to:

   Do you hope one is not like that teacher who
   publicly is shaming one of his students, though
   without actually giving the name of the student.

   Or do you hope one is not like that student who
   did not turn in the assignments?

   The fact that programmers can't program is
   known since the invention of the "FizzBuzz"
   programmer test. But in the case of the student,
   one actually can't know for sure whether he only
   had problems with the /upgrade/ of his education,
   but still can program in his everyday job.

   So, what was the question? Quoted from earlier in
   the same thread:

|The question is, what should a person "know" when hiring out
|as a programmer? What is 'know" and what should be "known"?
|Specifically with Python.

   Some areas of knowledge follow, a programmer should not be
   ignorant in all of them:


I can probably manage the following, even if I hate some of it or some 
might be advanced:



 - writing FizzBuzz
 - writing GUI software [My own]


(Writing a GUI system or using one? I've done both and try and avoid GUI 
completely if possible.)



 - writing software to analyze text files
 - writing software to generate images from data
 - writing software to analyze images
 - how to program operating systems via system calls
 - algorithms and datastructures
 - numerical mathematics
 - how to write a recursive descent parser
 - maths (how to transform to polar coordinates or
   what the use of a fourier transformation is)


And I have little interest in most of this lot (my eyes glaze over just 
reading some of these):


>  - writing GUI software [Other people's]
>  - writing software to analyze data bases
>  - writing user interfaces for data bases
>  - how to use operating systems
>  - how to administer a computer
>  - how to use the command languages of operating systems
>  - how to use an editor well (e.g., vim or emacs)
>  - how to use UN*X tools (grep, uniq, sed, ...)
>  - regular expressions
>  - a source management tool (like git)
>  - design patterns
>  - design by contract
>  - OOA/OOD
>  - the most important libraries for Python (standard and other)
>  - data base design / normalization
>  - style (e.g. "Clean Code" by Robert Martin, pep 8, ...)
>  - refactors
>  - software engineering
>  - being able to read and write EBNF
>  - software-project managemet (e.g. Agile, "Scrum")
>  - computer science (complexity, NP, grammars, ...)
>  - test (e.g., unit test), TDD
>  - programming interviews (there are many books about this topic!)
>  - Using a real Newsreader (not Google Groups)
>  - common algorithms/heuristics for global optimization
>  - common types of statistical analyses and neural networks

It seems the first group is more pure coding (and fun, a lot of it), and 
the second is the usual lot of tools and technologies that programmers 
seems to have to know about these days (and not so much fun).


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Beginners and experts (Batchelder blog post)

2017-09-28 Thread bartc

On 28/09/2017 12:31, Steve D'Aprano wrote:

On Thu, 28 Sep 2017 09:12 pm, bartc wrote:


And I have little interest in most of this lot (my eyes glaze over just
reading some of these):

  >  - how to use operating systems


You've never used a system call? Written to a file? Moved the mouse?


Wasn't that more this option:

 - how to program operating systems via system calls

Which was in my first group. Using an OS, I just do the minimum 
necessary and don't get involved in much else.


(In my first phase as a programmer, there were personnel whose job it 
was to do that. In the next phase, with microprocessors, there /was/ no 
operating system! Bliss. That phase didn't last long, but fortunately 
those OSes (MSDOS and the like) didn't do much so didn't get in the way 
either.)





  >  - how to use an editor well (e.g., vim or emacs)


You have no interest in using your editor well?


I use my own editor as much as possible. That doesn't have any elaborate 
features that it is necessary to 'learn'.





  >  - style (e.g. "Clean Code" by Robert Martin, pep 8, ...)


Until now, I thought that people who wrote crappy code did so because they
didn't know any better. This is the first time I've seen somebody state
publicly that they have no interest in writing clean code.


I meant I have no interest in reading books about it or someone else's 
opinion. I have my own ideas of what is clean code and what isn't.





  >  - test (e.g., unit test), TDD


You don't test your code?


I assume this meant formal methods of testing.


I suppose that makes it a lot easier to program. Just mash down on the keyboard
with both hands, and say that the code is done and working correctly, and move
on to the next project.

*wink*


Actually I used to like using random methods (Monte Carlo) to solve 
problems. That doesn't scale well however, at some point you have to 
properly think through a solution.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: I'd like to use "semantic indentation"

2017-09-30 Thread bartc

On 30/09/2017 19:12, Stefan Ram wrote:

   I would like to write source code similar to:

country( 'USA' )
   state( 'Alabama' )
 town( 'Abbeville' )
 town( 'Addison' )
   state( 'Arizona' )
 town( 'Apache Junction' )
 town( 'Avondale )
 town( 'Benson' )

   using "semantic indentation".

   It seems I can't do this with Python.

   Is there any workaround?


 def country(x): print("C:",x)
 def state(x): print("S:",x)
 def town(x): print("T:",x)

 def fn(*a): pass

 fn(
   country( 'USA' ),
 state( 'Alabama' ),
   town( 'Abbeville' ),
   town( 'Addison' ),
 state( 'Arizona' ),
   town( 'Apache Junction' ),
   town( 'Avondale' ),
   town( 'Benson' )
   )


This pretends they are arguments to a dummy function. But it probably 
won't work with anything that isn't also an expression.



--
bartc


--
https://mail.python.org/mailman/listinfo/python-list


Re: on a very slow function

2017-10-02 Thread bartc

On 02/10/2017 08:41, Peter Otten wrote:

Daniel Bastos wrote:


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



x.bit_length()

12534884

So at this point it alreay would take 1.5 MB to store the number in binary.
The actual format requires even a bit more memory:


import sys
sys.getsizeof(x)

1671344

So for every operation you have to touch a lot of memory -- and that takes
time.


If it recalculates 'last' once for each of those couple of dozen printed 
lines, that I doubt accessing a few MB of memory is the issue. More 
doing such a big calculation.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: on a very slow function

2017-10-02 Thread bartc

On 02/10/2017 14:54, Peter Otten wrote:

bartc wrote:


On 02/10/2017 08:41, Peter Otten wrote:

Daniel Bastos wrote:


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



x.bit_length()

12534884

So at this point it alreay would take 1.5 MB to store the number in
binary. The actual format requires even a bit more memory:


import sys
sys.getsizeof(x)

1671344

So for every operation you have to touch a lot of memory -- and that
takes time.


If it recalculates 'last' once for each of those couple of dozen printed
lines, that I doubt accessing a few MB of memory is the issue. More
doing such a big calculation.


You are probably right that the calculation requires a significant amount of
the total time here, but it's not just "a few MB". If you look at


  last = last**2 + c


the required memory doubles on every iteration. You will soon run into the
problem even under the (overly optimistic) assumption that the calculation
requires time proportional to memory.


On my machine, the iterations whizzed up the screen until I noticed it 
pausing on the 21st iteration, when the memory size of last was 0.5MB.


When I started last as "A", and multiplied by 2 at each step, it started 
to pause at the 27th iteration when the size of last was 268MB.


I would estimate then another 9 steps of the original (30th iteration) 
before memory usage has the same effect. Although it would probably 
already have ground to a halt long before then.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: newb question about @property

2017-10-03 Thread bartc

On 03/10/2017 15:39, Ian Kelly wrote:

On Tue, Oct 3, 2017 at 4:41 AM, Steve D'Aprano
 wrote:

On Tue, 3 Oct 2017 06:51 am, Bill wrote:


Can you inspire me with a good decorator problem (standard homework
exercise-level will be fine)?



Here is a nice even dozen problems for you. Please ask for clarification if any
are unclear.



(1) Write a decorator which simply prints a descriptive message and the name of
the decorated function once, when the function is first decorated.

E.g. if you write:

@decorate
def spam(x):
 return x + 1  # for example

print(spam(1))
print(spam(2))


Python should print:

Decorating function spam.
2
3


Note: "spam" must not be hard-coded, it must be taken from the function being
decorated. (Hint: all functions have their name available as func.__name__.)


(2) Modify the decorator from (1) so that calling the wrapped function also
print a descriptive message such as "Calling function spam". The expected
output will be:

Decorating function spam.
Calling function spam.
2
Calling function spam.
3


(3) Write a decorator that checks that the decorated function's first argument
is a non-empty string, raising an appropriate exception if it is not, and lets
through any other arguments unchanged.


(4) Same as above, except the first argument is automatically stripped of
leading and trailing whitespace and forced to uppercase.


(5) Write a decorator which injects the argument 10 into the list of arguments
received by the wrapped function. E.g. if you write:

@inject
def add(a, b):
 return a + b

@inject
def sub(a, b):
 return a - b

print(add(5), sub(5))

Python should print "15 5". (And *not* "15 -5".)


(6) [ADVANCED] Modify the decorator in (5) so that it takes an argument telling
it what value to inject into the list of arguments:

@inject(99)
def sub(a, b):
 return a - b

print(sub(5))

will now print "94".


(7) Write a decorator which checks the decorated function's two arguments are
given smallest first, swapping them around if needed.


(8) Write a decorator which prints the name of the wrapped function, its
arguments, and the time, each time the wrapped function is called.


(9) [ADVANCED] Modify the decorator from (8) to take an argument specifying the
path to a file, and use the logging module to log the details to that file
instead of printing them.


(10) Write a decorator which adds an "cache" attribute initialised to an empty
dictionary to the decorated function.


(11) Write a decorator which wraps a class (not function!), and adds a "help"
method to the class which prints a message as shown below. For example:

@addhelp
class Spam:
 pass

@addhelp
class Eggs:
 pass

x = Spam()
x.help()
y = Eggs()
y.help()

will print:

See http://example.com/Spam
See http://example.com/Eggs

(Hint: classes also have a __name__ attribute.)


(12) [ADVANCED] Write a decorator which wraps a class, and applies the decorator
from (10) above to each non-dunder¹ method in the class. That is, after:

@addcaches
class MyClass:
 def foo(self):
 pass
 def bar(self):
 pass

print(MyClass.foo.cache, MyClass.bar.cache)

should print "{} {}".



¹ Remember that dunder methods are those that start with two leading and
trailing underscores: "Double UNDERscore" methods.


[Sorry can't see Steve's original post.]

Does all this advanced stuff (which I don't understand and which doesn't 
look very appealing either; hopefully I will never come across such 
code) still count as programming?


It seems to me the equivalent of an advanced driving course teaching you 
how to customise your car rather than involving any actual driving.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: newb question about @property

2017-10-04 Thread bartc

On 04/10/2017 06:32, Steve D'Aprano wrote:

On Wed, 4 Oct 2017 02:00 am, bartc wrote:


Does all this advanced stuff (which I don't understand and which doesn't
look very appealing either; hopefully I will never come across such
code) still count as programming?


I could not have hoped to see a more perfect example of the Blub effect in
action if I had invented it myself.


 As long as our hypothetical Blub programmer is looking
 down the power continuum, he knows he's looking down.
 Languages less powerful than Blub are obviously less
 powerful, because they're missing some feature he's used
 to. But when our hypothetical Blub programmer looks in
 the other direction, up the power continuum, he doesn't
 realize he's looking up. What he sees are merely weird
 languages. He probably considers them about equivalent
 in power to Blub, but with all this other hairy stuff
 thrown in as well. Blub is good enough for him, because
 he thinks in Blub.


http://www.paulgraham.com/avg.html


I've seen that example brought up before. It still doesn't cut any ice.

You might as well be condescending of someone who finds Joyce or Proust 
unreadable, and prefers McBain, Simenon or Chandler. (Sorry, can't think 
of any modern pulp novelists).


It is just being elitist. I have a preference for keeping things simple 
and avoiding unnecessary complexity. But with programming languages many 
do have a penchant for the latter.


As an example, a recent discussion on comp.lang.c was about implementing 
named constants. I proposed one very simple way of doing it, other 
people were talking about using #define, enum, const, static const, or 
importing constexpr and special rules for 'const' from C++. All 
unsatisfactory and each having their own problems.


For that matter, I don't think Python has such a feature either. So that 
you write for example:


  const C = 123345

and then whenever C appears within the code, it's implemented as:

  LOAD_CONST (123345)

I'm pretty sure that there are very complicated ways of achieving 
something similar, maybe with all your decorators, or using PyMacro or 
whatever. But not doing it straightforwardly. [Python's design makes a 
simple implementation harder.]


Anyway, what I'm saying is that languages sometimes neglect the basics 
in favour of all this other stuff.



You don't think that adding a cache for an expensive function is programming?

If you had ten expensive functions, and you wanted to add a cache to each of
them, would you write out ten separate caches (probably copying and pasting
the code each time)?

Or would you write a function that builds a cache and adds it to the expensive
function *once*, then call it ten times, once for each function being
wrapped?


I'm trying to think of a real example where I've had to add a cache to 
to a function, whatever that even means (memoisation?).


Is it looking to see if a certain combination of parameters has been 
used before and retrieving the return value that resulted on that 
occasion without having to redo the calculation? In my sort of coding 
that would need be done on a per-function basis because there would be 
other considerations.


It does still sound like adding a turbo-charger to your engine, rather 
than actually going anywhere. That at least might be useful, but it's 
still not driving.


But if the ultimate purpose is more speed, then piling on yet more code 
and more layers may be counter-productive!



That you think that this is not programming is an indictment off your
programming skills. These sorts of functional programming techniques go back
to the 1950s, Lisp is literally the second oldest high-level language ever
(only Fortran is older). You may or may not have been a hotshot in your
little corner of the programming world, but there's an entire world out
there.


What other languages apart from Python have equivalent features to 
decorators and, what's the other one, descriptors? Apart from Lisp.




--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-04 Thread bartc

On 04/10/2017 11:42, Stefan Ram wrote:

Robin Becker  writes:

Given the prevalence of the loop and a half idea in python I wonder why we don't
have a "do" or "loop" statement to start loops without a test.


   VBA has quite an orthogonal way to build loop control:

   pre-checked positive:

Do While ...
 ...
Loop

   post-checked positive:

Do
 ...
Loop While ...

   pre-checked negative:

Do Until ...
 ...
Loop

   post-checked negative

Do
 ...
Loop Until ...

   "endless":

Do
 ...
Loop


None of them appear to be loop-and-a-halves.

(Note that your reverse-indentation style is confusing! Imagine that 
Python was written like this:


for i in R:
print (i)
)

Anyway I think what is needed in Python for a proper loop-and-a-half is 
this:


  while:
 s1
 s2
 do cond:
   s3
   s4

s1, s2, s3, s4 are executed in sequence while cond is true. When cond is 
false, only s1, s2 are executed in that iteration, and the loop 
terminates. (A few syntactical details to be worked out such as whether 
while, do and else line up or not.)


This is equivalent I think to the current:

  while 1:
 s1
 s2
 if cond:
   s3
   s4
 else:
   break

But this would be a less satisfactory, ad-hoc approach. For example, 
there can be several such if-blocks within the same loop. They could be 
nested. There might not be any, so can't at a glance distinguish an 
endless loop from a loop-and-a-half.


My proposed while-do has a less chaotic structure. It wouldn't preclude 
'break' from still being used, but there would be less need.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-04 Thread bartc

On 04/10/2017 11:57, Rhodri James wrote:

On 04/10/17 10:01, Robin Becker wrote:
Given the prevalence of the loop and a half idea in python I wonder 
why we don't have a "do" or "loop" statement to start loops without a 
test.


See PEP 315.  Guido's rejection note is here:
https://mail.python.org/pipermail/python-ideas/2013-June/021610.html


Oh, OK, similar to what I proposed earlier. That it was rejected is not 
a surprise. Programming languages seem to hate special forms for basic 
constructs such as looping, even though they can express more directly 
exactly what the coder intended.


But this is what it says about it:

"Please reject the PEP. More variations along these lines won't make the
language more elegant or easier to learn. They'd just save a few hasty
folks some typing while making others who have to read/maintain their 
code wonder what it means."


Exactly the same could be said of pretty much any of the advanced 
features that /have/ been added.



--
bartc

--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-04 Thread bartc

On 04/10/2017 14:02, Robin Becker wrote:

On 04/10/2017 11:57, Rhodri James wrote:

On 04/10/17 10:01, Robin Becker wrote:
Given the prevalence of the loop and a half idea in python I wonder 
why we don't have a "do" or "loop" statement to start loops without a 
test.


See PEP 315.  Guido's rejection note is here:
https://mail.python.org/pipermail/python-ideas/2013-June/021610.html

seems fair enough; I suppose the cost is negligible or perhaps there's 
peephole optimization for this common case.


Read the thread. Not having a dedicated feature means I counted at least 
half a dozen different ideas for implementing what the OP really wanted 
to do, which was expressed using C-like syntax. None of which were as 
obvious.


And that C-like one worked because it could use an assignment within a 
while-condition.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: newb question about @property

2017-10-04 Thread bartc

On 04/10/2017 14:41, Ian Kelly wrote:

On Wed, Oct 4, 2017 at 5:07 AM, bartc  wrote:



For that matter, I don't think Python has such a feature either. So that you
write for example:

   const C = 123345

and then whenever C appears within the code, it's implemented as:

   LOAD_CONST (123345)



Python has the simplest named constants of all:

C = 12345

As long as you don't subsequently change it, it's a constant. And it's
very simple because it works just like any other variable.


Yes, but you don't want it to work like other variables!

In other languages, a known compile-time constant is essential in 
certain contexts, but even in Python there are advantages to such a 
feature, for example in more opportunities for optimisation.


Even if it's just so it can use LOAD_CONST instead of LOAD_GLOBAL (as 
such constants often are global).


The problems with doing this in current CPython are first, that all such 
identifiers are dynamic: you can assign anything to them at any time. 
Also that some may be inside imported files, which the byte-code 
compiler will not know about until its too late.


(There are ways around those but it would be an impossible sell when 
most people are not convinced that lightweight named constants are useful.)



I'm trying to think of a real example where I've had to add a cache to to a
function, whatever that even means (memoisation?).


You've never used a dynamic programming algorithm?


I had to look up what it means, but I still didn't see any practical 
examples.


Probably I've done such coding, but I didn't give it a fancy name, and 
more likely just considered it data caching.



> Descriptors are a bit unique to Python, I'll grant, but mostly they're
> just used in the form of properties. Here's a list of languages that
> support properties:
> https://en.wikipedia.org/wiki/Property_(programming)#Example_syntax

"A property, in some object-oriented programming languages, is a special 
sort of class member, intermediate in functionality between a field (or 
data member) and a method."


But Python has some problems just in using fields. If you wanted say a 
data type with two fields called x and y, then AFAIK you just create any 
suitable class, but you don't need to specifically declare those two fields:


 class any():
 pass

 p=any()
 p.x=10
 p.y=20

But you also do this:

 p.z=30

and it magically acquires a third field! Or you want to modify p.x, but 
accidentally type:


 p.c=40

No error. Some would perceive all this as an advantage, but it means you 
can't just declare a lightweight struct or record 'Point' with exactly 
two fields x and y. You have to use other solutions ('namedtuples' or 
whatever, which probably are immutable so that don't work the same way).


This is another example of neglecting the basics, but going for more 
advanced, perhaps more sexy features instead.


Result? You can't just look at my 'any' class and see what fields it 
uses. You can't even just look at the static source code. You have to 
run the program to find out. And it might be different each time.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-04 Thread bartc

On 04/10/2017 14:44, john polo wrote:

In Python Programming Fundamentals 2nd ed., the author, Kent D. Lee, 
brings up loop and a half in ch. 3, Repetitive Tasks (p. 82). He wrote:


"Whether you are writing code in Python or some other language, this 
Reading
Records From a File pattern comes up over and over again. It is 
sometimes called
the loop and a half problem. The idea is that you must attempt to read a 
line from the
file before you know whether you are at the end of file or not. This can 
also be done
if a boolean variable is introduced to help with the while loop. This 
boolean variable
is the condition that gets you out of the while loop and the first time 
through it must

be set to get your code to execute the while loop at least one."


while not eof(f):
   # read next bit of the file

But you need an eof(f) function that tells you if you are at the end of 
the file. Some people might be concerned that the status could change 
between checking for eof, and doing a subsequent read (but I've never 
had such problems).


This is suitable for reading perhaps binary files in uneven chunks, 
which are dependent on the last bit read, so iterating over the file by 
line or by byte won't work.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: newb question about @property

2017-10-04 Thread bartc

On 04/10/2017 17:02, Rhodri James wrote:

On 04/10/17 16:33, Paul Moore wrote:



It's not an advantage or a disadvantage, just an approach. Many people
like it, you may not. Specifically, yes you can't "just declare a
lightweight struct or record with exactly two fields".


Actually you can:

 >>> class Point:
...   __slots__ = ("x", "y")
...   def __init__(self, x, y):
... self.x = x
... self.y = y
...   def __str__(self):
... return "({0},{1})".format(self.x, self.y)
...
 >>> p = Point(3,4)
 >>> print(p)
(3,4)
 >>> print(p.x)
3
 >>> p.x = 7
 >>> print(p)
(7,4)
 >>> p.z = 2
Traceback (most recent call last):
   File "", line 1, in 
AttributeError: 'Point' object has no attribute 'z'

I pretty much never bother to do this because (bart to the contrary)


But it's something you'd have to explicitly do (unless perhaps you make 
use of those decorators, which AFAICS can do magic).


And when I tried, it didn't really work in Python 2 (extra attributes 
could still be created, and .__slots__ wasn't readonly); only Py3.


it 
isn't useful if you're thinking in Pythonic terms,


I clearly don't. When I do this in my non-Python language it would be just:

  record any = (var x,y)

  p := any(10,20)
  println p  # (10,20)
  println p.y, p.x   # 20 10
  println p.len  # 2
  println p[2]   # 20
  println p = any(10,20) # 1 (compares fields)

No __slots__, __init__ or __str__ need to be defined; it just works.

If I needed a version suitable for foreign function interfacing, a 
little different:


  type point = struct (real64 x,y)

  p := point(10,20)
  println p  # (10.,20.)
  println p.bytes# 16

It's not Pythonic, but it is pretty handy

(I know Python can also do structs like this but it appeared to be quite 
a slog last time I looked.)


I guess my kind of coding is somewhat less esoteric than the kind of 
thing I typically see in Python here.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-05 Thread bartc

On 05/10/2017 07:57, Gregory Ewing wrote:

Steve D'Aprano wrote:

I recall that the Pascal compiler had to do some clever behind the scenes
jiggery-pokery to get eof() to work, but that's what compilers are 
supposed

to do: make common tasks easy for the programmer.


Sometimes the jiggery-pokery worked, sometimes it didn't.
For example, the following wouldn't work as expected:

    while not eof(input) do begin
   write(output, 'Enter something:');
   readln(input, buffer);
   process(buffer);
    end

because the eof() would block waiting for you to enter
something, so the prompt wouldn't get printed at the
right time.

Basically, Pascal's eof-flag model was designed for
batch processing, and didn't work very well for
interactive use.


This doesn't make sense. For interactive use, you wouldn't bother 
testing for eof, as you'd be testing the eof status of the keyboard.


You might want a way of the user indicating end-of-data, but that's 
different; you don't want to abruptly send an EOF (via Ctrl-C, D, Z, 
Break or whatever). That would be a crass way of doing it. Besides you 
might want to continue interacting with the next part of the program.


So the loop would be like this (Python 3; don't know why it doesn't work 
in Python 2):


while 1:
buffer = input("Enter something (Type quit to finish): ")
if buffer == "quit": break
print ("You typed:", buffer) # process(buffer)

print ("Bye")

This is a loop-and-a-half.

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-05 Thread bartc

On 05/10/2017 12:09, Chris Angelico wrote:

On Thu, Oct 5, 2017 at 9:56 PM, bartc  wrote:

This doesn't make sense. For interactive use, you wouldn't bother testing
for eof, as you'd be testing the eof status of the keyboard.


You mean the way heaps and heaps of Unix programs work, processing
until EOF of stdin? Yeah, totally makes no sense, man, no sense at
all.


Out of the hundreds, perhaps thousands of such input loops I must have 
written, how many needed to test EOF? Hmm, somewhere around zero I think.


Oh hang on, I wasn't using Unix; does that make a difference?

If you're referring to the ability to redirect stdin so that input can 
come from a file as well as from a live keyboard, then you're doing file 
handling; it's NOT interactive.


(And I've used such programs where you get no prompt as to what to type, 
or how to finish, and you just blindly press Ctrl C, Ctrl D, Ctrl Z or 
Ctrl Break in turn until it stops. Really friendly. Because the program 
reads from stdin but assumes it comes a from a file or pipe anyway.)


Note that Unix way isn't the ONLY way of doing things.

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: newb question about @property

2017-10-05 Thread bartc

On 05/10/2017 12:29, Gregory Ewing wrote:

bartc wrote:
Result? You can't just look at my 'any' class and see what fields it 
uses. You can't even just look at the static source code. You have to 
run the program to find out. And it might be different each time.


You can usually get a pretty good idea of what attributes a
class has by looking at its definition. The vast majority of
classes will either initialise their attributes in the __init__
method or provide defaults as class variables.

While in theory it's possible for code to add attributes
later after initialisation, in practice this is hardly ever
done.


Yeah, but, like many other things in this language, there are million 
ways of doing it.


Just had a quick look, the first hit was talking about using a module 
'pyrecord'.


Another mentioned 'namedtuples'.

Another used the '__slots__' method already mentioned (remembering the 
difference between old and new classes in Python 2...)


One more uses a module 'recordtype'.

And then there is just using a normal class, where you have to look 
closely at the code to see what it's implementing. It allow ad-hoc 
fields to be created, or it may define __init__ etc.


And all with different capabilities regarding adding extra fields, 
having mutable records, initialising a record, comparing them, printing 
them, ....


Am I allowed to say that it all seems a bit of a mess?


--
bartc

--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-05 Thread bartc

On 05/10/2017 18:01, Chris Angelico wrote:

On Thu, Oct 5, 2017 at 10:26 PM, bartc  wrote:

On 05/10/2017 12:09, Chris Angelico wrote:


On Thu, Oct 5, 2017 at 9:56 PM, bartc  wrote:


This doesn't make sense. For interactive use, you wouldn't bother testing
for eof, as you'd be testing the eof status of the keyboard.



You mean the way heaps and heaps of Unix programs work, processing
until EOF of stdin? Yeah, totally makes no sense, man, no sense at
all.



Out of the hundreds, perhaps thousands of such input loops I must have
written, how many needed to test EOF? Hmm, somewhere around zero I think.

Oh hang on, I wasn't using Unix; does that make a difference?

If you're referring to the ability to redirect stdin so that input can come
from a file as well as from a live keyboard, then you're doing file
handling; it's NOT interactive.


How would you write a sort program? How would you tell it that you're
done entering data?


How do you do it with any kind of iterative program?

It can be done with an in-band end-of-data code, although it might take 
some effort especially if you also want that to be invoked by pressing 
Ctrl-D. Then you can continue using a simple loop, and ignore dealing 
with 'EOF' on a keyboard.



And yes, I have used sort(1) interactively, with no redirection whatsoever.


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.)



--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: why does memory consumption keep growing?

2017-10-05 Thread bartc

On 05/10/2017 22:06, Fetchinson . wrote:

Hi folks,

I have a rather simple program which cycles through a bunch of files,
does some operation on them, and then quits. There are 500 files
involved and each operation takes about 5-10 MB of memory. As you'll
see I tried to make every attempt at removing everything at the end of
each cycle so that memory consumption doesn't grow as the for loop
progresses, but it still does.

import os

for f in os.listdir( '.' ):

 x = [ ]

 for ( i, line ) in enumerate( open( f ) ):

 import mystuff
 x.append( mystuff.expensive_stuff( line ) )


What if you change this line to:

   mystuff.expensive_stuff( line )

If it's still growing (perhaps a bit less as it's not added to x), then 
something in mystuff is remembering data about each line. You might try 
removing the line completely too (temporarily of course).


Other replies suggest that deleting the import [name] doesn't affect any 
data it contains. So might as well move it to the top where it belongs.




 del mystuff

 import mystuff
 mystuff.some_more_expensive_stuff( x )


You'll have to comment these lines out first I think.

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-05 Thread bartc

On 05/10/2017 23:42, Gregory Ewing wrote:

bartc wrote:

It can be done with an in-band end-of-data code,


Then you need some way of escaping that in-band code, in case
it happens to equal some of the data you want to sort.


It needn't be a big deal. You can do this (you have to in Python as the 
normal 255 character signifying eof on a character stream is trapped):


 EOD=chr(26)  # can be anything that is an unlikely input line.

 def myinput(prompt):
 try:
 return input(prompt)
 except EOFError:
 return EOD

Then you can keep using a simple type of loop without worrying about EOF 
status:


 print ("Type Ctrl-Z on its own line to finish.") # Windows

 while 1:

 buffer=myinput("Enter something: ")
 if buffer==EOD: break
 print ("You typed:",buffer) # process(buffer)

 print ("Bye")

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.)


How to signal EOF from the keyboard is a fundamental piece
of knowledge about the OS. It's not the responsibility of
individual programs to teach it to you, any more than it's
your car's responsibility to explain what the steering wheel
does each time you start the engine.


If you have a utility that is designed to also be used interactively, 
but it shows absolutely nothing when you start it, like this:


 >sort





then it stinks. You wouldn't think much of a shell prompt that literally 
showed nothing at all instead of something like:


 c:\python39>

How would you even know what program you were in the middle of after the 
initial command has scrolled off the screen? How would you now it was 
still running? As typing a line into it give no response.


I don't run these things often enough to remember exactly how to specify 
an EOF with the keyboard. It might be:


- One of Ctrl C, D, Z or Break

- It may or not may not only work at the start of a line

- It may or not require to be followed by Enter

I anyway would never inflict such an interface on my users, who would 
also associate Ctrl C etc with aborting a program that's gone wrong.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: why does memory consumption keep growing?

2017-10-05 Thread bartc

On 06/10/2017 00:38, Stefan Ram wrote:

"Fetchinson ."  writes:

I have a rather simple program which cycles through a bunch of files,
does some operation on them, and then quits. There are 500 files
involved and each operation takes about 5-10 MB of memory. As you'll
see I tried to make every attempt at removing everything at the end of
each cycle so that memory consumption doesn't grow as the for loop
progresses, but it still does.


   "2x 8GB DIMM DDR3-1600" cost $95.99 according to a web page.
   This might be in the order of magnitude of the hourly rate
   of a freelancing programmer.


Brilliant. We can forget about freeing memory or garbage collection, 
just keep adding a 16GB bank of memory every few hours. It's cheaper 
that paying a programmer to write memory-efficient code or fixing the 
memory leak!


(That's assuming such a program will only run on the programmer's 
machine and not a million consumer machines who would also need to fork 
out for extra memory. Their salaries may not stretch as far.)


--
bartc


--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-06 Thread bartc

On 06/10/2017 02:07, Steve D'Aprano wrote:

On Fri, 6 Oct 2017 09:57 am, Marko Rauhamaa wrote:



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.


That's what it looks like. Is it doing something, or waiting for me to 
do something, or did it just hang?



The Unix commandline interface is not designed to be user-friendly for newbies
(or experts, for that matter). It is terse, often *painfully* so (would it
have killed the author to have spelled `umount` correctly?), the UI is
inconsistent, and it has a very steep learning curve -- a lot of effort is
required to make a little bit of progress.


OK. I'm not out to change Unix (not right now). But this style of 
utility was suggested as a way to write interactive input loops in 
Python programs, which you might expect to be friendlier.


That it is, to assume from the outset that you're reading from a file, 
not a keyboard. And the user typing in data also has to pretend they are 
entering data in a file, complete with an EOF marker.


That is what I object to.

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.



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, much as `ls` defaults to
outputting control characters but automatically swaps to replacing them
with ? when writing to a terminal.


Surely this is a common problem that has long since been solved? You 
have a interactive program - even with proper prompts and feedback - and 
one day you want to run it as a script.


(And properly, by being given the same of an actual file rather than 
using crude redirection.)


But you don't want hundreds of dialogue lines scrolling up the screen 
while it's doing so.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-06 Thread bartc

On 06/10/2017 12:04, Rhodri James wrote:

On 05/10/17 19:45, bartc wrote:
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.)


Actually it might.  Linux tools are written not to assume that stdin and 
stdout are the console, because they frequently aren't.  Extra puff 
written to stdout at best makes it harder to use in a pipeline, and at 
worst makes it useless; tools that do that tend not to get used.


A lot of people aren't getting it.

The internal utilities used within an operating system, primarily 
intended for file or redirected i/o with no live interaction, should be 
distinct from those designed to be used directly with a live user.


Or is it against the rules of Unix to have two different versions of a 
program?


Then you might have 'sort' for the non-interactive version, and 'isort' 
or whatever for the interactive.


Except you simply wouldn't use an interactive version of any program 
that reads an arbitrary long list of uninterrupted data, no matter how 
the ending is indicated. You'd use a text editor, enter the lines at 
your leisure, go back and forth to check and edit as needed, THEN you 
would submit that file to 'sort'. As an actual input file.


So I can't see the point of using that same pattern of input usage 
(reading from stream, file, pipe whatever until interrupted with an EOF 
signal) for a true interactive program that is used in a sensible manner.


(Say, an FTP program, which has a prompt, lots of commands, and usually 
instant feedback. An actual dialogue.


A program like 'python' might fit the bill too. Here, you can give it 
the name of a file, OR say nothing, and it will take input from stdin.


Funnily enough, you now get a message, and a prompt. And when entering 
multiple lines of code, you get a prompt before each line. You can also 
terminate the sequence by entering a blank line.


So it IS possible to do it properly after all!)

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-06 Thread bartc

On 06/10/2017 12:51, Chris Angelico wrote:

On Fri, Oct 6, 2017 at 10:41 PM, bartc  wrote:


> What you REALLY mean is that you can't see the point of an interactive
> sort command. It doesn't fit into your workflow. And that's fine. It's
> not something you'd use very often. There are other programs, however,
> that behave exactly the same whether used in batch mode or interactive
> mode, and where you would do exactly the same thing as I described -
> provide input, and hit Ctrl-D to mark that you're done.

Examples?

And is there any reason why you wouldn't use a text editor to capture 
your input first? I can see myself noticing an error I'd made 10 lines 
up, which is now too late to change, and I've still got 100 lines to go. 
What to do?


I just can't anyone wanting to use programs that work in the way you 
suggest. Not outside of a student exercise (read N numbers and display 
the average), where getting the input correct isn't so important.


> And since
> every one of these programs is written to read from stdin until EOF,
> you can use them all in exactly the same way - type at keyboard, hit
> Ctrl-D when done.

So they're all at it! That doesn't mean it's a good way of doing things.



So it IS possible to do it properly after all!)


Actually, Python's interactive mode is completely different from its
file input mode. You're not really comparing like things here.
Python's incremental interpreter is *by nature* interactive, and
redirecting its input does not produce the same result as running
"python3 filename.py" would. Can you find yourself a better example?


I gave the FTP example. (Which actually, in my version, doesn't work 
properly when trying redirect input into it. You have to give an actual 
file name.)


But what's wrong with the Python example? It detects when it's given a 
file (as as actual parameter, or redirected), and when it's used 
interactively, and adapts its behaviour accordingly.


It just needs a bit of effort.

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-06 Thread bartc

On 06/10/2017 12:45, Chris Angelico wrote:

On Fri, Oct 6, 2017 at 9:32 PM, bartc  wrote:

(And properly, by being given the same of an actual file rather than using
crude redirection.)


Why do you call redirection "crude"? Do you not understand the value
of generic solutions that work with all programs, rather than having
every program implement its own "take input from file" parameter?

You can disagree with the Unix philosophy all you like, but when you
insult it, you just make yourself look like an idiot.


Redirection is used on Windows too. I use output redirection quite 
frequently (to capture the output of 'dir' for example).


I don't rely on > and < in my own programs. Where there's complex, mixed 
output, the bulk of it - the data - needs to go to a proper file, while 
the screen shows messages.


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.)


Another compiler might simply write the output to a file 'program.i'.

BTW if I try:

 > gcc https://mail.python.org/mailman/listinfo/python-list


Re: newb question about @property

2017-10-06 Thread bartc

On 05/10/2017 14:13, Steve D'Aprano wrote:

On Thu, 5 Oct 2017 10:51 pm, bartc wrote:


Am I allowed to say that it all seems a bit of a mess?



You may or may not be pleased to learn that there's a push to create a "record
like" or "struct like" datatype for Python 3.7 or 3.8, tentatively called
a "Data Class" for now.



https://www.python.org/dev/peps/pep-0557/


Yeah, maybe (looks a bit over-ambitious to me; why is it necessary to 
have typed fields? Or to do relative compares?)


But it reminds me a bit of the xkcd cartoon about the 14 competing 
standards becoming 15...


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-06 Thread bartc

On 06/10/2017 14:11, Peter J. Holzer wrote:

On 2017-10-06 12:38, bartc  wrote:

On 06/10/2017 12:51, Chris Angelico wrote:

What you REALLY mean is that you can't see the point of an interactive
sort command. It doesn't fit into your workflow. And that's fine. It's
not something you'd use very often. There are other programs, however,
that behave exactly the same whether used in batch mode or interactive
mode, and where you would do exactly the same thing as I described -
provide input, and hit Ctrl-D to mark that you're done.


Examples?

And is there any reason why you wouldn't use a text editor to capture
your input first? I can see myself noticing an error I'd made 10 lines
up, which is now too late to change, and I've still got 100 lines to go.
What to do?

I just can't anyone wanting to use programs that work in the way you
suggest. Not outside of a student exercise (read N numbers and display
the average), where getting the input correct isn't so important.


I regularly use at least cat, wc and od this way (plus a few of my own
utilities like utf8dump). I'm sure I've used sort this way, too, though
rather rarely. I usually don't type the input but paste it in,


Exactly. Probably no one ever uses these programs with actual live input 
with the possibility of uncorrectable errors getting through.


So not a good reason to use that coding pattern to write programs which 
ARE designed for live, interactive input:


print ("Enter blank expression to quit.")

while 1:

buffer=input("Expr: ")
if buffer == "": break
try:
print (eval(buffer))
except:
print ("Error")

print ("Done")

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-06 Thread bartc

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.)


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).


If I use -fdump-tree-all, that also goes to a file (various).



Writing to stdout is very often a good design. Not always, but nothing
is ever 100% black and white, but sufficiently often that building an
OS based on the idea (Unix) was pretty successful :-)


The first computer I used was via a teletype printing on paper. If every 
operation producing an arbitrarily open-ended amount of output defaulted 
to the terminal, then it would have been totally impractical (in time 
taken and the amount of paper used).


Even with today's consoles, 80,000 lines whizzing up the screen (when 
program.c contains '#include '), while not taking quite that 
long, still seems crazy to have as the default operating mode.


But you will say, Ah but you will never see it because it will nearly 
always be piped into another program.


And that reinforces the point I keep making: many of these are internal 
utilities never intended to be used as properly interactive commands.


Fine, but why keep bringing them up as models of how to write true 
interactive programs?



--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-06 Thread bartc

On 06/10/2017 15:55, Chris Angelico wrote:

On Fri, Oct 6, 2017 at 11:38 PM, bartc  wrote:



Have you ever worked on a slow remote session where a GUI is
completely impracticable (or maybe even unavailable), and redrawing
the screen is too expensive to do all the time? You absolutely have to
work with line-by-line content.


Not since about 1977, using 110 baud teletypes and VDUs, on a mainframe 
not geared to interactive use so it was unresponsive anyway.


By 1981 however I was using a memory-mapped text display (of my 
home-made computer) which even with its 8-bit processor could update the 
screen at 200,000 characters per second. In other words, instantly.


So what's the excuse for an unresponsive text display in 2017?


What text editor do you use there?


That depends; are we still in the 1970s?


That's why we have the stderr stream as well as stdout. You can
redirect stdout and still have messages go to the screen (via stderr);
or you can redirect stderr as well, sending those messages to a
logging facility. How do you do THAT with your program?


I said the output was complex. Then there might be more than one output 
file, and one or more of the outputs need to be in an actual file.


Just blithely sending /everything/ to stdout, even mixed up with stderr, 
might be something I'd do for a quick throwaway program, not a major 
application.


(And since I mainly use my own languages, actually getting hold of 
'stdin', 'stdout' and 'stderr' is not trivial. Creating actual named 
files is much easier.)




Also: can you use your program to write to a file on a different
computer? I can pipe a program's output into SSH. You can make a crude
intercom system like this:


No. I've got no idea about formal networking. (Actually, I walked out of 
the computer networks exam in my CS course, as I realised I knew nothing.)


But as it happens, I could make computers talk to each when I was 
working with microprocessors, using home-made interfaces, rs232 or 
rs423. I wouldn't know how to do it now because it depends on other 
people's over-complex tech.



I'm not sure what you mean by a working pipe system. Yes, the one
cmd.exe gives you is not nearly as flexible as what bash gives you,
but for the purposes of the examples given so far,


I just don't work that way. The OS is there to launch applications, or 
to provide a basic API for common services such as a file system. I 
don't need its complicated shells.



BTW if I try:

  > gcc 

"It doesn't work" is a terrible way to report this. What's the
problem? Is it possibly what's described fairly clearly in the error
message?


It says 'no input files'. Presumably it's one of those programs that 
only takes input instructions from the command line, and does not look 
at stdin.


In which case you wouldn't be able to pipe source code into it. You 
might actually have to tell it the name of a discrete file you want to 
compile.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-06 Thread bartc

On 06/10/2017 18:42, Chris Angelico wrote:

On Sat, Oct 7, 2017 at 4:13 AM, bartc  wrote:



So what's the excuse for an unresponsive text display in 2017?


Got it. You assume that a system is a coherent computer with its
peripherals, rather than being a networked collection of computers,
all of them controlled from your laptop in response to a panicked
email saying the web site is down. Your terminal exists on your
laptop. The programs are being run on any of a number of your servers,
possibly several of them concurrently. How do you handle that?


What text editor do you use there?


That depends; are we still in the 1970s?


Nope. We're in 2017, where the "system" is often a networked
collection of computers.


Still no excuse. We were talking about the need to use a crude keyboard 
interface to serially create a file of data a line at a time rather than 
using a proper application for it (such as a text editor).


So which bit do you have access to locally? The keyboard presumably. And 
the display has to be local unless you it's either got a 50' screen or 
you use binoculars. Are you saying the bit in the middle is remote and 
that is what is playing up?


This is exactly the situation from the 1970s that I thought we'd long 
left behind! There really is no excuse for not having the minimum amount 
of local processing power available to be able to enter and review a few 
dozen lines of text without needing to involve a temperamental network.


If you're stuck, whip out a tablet computer or smartphone (they should 
still function without connectivity) and use a preloaded text editor. Or 
just compose and then save an email. Even the simplest should be more 
sophisticated than just blindly entering text on a Linux terminal screen.



(And since I mainly use my own languages, actually getting hold of 'stdin',
'stdout' and 'stderr' is not trivial. Creating actual named files is much
easier.)


More blub happening right there. You start out by assuming that the
standard streams are unimportant, therefore you think that providing
them is pointless. It's self-perpetuating.


They were a creation of either C, Unix, or some combination. Certainly I 
had very little to with any of that for decades. I can't remember that 
it ever stopped me doing anything I needed to do.


My own programs worked like this (showing original '#' symbol I used);

 print "One"   # to console (also using print #0)
 print #f, "Two"   # to file handle f
 print #s, "Three" # append to string s
 print #w, "Four"  # to window or control w
 print #b, "Five"  # to image b

What would I want with stderr?!


It's 2017. You should understand at least a bit about the internet and
how to use it.


I can use it but can't fix it when it goes wrong.


I don't know if you're an idiot or a troll. Using TCP/IP networking is
pretty simple (at least if you're using a real language - your own toy
languages might have made it unnecessarily hard, for all I know),
hardly "over-complex" by comparison to RS-232 programming.


So how do you use it from Python - without using an existing Python 
library? Or is it only simple when someone else has made it idiot-proof?


(That reminds me, at some point I have to provide a winsock2.h file for 
my C compiler. I may have to finally learn some of this stuff to test it.)



I just don't work that way. The OS is there to launch applications, or to
provide a basic API for common services such as a file system. I don't need
its complicated shells.


Blub rears its head again.


How so? I said I have little need for most of what an OS does, in my 
development work, which is perfectly true. Perhaps you haven't noticed 
that many are using sophisticated IDEs now rather than fiddling about 
with command lines. (Mine is not sophisticated, but still better than a 
command line.)



At what point will you acknowledge that there are things you do not
understand that are actually useful?


I can understand that people who use Unix and Linux arrange their world 
so that all these things are apparently indispensable.


What you're trying to tell me is that because Unix provides such a 
tightly knit system system of utilities, stdin, stdout, files, pipes and 
very specific ways of using the keyword (which seems to consist of 
avoiding actually using it for entering data as much a possible; just 
using the logical idea of it), then every other text entry system in the 
world, in whichever OS or application, must follow exactly the same 
model. Because the Unix one is so great.


Needless to say, I disagree.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-06 Thread bartc

On 06/10/2017 18:55, Marko Rauhamaa wrote:

bartc :


The internal utilities used within an operating system, primarily
intended for file or redirected i/o with no live interaction, should be
distinct from those designed to be used directly with a live user.

Or is it against the rules of Unix to have two different versions of a
program?

Then you might have 'sort' for the non-interactive version, and 'isort'
or whatever for the interactive.


You are right that interactive programs exist and operate very
differently from what are known as *tools*.

Interactive Linux programs include:

 LibreOffice
 NetworkManager
 Firefox
 Skype
 XBoard
 Emacs
 GIMP
 top
 gdb

etc.


I meant interactive programs that work with a scrolling display, as 
suits a program like this:


 while 1:
print (input("?"))

Considerations of the 'eof' status of a keyboard would of course be 
irrelevant for anything more sophisticated, either with a more organised 
console app, or one using a GUI.



I don't know if anybody has seen a market/need for an interactive sort
program, but there's nothing preventing you from writing one.


For sort, there is no real need. You use a text editor to create your 
data. Then use existing file-based sort.



So I can't see the point of using that same pattern of input usage
(reading from stream, file, pipe whatever until interrupted with an
EOF signal) for a true interactive program that is used in a sensible
manner.


So go ahead and write an interactive sort program. It might employ a
mouse, joystick, iris scanner, touchscreen, sound effects or whatever
facilities you would think would be useful for the human user.


It wasn't me who brought up 'sort' when the subject was interactive 
keyboard dialogues (it was Chris I think).



A program like 'python' might fit the bill too. Here, you can give it
the name of a file, OR say nothing, and it will take input from stdin.


Personally, I think stdin is a bit lame as a stimulus source for an
interactive program. That's not even what stdin is primarily meant for;
stdin is meant to be the input data for a job. Similarly, stdout is
meant to be the result of the computation. Stderr, then, is used to
deliver optional diagnostic messages, ie, metainfo about the
computation.


You really need punched tape or cards for input and output to get the 
full effect. Complete with all the sound effects. Sadly when I came into 
it, we were using mag-tape for input (with a variety of outputs).


The clatter of an ASR33 printing your results was also a treat.

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-06 Thread bartc

On 06/10/2017 20:38, Grant Edwards wrote:

On 2017-10-06, bartc  wrote:


For sort, there is no real need. You use a text editor to create
your data. Then use existing file-based sort.


I sort streams on stdin far more often than I sort named files.


So what's been established is that 'sort' is useful for a text stream 
that already exists as a file or is the output of another process.


What hasn't been established is why how this works this has to influence 
the design of simple text-based dialogues, real ones where there will 
likely be an actual user tapping the keys in real time.


The only tenuous connection I can see, is that if 'sort' is run without 
any piped or redirected input, it will resort to the keyboard. Even 
though that method is not user-friendly and hardly anyone ever uses it 
in that mode. So that same unfriendly technique should be the model for 
text dialogues everywhere.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-06 Thread bartc

On 06/10/2017 20:21, Chris Angelico wrote:

On Sat, Oct 7, 2017 at 5:51 AM, bartc  wrote:



If you're stuck, whip out a tablet computer or smartphone (they should still
function without connectivity) and use a preloaded text editor. Or just
compose and then save an email. Even the simplest should be more
sophisticated than just blindly entering text on a Linux terminal screen.


Save an email and then what?


You will have been able to create and review the text using normal 
editing methods. It will then be saved as a draft somewhere. When the 
sort program is back up (if that's what you're planning), then retrieve 
the text with copy&paste. No need to actually send it anywhere.


My point is that everyone has the facility to create at least plain text 
documents off-line.


There is no need to start some ancient terminal utility, get no response 
from it, then blindly type in line after line with no idea if it's doing 
anything with it.



You need to make a change to something on
a remote server. Maybe your hosts file is borked. Maybe the mail
server configuration is slightly off, resulting in delayed delivery.
Maybe your bindfile has an outdated record in it so half your users
are getting timeouts. Whatever it is, it's almost certainly going to
be managed by a text file in /etc, so you need to edit that file.

How do you edit a file on a remote computer? How do you compare three
instances of that file on different computers to see if one of them is
different?


I've no idea where you're going with this.

Remember my original complaint was in treating keyboard entry like a 
file complete with EOF marker.



They were a creation of either C, Unix, or some combination. Certainly I had
very little to with any of that for decades. I can't remember that it ever
stopped me doing anything I needed to do.


That's Blub. You've never used it, so you don't understand its value,
so you scorn it.


OK, that works both ways as you've never used any of my stuff.


  print #w, "Four"  # to window or control w
  print #b, "Five"  # to image b



I'm not sure what printing to a window or image would mean, or how
it's useful,


It displayed the text at the current position (using the current font, 
size and colour) and moved the current position to the end of the text.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-06 Thread bartc

On 07/10/2017 00:43, Steve D'Aprano wrote:

On Sat, 7 Oct 2017 12:24 am, bartc wrote:


print ("Enter blank expression to quit.")



I *despise* programs that do that, and would cheerfully and unapologetically
take their designers, disguise them as a lettuce, and stake them out to be
nibbled to death by snails.

At the interactive prompt, I am frequently hitting Enter on a blank line,
either by accident, or deliberately to break up the calculations into groups,
or just to give myself time to think.

Blank lines should be treated as "do nothing" and simply ignored, and there
should be an explicit QUIT command.



Um, that actually follows what interactive Python does. If you type this 
(I'm using <<< as the prompt as >>> confuses my newsreader's quoting 
system):


 <<< def fn():
 <<<pass
 <<<pass

At this point, you can break out by pressing the key for 'eof', or by 
pressing Enter at the start of a line. Even though a blank line is legal 
Python syntax.


(Most of my real interactive programs with a command line interface 
programs use Escape, quit, exit, q or x to finish.


Interactive Python requires quit() or exit(), complete with parentheses. 
Unless you've redefined quit and exit as something else, then you have 
to crash out by other means.)


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-06 Thread bartc

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.)


(In my IDE, if a particular C file is highlighted, then typing 'cpp' 
will invoke the currently selected C compiler's -E equivalent, then 
instantly show the result in the editor.


Looking at the script for that, that does make use of the -o option, for 
gcc, so I must have known about it.)



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.


I think they are different kinds of applications.

(As for the ability to chain these programs together, I have the same 
opinion of that as doing the same in program code when you use the 
result of one function/method call to feed in as the argument to the next.


They can both end up as long horizontal hard-to-follow (or to intercept) 
sequences.


I'd prefer to break them up using intermediate variables in the language 
and intermediate files in the shell.


And as you can see from my IDE's 'cpp' command, which works with 4 
different C compilers (a fifth doesn't properly support -E), there are 
other approaches developers can use.)


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-07 Thread bartc

On 07/10/2017 02:46, Steve D'Aprano wrote:

On Sat, 7 Oct 2017 06:18 am, bartc wrote:


For sort, there is no real need. You use a text editor to create your
data. Then use existing file-based sort.


What you mean is, *you* see no need for sorting interactively, or sorting as
part of a pipeline of functions. That speaks more of your lack of imagination
and closed-mindedness than any real lack.


Where did I say that?

The 'existing file-based sort' works from files and pipes.

It's capturing the data to start with that it would be ludicrous to do 
interactively using such a crude interface.



Personally, if I have a few (say, a dozen or so) lines I want sorted, it is
much easier to:

- select text from whatever application I'm using;

- bring up a terminal (I almost always have one already open);

- type `sort ENTER`;

- middle-click to paste the lines;

- type Ctrl-D;

- select the output lines;

- paste back into the original application;



That's not entering the data interactively (such as typing 'sort' then 
it sits silently recording lines of text (you hope) until it sees EOF). 
You say the lines already exist in a text editor. Exactly what I said; 
you start with text that has already been entered or generated by other 
means.


However it does seem to expose a flaw in the ability of command line 
tools to work with non-command line tools.


So I have to copy 33,000 lines from a document, get to the terminal 
(keeping that document open because I'm not done with it), start 'sort', 
and paste those 33,000 lines into the console, then type Ctrl-D. Which 
then promptly prints the newly sorted 33,000 lines onto the console. 
Then you have to select those 33,000 lines (not easy as you now have 
find the midpoint of 66,000 lines of output), copy it, and paste it back 
into the app.


Put that way, it doesn't sound very sophisticated does it?

(Now I expect you're going to bombard with workarounds to fix all those 
issues.)



(seven steps)


versus:




That's not what I meant at all, which is about creating the data from 
scratch. Here, the data STILL already magically exists somewhere!


Is it possible that you guys have never had to create anything original?

(How would /I/ sort a block of text in my editor? There's no built-in 
function, so using your approach:


 * Select the block

 * Ctrl KWfileEnter to write it to 'file'

 * Elsewhere, sort file2

 * Back in editor, Ctrl KY Ctrl KRfile2Enter to delete then insert file2

Only four steps? Something went amiss in your analysis I think. And even 
these could be simplified by Using Ctrl KS and Ctrl KL to use a 
predefined clipboard-like filename for the intermediate.


However, how hard would it for the editor to do its own sorting? Not 
very, as it turns out, only half a dozen lines of code (see below after 
sig). Now the sequence is:


  * Select the block

  * Ctrl KH

How many steps did you have, seven?)


I forget... it is "work harder, not smarter"? Being inefficient is a good
thing, right?


Okay

--
bartc

--
proc cmd_ctrlkh <"med:*ck*ch "> (td) =
if td.blockstart then
isort(td.text[td.blockstart..td.blockend])
pageupdate(td)
fi
end
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-07 Thread bartc

On 07/10/2017 03:18, Chris Angelico wrote:

On Sat, Oct 7, 2017 at 12:50 PM, Steve D'Aprano
 wrote:

On Sat, 7 Oct 2017 06:21 am, Chris Angelico wrote:


I'm not sure what printing to a window or image would mean, or how
it's useful, but sure.


Print to window: Print Preview.

Print to image: export to pdf or jpg or png.


Except that that isn't what you get in his programming language. What
you seem to get (judging from his response to the post you're quoting)
is something that lets you treat a GUI window as if it were a console,
printing text to it in some sort of "glass teletype" way. Leaves me
wondering if he's ever taken one of his apps to a system that uses a
different default font, or anything like that. Unless all his GUIs are
built in HTML?


(That particular language was one I was using over 20 years ago and it 
was an integrated part of a CAD application (and it started off 
pre-Windows).


The app also supported printer/plotter/image destinations including 
PostScript. The same language could take a marked-up text file, convert 
it to a series of drawing elements, then render and print that page on a 
PS printer. Then the same with the next page. I think I did a 350-page 
manual like that. With pictures.


My current language doesn't link its 'print' to graphic displays or images.)

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-07 Thread bartc

On 07/10/2017 09:35, Steve D'Aprano wrote:

On Sat, 7 Oct 2017 11:05 am, bartc wrote:



Um, that actually follows what interactive Python does.



What is "that" to which you refer?

If you mean, "what I, Bart C, suggested, namely having the program exit on a
blank line", then you are wrong. In the Python interactive interpreter, you
can enter blank lines, and the interpreter doesn't exit.



There's one priviso: blank lines are only ignored at the primary prompt >>>
not the secondary prompt ... where a blank line is used to end the block. But
the interpreter doesn't exit. A slight compromise for the sake of convenience
at the interactive prompt.


That's what I mean. Enter is used to end one state and get back to another.

The same thing with my loop evaluating expressions. When you're done 
with with expressions, you might exit in the trivial example, or you 
might get back to a main command loop. Just like Python.





(Most of my real interactive programs with a command line interface
programs use Escape, quit, exit, q or x to finish.


And how do you distinguish between calling quit from inside the function, and
using quit inside the function?


Huh? Most interactive programs aren't language interpreters like Python, 
where everything needs to be considered to be a line in the language syntax.



Unfortunately ESCAPE is already used. VT100 (the terminal emulation which is
used in just about all terminals) all control sequences begin with ESC. So
every time you do something like press an arrow key, the terminal sends ESC
followed by other stuff. It would be painful if every time you hit an arrow
key, the interpreter took it as "Exit".


Yes, I discovered this. So my programs that use Escape on Windows needed 
to use Escape Escape on Linux to get around that.



Interactive Python requires quit() or exit(), complete with parentheses.
Unless you've redefined quit and exit as something else, then you have
to crash out by other means.)


"Crash out", he says.

If your intention is to prove that you're a know-nothing ignoramus, you're
doing an excellent job of it.


Yes, crash out. I've always considered control sequences as something 
out of the ordinary used when things go wrong. Eg:


 <<< while 1:
 <<< pass
 <<<

Here it appears to hang, and nothing you type does anything except (on 
Windows) Ctrl-C. That's what I call crashing out. Although that stays 
within the interpreter. If I press Ctrl-Break instead, it aborts the 
interpreter too.


What exactly is your problem, that anyone who has a different take on 
things must be an 'ignoramus'? And, to boot, an ignoramus who knows nothing?


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-07 Thread bartc

On 07/10/2017 14:19, Steve D'Aprano wrote:

On Sat, 7 Oct 2017 11:06 pm, bartc wrote:



Ctrl-K to enter "operate on selected text" mode;
Y to Delete
Ctrl-K to enter "operate on selected text" mode;
R to Read from a file (at last an actual mnemonic command!)
enter a file name

That's five steps.


Are we counting steps or keystrokes?


And now you have two "temporary" files, file and file2, which need to be
deleted. Two more steps that you conveniently don't count.


Actually I keep a set of 9 scratch file names just for such purposes. So 
overwriting and deleting don't matter. (Apparently the names are 
offensive to some so I won't mention them, but they're easy to type.)



And you think that memorising these non-standard keyboard shortcuts Ctrl-KW
Ctrl-KY Ctrl-KR


I believe these used to be WordStar commands, if anyone can remember that.

 is better than memorising Ctrl-D which works across thousands

of applications? Good for you. You probably would love Emacs, except other
people use it, and therefore you will hate it.


[...]

However, how hard would it for the editor to do its own sorting?


Yes, it is a mystery to me why so few editors include a "sort lines" function.


I don't know if you're being sarcastic here or not, so I don't know if 
you mean few editors have 'sort' or most of them do. Neither do I get 
the point you're making.


But it's a little ironic that it took less time to add such a feature 
than I spent writing about it in a post!


--
bart

--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-07 Thread bartc

On 07/10/2017 14:19, Steve D'Aprano wrote:

On Sat, 7 Oct 2017 11:06 pm, bartc wrote:



So I have to copy 33,000 lines from a document,


Don't be daft. Nobody says that stdin is a sufficient interface for a
heavy-weight task like that. With 33000 lines of text, I absolutely would
save them to a permanent file on disk, because I wouldn't want to risk having
the application crash or the power go off just as I've typed line 32999 and
lose the lot.


You're missing something I think. The 33K lines already exist elsewhere, 
and have been copied to the clipboard. So you won't lose anything if the 
power goes off, assuming the original are secure.



For 33000 lines, having one extra temporary file floating around is a cost
worth paying. For 33 lines, it is not.


I was demonstrating the crudeness of copying and pasting to a console 
window rather than between proper applications. That was easier to show 
with a larger example which highlighted some of the practical aspects.



You want a one-size fits all solution. Are you capable of understanding that
different tasks and different scenarios are often best solved using different
techniques?


[...]

Put that way, it doesn't sound very sophisticated does it?


Nobody said it was sophisticated. That's the whole point: having sort read
from stdin as you type into the terminal is the LEAST sophisticated,
simplest, most bare-bones, basic technique that works.


You do remember this was about using programs /like/ sort as a model for 
writing true interactive scrolling text apps?


I said it was a poor model because sort is normally used with files and 
pipes. You're trying to keep it as a viable model because, sometimes, 
sort can also be used with pasted text which sort reads as as though it 
had been typed in real time (not from a pipe or file anyway).


OK, I'm not suggesting doing away with that.

But it is still a bad model of text application to use elsewhere, even 
if extra prompts were added. For one thing, it only reads one block of 
data, then it stops. A more typical text application will be doing 
different things requiring different entry modes.


--
bartc
--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-07 Thread bartc

On 07/10/2017 15:45, Grant Edwards wrote:

On 2017-10-07, bartc  wrote:


Interactive Python requires quit() or exit(), complete with parentheses.


Nonsense.  On Unix you can just press ctrl-D (or whatever you have
configured as eof) at the command prompt. On windows, it's Ctrl-Z
.


Steve spoke about the 'usual quit/exit/bye' commands.

If you type 'quit' in interactive Python, then it says:

  Use quit() or Ctrl-Z plus Return to exit

Same for exit. So in Python, IF you want to use quit or exit to 
terminate, you have to use quit() or exit() instead.


So please explain how what I wrote was nonsense.


Unless you've redefined quit and exit as something else, then you have
to crash out by other means.)


Admit it, you're just trolling.


FFS, NOW what's wrong?

IF you DO redefine those names, then you DO have to use other means to 
terminate. I happen to call those means 'crashing out', because it's 
like yanking the plug rather than using the on/off switch. Especially on 
Windows where the usual Ctrl C doesn't work, so you resort to Ctrl-Break 
will which actually abort it. Ctrl Z is uncommon.


I suspect it's you trying to deliberately wind ME up.

I'm getting fed up with this thread now.


--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-07 Thread bartc

On 07/10/2017 17:28, Steve D'Aprano wrote:

On Sun, 8 Oct 2017 01:15 am, bartc wrote:



You do remember this was about using programs /like/ sort as a model for
writing true interactive scrolling text apps?


I don't remember any such thing. I remember you *claiming* that, but if anyone
actually did make that claim, I haven't seen it.



bart:
> This doesn't make sense. For interactive use, you wouldn't bother
> testing for eof, as you'd be testing the eof status of the keyboard.
>

ChrisA:

> You mean the way heaps and heaps of Unix programs work, processing
> until EOF of stdin? Yeah, totally makes no sense, man, no sense at
> all.

bart:
> If you're referring to the ability to redirect stdin so that input can
> come from a file as well as from a live keyboard, then you're doing
> file handling; it's NOT interactive.

ChrisA:
> How would you write a sort program? How would you tell it that you're
> done entering data?

--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-08 Thread bartc

On 08/10/2017 10:12, Steve D'Aprano wrote:

On Sun, 8 Oct 2017 02:06 am, bartc wrote:



Thousands of Python programmers on Windows successfully learned to use Ctrl-Z
ENTER back in the days of Python 1.5, before quit/exit were added as a
convenience for beginners, and many of them probably still use it.


Actually I NEVER normally use Python in interactive mode. Only to test 
how it works interactively. When I use Python, it's from my IDE.



I'm getting fed up with this thread now.


This thread would be a lot less frustrating if you would enter into it with a
spirit of open-minded enquiry rather than an overbearing sense of superiority
that anything others do that you don't must be worthless.


Frustrating for whom?

It seems to me that it's pretty much everyone here who has an 
overbearing sense of superiority in that everything that Unix or Linux 
does is a million times better than anything else.


Even with things like building applications (eg. trying to build CPython 
from sources), they are designed from the ground up to be inextricably 
linked to Linux scripts, utilities, makefiles, installation schemes, or 
designed to work with the Linux-centric gcc C compiler. Then when they 
don't work as well anywhere else, it's because Linux is so much better! 
No, it's because they were non-portably designed around Linux and 
therefore designed NOT to work well anywhere else.


It is also slightly frustrating for me when I see how Python is 
developing, with layer after layer and library after library piled on to 
achieve some fantastically complicated solution (one of 48 different 
ones to choose from) to replicate some basic functionality that could 
have been done in 5 minutes if GvR had decided to add it right at the start.


But this is a Python group and I have to restrain myself from such 
comments to avoid getting lynched. There is nothing wrong with Python!


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-08 Thread bartc

On 07/10/2017 15:40, Steve D'Aprano wrote:

On Sat, 7 Oct 2017 11:54 pm, bartc wrote:


So my programs that use Escape on Windows needed
to use Escape Escape on Linux to get around that.



Or you could just follow the expected Unix interface instead of inventing your
own.


Your job is to port an editor that people have been using for 30 years 
to Linux. The first thing you do is to change all the commands and 
shortcuts to match what is typical on Linux? So that no-one who was 
familiar with it as it was can actually use it?





Back in the days when I used a Mac (long before OS X), I used to hate it when
Windows developers would port their software to Mac. With the exception of a
few big software companies like Microsoft, who had actual Mac teams, they
would do what you do: completely ignore the Apple UI guidelines and port
their unfamiliar and arbitrary user interfaces to the Mac software, making it
essentially unusable.


What is it with those who write OSes in that they have to tell everyone 
how to run the show? An OS's job is to run programs and do whatever the 
program requests.


BTW, how did the Apple UI guidelines come about; where they copying 
existing practice, or did /they/ decide to come up with something new 
and incompatible with anything else? And if the former, then you ask the 
same question of Xerox or whoever.


Just look at any interactive page on the web, they all work differently. 
People are used to it. And it allows innovation.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-08 Thread bartc

On 08/10/2017 12:22, Paul Moore wrote:


When developing scripts, applications, or any form of code, I use good
ideas from anywhere, as I doubt that I have the monopoly on knowing
the perfect way to write code. Some of those good ideas come from
Unix-based systems. That's not "because Linux is so much better", it's
because someone other than me had a good idea, and I acknowledge the
fact.


When developing code I use whatever tools and techniques I like.

But if I want to someone else to build one of my applications, I make it 
as easy as possible for them, even to to the extent of translating it to 
a language that they will be able to build.


Here, for example, is a C compiler (which, actually, is not written in 
C, but is presented as a C program):


   www.bcas.freeuk.com/mcc64.c

One file only. But it is only for 64 bits. Build on Windows or Linux 
(for Linux it is 'gcc -m64 mcc64.c -omcc -lm'). Runs on either (but 
generates code for win64 ABI).


Another: www.bcas.freeuk.com/pcc64.c, a byte-code interpreter, builds 
and runs on either OS, one file. That needs a separate byte-code 
compiler, www.bcas.freeuk.com/qcc64.c. Again, one file. Again, runs on 
either OS. And I believe each file works with any C compiler.


(Actually, I just found it had a dependency on a Windows time function; 
I've removed that temporarily for this upload.)


See the pattern here? Simplicity not complexity. Consideration for 
others by making life easier.)



--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-08 Thread bartc

On 08/10/2017 13:05, Chris Angelico wrote:

On Sun, Oct 8, 2017 at 10:46 PM, bartc  wrote:



Just look at any interactive page on the web, they all work differently.
People are used to it. And it allows innovation.



Maybe it's just that you're not old enough to have worked with text
editors that predate CUA? That might explain your confusion about what
should be standardized.


I first used line editors in the 1970s.

When I started writing graphics apps, graphics was very new, at least in 
the low-end business computer world (the one that was soon dominated by 
the IBM PC).


So there was little existing practice to copy from. (And actually, I had 
my hands full either designing the graphics boards, or writing the 
drivers, graphics libraries, providing the fonts and so on (plus the 
languages), all the underlying stuff needed to make it all work.)


However as graphics became more mainstream then yes I did adopt some 
commonly expected styles (menubars for example). As for Alt-F4, if that 
generates a WM_CLOSE message for example, then I would be obliged to 
deal with it.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-08 Thread bartc

On 08/10/2017 17:13, Chris Angelico wrote:

On Mon, Oct 9, 2017 at 2:01 AM, bartc  wrote:

However as graphics became more mainstream then yes I did adopt some
commonly expected styles (menubars for example). As for Alt-F4, if that
generates a WM_CLOSE message for example, then I would be obliged to deal
with it.


Yes, it usually does generate that. Why? Because your desktop manager
translates concrete user actions into abstract events like "close
window" - and does so according to a number of standards. In case you
haven't noticed, those standards are not 100% consistent across
platforms. So that means that...

On Sun, Oct 8, 2017 at 10:46 PM, bartc  wrote:

On 07/10/2017 15:40, Steve D'Aprano wrote:

Or you could just follow the expected Unix interface instead of inventing
your own.


Your job is to port an editor that people have been using for 30 years to
Linux. The first thing you do is to change all the commands and shortcuts to
match what is typical on Linux? So that no-one who was familiar with it as
it was can actually use it?


... yeah, you absolutely *should* follow your OS's conventions, and
you automatically *will* if you're using a properly-designed GUI
toolkit. Why should it be different with the console? For instance,
anyone on Linux will understand what this prompt notation means:

Use config file: [~/.flurblerc]

Yep, definitely follow your host platform's conventions.


Yeah, well, some people like to be sheep, others like to be individuals**.

I start in computing at a time when an application was the only thing 
running on a computer, at least, when people had personal computers of 
their own. Then it really didn't matter what went on outside, as nothing 
did.


(That approach seems to have become popular again with tablets and 
things usually having one application occupying the screen at a time.)


And within an application, it can do what it likes. With regards to 
editing, there are some common conventions that I absolutely hate:


* Left and right keys, and backspace and delete keys, that don't regard 
the left and right ends of a line as hard stops; they just keep going. 
OK-ish for word processing, but not for line-oriented code.


* Clicking on a box containing text and the whole thing being 
highlighted. Now you're on tenterhooks as the slightest move and 
everything disappears. You might be able able to press Ctrl Z to get it 
back (yes, the same Ctrl Z that's supposed to terminate applications!) 
but it's still highlighted.


* Clicking backspace on a web page doing the same as the Back button. 
Now, backspace is used for editing text within forms. It's very annoying 
if, after half an hour filling in a form, somehow the current box loses 
the focus (the cursor), but you proceed to press backspace space several 
time before noticing. Like my first complaint, but in spades.


* Under Windows, if you press Shift while Caps Lock is on, you get lower 
case letters. I've never, ever wanted to do this (probably no one else 
has). My own editor doesn't obey that convention: shift-A will always 
come out as 'A' whatever the caps lock setting.


There are dozens more, yet you are surprised why sometimes I prefer 
doing things my own way? There are good reasons!


(**I was in the audience of a Michael Palin interview a couple of weeks 
back. (You know, an actual Python!) Before he came on the audience was 
programmed to respond to the word 'individuals' by all saying 'Yes, we 
are all individuals!'. Apart from me, obviously.)


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-08 Thread bartc

On 08/10/2017 19:10, Chris Angelico wrote:

On Mon, Oct 9, 2017 at 3:50 AM, bartc  wrote:



You assume that since
*you* have never needed to produce one lower-case letter in a block of
upper-case, that "probably no one else has", and then you make it
impossible to do that in your editor.


Only when caps-lock is stuck on (then the feature may have be of some 
use at last). However my editor also makes it very easy to reverse or 
change case of existing text.


The advantage of Shift working one-way is that it is guaranteed to give 
you a capital letter without you needing to check the caps-lock status 
or checking the screen to see that it was typed as capitals.


That is 100 times more useful than the rare time you have to add a lower 
case letter in a sea of capitals and can't be bothered to turn off caps 
lock.


 I have wanted to produce a

lower-case letter by holding Shift.
I've read that other people have had exactly the same trouble. I don't 
believe that my pattern of typing English text is that different from 
most other people's, and I've ALWAYS found that 'feature' annoying, so 
from that I might infer that plenty of others do too.


In fact, if I start off MS Word, with caps lock unknowingly on, and type 
Shifted-T, unshifted-H, unshifted-E, that will temporarily display 'tHE' 
before it gets auto-corrected to the intended 'The'.


I wonder why it does that? According to you, people WANT to type tHE.

BTW, all the typewriters I've used do exactly what I want. If caps lock 
is on (shift-lock there), then pressing Shift doesn't reverse it. So, 
what happened to existing practice there, typewriters hadn't been around 
long enough?


> I have also used this behaviour to
> detect and recognize faults of various sorts. Do you understand the
> concept of debugging a system by getting more information, not less?

I've no idea what you're talking about there.

> Yep. Good reasons like that you're a moron.

> Yeah, well, some people like to be standards-compliant, others like to
> be irrelevant morons.

I started to be angry when I saw these insults now I'm just rather 
depressed.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-09 Thread bartc

On 09/10/2017 06:15, Gregory Ewing wrote:

Grant Edwards wrote:

Which took it from RSX-11.  Or probably more specifically from
FILES-11.  I woldn't be surprised if the enineers at DEC got it from
somewhere else before that.


Quite possibly it goes back to the very earliest DEC OS
that had files, whatever that was.

The reason for it was that the file system only kept track
of file sizes in blocks, not bytes, so some way was needed
to mark the end of a text file part way through a block.


Ctrl-Z was just code 26 or [what I've always called] ETX or end-of-text.

I'd used DEC quite a bit (including rsx-11m) but only became aware of 
ETX when using CP/M. (Where it had a annoying habit, IIRC, of copying 
files in text mode so that it stopped at the first ETX byte.)


And actually, until recently, I added ETX (followed by 0 for good 
measure) as a sentinel in a function reading a file into a block of 
memory (now I just use 0 for that purpose).


But I don't consider that these internal uses, some of which are 
archaic, belong in a user interface.



[Looking it up now, actual ETX is code 3, or Ctrl-C, and EOT is code 4. 
So how 26 - apparently code SUB, whatever that means - ended up being 
used to mark the end of text files, I don't know.]


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-09 Thread bartc

On 09/10/2017 05:49, Chris Angelico wrote:


Generally, my preferred editor is nano, since it lives within those
requirements but still has a decent UI. It's not always available
though, and it's useful to know how to manage without it. But even
though you won't always be doing this sort of thing, it's definitely
something that a *programming language designer* should be aware of.
Basic networking is critical to any modern language.


That's an odd opinion given that modern languages don't even want to 
have basic input and output as part of the language; they're offloaded 
to a library. And in your example, which I don't really understand, it 
seems more like the headache of the application.


(Where a language allows elements of a program to be disseminated across 
a network, that's rather different, and an advanced feature that only 
some languages might have. Not all.)


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: on = style

2017-10-09 Thread bartc

On 09/10/2017 07:40, Abdur-Rahmaan Janhangeer wrote:

hi just a quick question, why is

my_pens = 4
my_pencils = 5

is preffered to

my_pens = 4
my_pencils = 5

*referring to = symbol alignment



I will sometimes line things up, if a block of assignments are related:

  red = 1
  green   = 2
  blue= 3

There might sometimes be extra maintenance if you then add:

  turquoise = 4

and have to readjust the others, or you add:

  yellow= 201

and prefer the number should be aligned right-justified:

  red   =   1
  green =   2
  blue  =   3
  turquoise =   4
  yellow= 201

but it's not hard. Although it might not be worth doing until a program 
is finished. Compare to:


  red = 1
  green = 2
  blue = 3
  turquoise = 4
  yellow = 201

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: The "loop and a half"

2017-10-10 Thread bartc

On 09/10/2017 01:37, boB Stepp wrote:

On Sun, Oct 8, 2017 at 5:36 AM, bartc  wrote:



And Bart, when large numbers of technical experts in their fields have
spent many hours/months/years, yea, even several decades, developing
these software systems, why do you think that you, all by yourself,
know better?


In some fields, then yes!

The problem with experts is that they do like to pile layer upon layer, 
plus another layer to deal with the complexity created by the previous 
layers!


For example, I write compilers, including a C compiler. But I couldn't 
start compiling the CPython sources (with any compiler actually), 
because the first step was running a 30,000-line configure script, for 
Linux. I work on Windows.


However there is now a solution using VS2015. There was a thread on this 
subject in May 2017, and there I recounted my attempts at using VS2015 
to build CPython. A copy of that I've put here:


 https://pastebin.com/raw/V76WP1Ha (Raw text so no adverts.)

CPython is 250K lines I think; a fast compiler ought to be able to deal 
with a program like that in one second (depending on how many files it's 
split up into). Now look at that link.


Experts

Building big cumbersome, complicated systems is easy. Making them small 
and simple is harder.



Can you not see how frustrating this is for people who
have spent good chunks of their lives trying to do the best they can
on these software systems?


Only if they concede I might have a point. I haven't seen much sign of that!

I doubt anyone using *nix systems, which are massively popular, is going 
to start feeling insecure due to the opinions of one guy.


You say (in a bit I see I've snipped), that non *nix people read these 
forums. But my experience is that the majority of people who post (in 
c.l.p and comp.lang.c) are using *nix. It's unbalanced.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-11 Thread bartc

On 11/10/2017 14:16, Marko Rauhamaa wrote:


C++'s main problem is that it tries to solve the wrong problem. A C++
compiler seeks to make sure your program doesn't have bugs. That noble
(but futile) goal makes it painful to program in C++.


It's painful to program for lots of reasons, I don't think that is the 
main one.


The ideas behind C++'s many features individually make perfectly good 
sense - on paper. Until you look at ghastly examples of C++ source code 
and it really hurts your eyes.




Python and C don't try to protect you. In return, you get syntactic
convenience that probably enhances the quality of your programs.


Python, maybe. C syntax isn't as painful as C++ but I still have a lot 
of trouble with it. (Eg. the variable declaration 'char(*(*x[3])())[5]'. 
The name of the variable can be found lurking in that lot somewhere, but 
what's the type?) Not so convenient.


--
bartc


--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-11 Thread bartc

On 11/10/2017 15:52, breamore...@gmail.com wrote:

On Wednesday, October 11, 2017 at 3:14:51 PM UTC+1, bartc wrote:

On 11/10/2017 14:16, Marko Rauhamaa wrote:


Python and C don't try to protect you. In return, you get syntactic
convenience that probably enhances the quality of your programs.


Python, maybe. C syntax isn't as painful as C++ but I still have a lot
of trouble with it. (Eg. the variable declaration 'char(*(*x[3])())[5]'.
The name of the variable can be found lurking in that lot somewhere, but
what's the type?) Not so convenient.



https://cdecl.org/ tells me that your variable declaration is a syntax error so 
maybe not much of an example.


Perhaps you didn't write or paste it properly. The site tells me that:

   char(*(*x[3])())[5]

(with or without a trailing semicolon) means:

   declare x as array 3 of pointer to function returning pointer to
   array 5 of char

(Example taken from page 122 of the C book "K&R2", in a section about 
writing a program to make sense of complex declarations.)


Anyway that fact you either tripped up on typing it, or that you had to 
use a special tool to find out what it meant, sort of reinforces my point...


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-11 Thread bartc

On 11/10/2017 15:36, Chris Angelico wrote:

On Thu, Oct 12, 2017 at 1:14 AM, bartc  wrote:

Python, maybe. C syntax isn't as painful as C++ but I still have a lot of
trouble with it. (Eg. the variable declaration 'char(*(*x[3])())[5]'. The
name of the variable can be found lurking in that lot somewhere, but what's
the type?) Not so convenient.


People love showcasing stupid examples like that. But how often do you
REALLY make declarations that complex? That's not technically
strawmanning, since C syntax does indeed include that, but you're
cherry-picking the most extreme example.


Sure. Statistically most declarations are going to be things like 'int' 
or 'char*. But more complicated ones (usually not as bad as the 
example), crop up often enough to be a nuisance.


I may see them more than others because I very often need to interface 
one of my languages with some API defined in C, and I need to exactly 
understand what the types are so that I can create compatible ones.


Anyone else can just include the apposite headers and be done with it 
without needing to see what's inside.


While on the subject of C syntax, here are some fun ambiguities:

f(x);// call function with arg x, or declare x of type f?

a*b; // multiply a by b, or declare b of type pointer to a?

(a)*b// multiply a by b, or cast *b to type a?

I understand that in C++, you also have things like this, but in spades.

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-11 Thread bartc

On 11/10/2017 17:16, Jonathan Cast wrote:

On Wed, 2017-10-11 at 15:14 +0100, bartc wrote:

On 11/10/2017 14:16, Marko Rauhamaa wrote:

Python and C don't try to protect you. In return, you get syntactic
convenience that probably enhances the quality of your programs.


Python, maybe. C syntax isn't as painful as C++ but I still have a lot
of trouble with it. (Eg. the variable declaration 'char(*(*x[3])())[5]'.
The name of the variable can be found lurking in that lot somewhere, but
what's the type?) Not so convenient.


I believe the type of any variable in C is the same as its declaration,
but with the variable name deleted.


Yes, I think we got that...


So:

 char (*(*[3])())[5]


..which doesn't help, and in fact makes things worse, as now you don't 
have a start point at which to start unravelling it. You have to do it 
from the inside out.



That is, an array of 3 pointers to functions that return pointers to
arrays of 5 characters.


But you left out the dozen steps needed to get from that to this!

Anyway if such a type can be more clearly expressed like this, why 
doesn't a language simply allow that, or near enough? Why does it need 
to be cryptic, or require an external tool to encode and decode (there 
is a reason that CDECL exists) or require the programmer to apply an 
algorithm?


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-11 Thread bartc

On 11/10/2017 19:30, Chris Angelico wrote:

On Thu, Oct 12, 2017 at 5:22 AM, Grant Edwards



The easiest way to make stuff like that readable is to unroll them
into a sequence of typedefs.  But, a lot of people never really
learn how to do that...


The most complexity you'll usually see is a function that
accepts/returns a pointer, and those generally should be typedef'd.
But even if not, they're still not anything like as bad as the
mythical examples that get touted as "why C is bad" or "why variable
declarations are bad" or "why type declarations are bad".


IME typedefs can make things worse, especially if used even for basic 
types. Then you spend your time tracing back typedefs to see what they 
mean (was it a char, or struct or what?).


C can combine the abstruseness of its type declarations, overuse of 
macros, and overuse of #if/ifdef blocks to render a lot of code a 
complete nightmare to try and understand. Or debug. Or maintain. Or 
port. Or implement (if testing a compiler).


I've looked at some of my generated C code, and here's one common 
example, not a complex type:


tokenrec * (*)[]

But I couldn't figure that out from the top of my head. Bear in mind 
this was in a parameter list that can change the meaning of []. I looked 
at the original source and that type is written like this:


ref [] ref tokenrec

'ref' means 'pointer to', and it can also be written like this:

pointer [] pointer tokenrec

In English, 'pointer to array of pointer to tokenrec'. See how the 
source language corresponds almost exactly to the English, and both are 
written left to right. Now go back and look at the C version - where do 
you even start? Are those parentheses significant? (I've no idea.)


The most complex of /my/ types to appear in generated C is probably 
this, used as a cast in this assignment:


 pcptr = (*(int64 * (**) (void))pcptr)();

(Original source is this:

pcptr := ref ref function=>ref int64(pcptr)^^()

In English, the cast is 'pointer to pointer to function returning 
pointer to int64'.


The line includes two dereferences (^^) which /I think/ account for two 
of the "*" in the C version. Which * are dereferences, and which are 
part of the type, or indeed whether only one * is the dereference, I 
have absolutely no idea. Great language...)


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-11 Thread bartc

On 11/10/2017 20:30, Chris Angelico wrote:

On Thu, Oct 12, 2017 at 3:29 AM, Rhodri James  wrote:

On 11/10/17 15:36, Chris Angelico wrote:



That's only really one level more complex than declarations I use fairly
regularly (I am an embedded system programmer most of the time).  On the
other hand, I never actually do declare things in that way: typedef is your
friend, and makes your C code much easier to read.


I wouldn't consider embedded systems to be the most common kind of C
coding out there, particularly when people compare against C++ (I
don't remember ever hearing of anyone doing embedded work in C++,
though I'm sure it does happen). Nevertheless, you're exactly right
about the typedefs. Writing crazily complicated type declarations
without typedefs is like writing massively nested list comprehensions
without intermediate variables. Hey look, Python's terrible! Or maybe
they're just non-idiomatic examples.


Look at my last example posted a few minutes before this.

You'd say the C needed typedefs.

But in the original language, type declarations are clear enough that 
they don't need typedefs.


The typedefs help to mitigate a problem in one language that doesn't 
exist in the other. Surely it's better to have neither the cryptic type 
nor the typedef. Everything would be much cleaner.


--
bartc


--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-11 Thread bartc

On 11/10/2017 21:52, breamore...@gmail.com wrote:

>> More importantly is the fact that due to your magnificent 
performance recently you have

been promoted to be the General Manager of my Dream Team.


Thanks, I guess.

You can of course cement your  place when you explain how, in your language, converting an invalid 
piece of user input, which should be an integer, is always converted to 
zero, and how you handle the inevitable divide by zero errors that will 
always, eventually, occur.


You mean it shouldn't do what happens here (Py3):

 a = input("? ").split()
 x = int(a[0])
 y = int(a[1])

 print (x,y)
 print (x/y)

and somebody enters '10 0' ? I don't think you can do much about that. 
However since that thread I've tweaked the way I do this, so that here 
[non-Python code]:


 print "? "
 readln a, b# read each as int, float or string
 println a/b# floating point divide

this produces these a/b results for various inputs:

 10 20  # 0.50
 10,20  # 0.50
 10skjhf 20 # error, divide string by int
 17.9 2 # 8.95
 10 # error, divide int by string ("")
# (blank) error, divide string by string
 .1e10 1e5  # 1.00
 ten twenty # error, divide string by string

For throwaway programs, or for testing, or for trusted input, this is 
perfectly reasonable. For perfect error checking, you need to do a bit 
more work on either verifying input, or using more sophisticated parsing.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-11 Thread bartc

On 11/10/2017 23:03, Gregory Ewing wrote:

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 **


The original has an extra pointer so idiomatic C might be more:

tokenrec ***

But this still defines a different type, namely:

pointer to pointer to pointer to tokenrec

not:

pointer to array of pointer to tokenrec

If you want to lose all array information, and really don't care if 
you're dealing with a pointer, or an array (and don't mind changing how 
such a value is passed, and how it is accessed) then this is fine for you.


You just have to access a 'tokenrec ***args' parameter as ***args. Or 
**args[i]. Or *args[i][j]. **(args[i]). Or ***args. Or args[i][j][k]. 
Yes, any combination will work! Only one will be correct.


In the original source, it can only be accessed one way - the correct 
way. Using the non-idiomatic 'tokenrec *(*)[]' in C imposes some extra 
constraints, but doesn't do the full job. However my complaint was about 
the syntax; the type system of C is another subject.


(How I ended up talking about C in this group I don't know. But 
yesterday I mentioned Python in the C group, so ...)


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-12 Thread bartc

On 12/10/2017 09:23, Christian Gollwitzer wrote:

Am 12.10.17 um 01:15 schrieb Stefan Ram:

   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.


Ok


   /Without/ a typedef.



And WHY would you do that? Typedefs do not cost money.


They cost extra effort in devising them, writing them, and having to 
trace them when someone else is reading the code.




Try this:



typedef double (*countdown_rate_func) (char letter);
countdown_rate_func select_rate_func(int level);




// I've substituted 'x' by 'level'
// and 'g' by 'select_rate_func' for clarity


Those substitutions don't help, as I'm trying to see how well it matches 
the original spec. If I change them back (not easy to tell which bit is 
whic):


  typedef double (*F) (char);

  F g(int x);

No, sorry, it doesn't really cut it. It is still cryptic. It doesn't 
help that C doesn't use a keyword to introduce a function (like, say, 
'function'). You still need to know that double (*F) is a pointer to a 
function returning double, and that double *F is a function returning a 
pointer to a double.


It also introduces this arbitrary name 'F', which if you encounter it in 
source, means you know have to search for this typedef. (And the 
requirement was a definition not a declaration.)


I claim that the above is quite clear, it declares a function in a 
Countdown game engine, which, depending on the level, returns a 
different function to rate the weight of the individual letters.


Renaming 'g' and 'x' to be more meaningful, and introducing a parameter 
name that is not needed, is a different subject. And actually I found 
your 'countdown_rate_func' and 'select_rate_func' names confusing (the 
two are actually of different rank, but both end in _func).



Your exercise results in the line noise
 double (*g(int x))(char)
(thanks to Ben for doing the exercise), which is not extremely bad, but 
still does tell nothing about the intent of that line.


Using any sane syntax for type (AND function) declarations, writing 
Stefan's function is straightforward. For example**:


function g(int x) => ref function(char)real =
   return nil
end

Just transcribed exactly as written (I could have used 'x:int' maybe). 
If I translate this to C, then it gives me:


static double (*g(int32 x)) (char) {
return 0;
}

It's a piece of cake. It shows how important the right syntax can be; 
you write what you have to write, then get on with the rest of the 
coding. Oh, and it's also very easy to read.


It's a mystery to me actually; there is zero cost to devising, 
implementing and using the most helpful syntax, and actually there are 
real benefits. So why use something so bizarre?


(**This is my actual language but as someone guessed, this part is 
derived from Algol68.)


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-12 Thread bartc

On 12/10/2017 06:39, Grant Edwards wrote:

On 2017-10-11, Gregory Ewing  wrote:

Neil Cerutti wrote:

I dig
const qualifiers, even though I'm comletely fine with their
absence from Python.


Out of curiosity, do you have any insights into why you
like them in C++, if you don't miss them in Python?


I like them in C because it allows the linker to place them in ROM
with the code.  It also _sometimes_ provides useful diagnostics when
you pass a pointer to something which shouldn't be modified to
something that is going to try to modify it.


It's one of these features that on paper sound good. In practice, it's 
just useless extra clutter. It's used to:


(1) Define named constants; except (in C) they can't be used like 
constant expressions, you can take their addresses, and accidentally or 
maliciously change their values.


(2) Declare data to be put into read-only memory as you say. That's fine 
with a 'const int * p', but what about a 'int * const p'? (Or is it the 
other way around? Whatever...). Or any other hybrid type where some 
elements are const and some aren't.


(3) Pass data that is supposed to be read-only, but with any even 
slightly complex type, it won't work (the head of a linked list for 
example, where the node elements need to be writeable). It gives a false 
sense of security.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-12 Thread bartc

On 12/10/2017 11:39, Stefan Ram wrote:

bartc  writes:

(1) Define named constants; except (in C) they can't be used like
constant expressions, you can take their addresses, and accidentally or
maliciously change their values.


   When I think of »const«, I do not think of ROM.

   »const« makes code more readable, because it conveys the
   intentions of the author and simplifies the mental variable
   model of the reader.

   »const« helps to find inadvertend modifications.

void f( const int i ){ if( i = 4 )putchar( 'x' ); }


That's two undesirable language features: (1) Having to use 'const' in 
front of every simple parameter, so that 'const' now dominates every 
program; (2) Mixing up '=' and '=='.


You're saying it's OK to use both as they sort of cancel each other out!

(Other languages solve the =/== problem by either not allowing 
assignment within an expression, or by using a symbol for it that isn't 
so easily mistaken for equality.)


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-12 Thread bartc

On 12/10/2017 16:18, Marko Rauhamaa wrote:

Grant Edwards :


Using const with strings in C with amateurish libraries is a headache
because _some_people_ will write their declarations so as to require
pointers to mutable strings even when they have no intention of
mutating them. Those people should be hunted down and slapped with a
herring until they understand the error of their ways.


Hear, hear.


The standard library is much better about that.


You lost me there.

Seriously, though. C strings are not the most problematic issue. How
about other structures? What about:

long ftell(FILE *stream);
int fgetpos(FILE *stream, fpos_t *pos);

Should that be "const FILE *stream"?

In general, C record definitions (opaque structs) that represent
encapsulated classes don't take a "const" in any context. They *could*
but that isn't the tradition. For example, here's a random function from
the Linux kernel:


static bool tcp_fastopen_cookie_gen(struct request_sock *req,
struct sk_buff *syn,
struct tcp_fastopen_cookie *foc)
{
if (req->rsk_ops->family == AF_INET) {
const struct iphdr *iph = ip_hdr(syn);

__be32 path[4] = { iph->saddr, iph->daddr, 0, 0 };
return __tcp_fastopen_cookie_gen(path, foc);
}

#if IS_ENABLED(CONFIG_IPV6)
if (req->rsk_ops->family == AF_INET6) {
const struct ipv6hdr *ip6h = ipv6_hdr(syn);
struct tcp_fastopen_cookie tmp;

if (__tcp_fastopen_cookie_gen(&ip6h->saddr, &tmp)) {
struct in6_addr *buf = (struct in6_addr *) tmp.val;
int i;

for (i = 0; i < 4; i++)
buf->s6_addr32[i] ^= ip6h->daddr.s6_addr32[i];
return __tcp_fastopen_cookie_gen(buf, foc);
}
}
#endif
return false;
}



If you took a working C program and removed all the consts, it would 
still work.


I don't think the language would miss them if they were to disappear.

It is anyway too crude a technique for the things people like to apply 
it to.


>
> Note how both "req" and "syn" could well be declared as "const"
> pointers but are not.

const pointer, or pointer to const struct? Or both?

With a const struct, you are stopped from directly modifying elements, 
but if an element is a pointer, nothing stops you writing to what the 
pointer points to, unless that has a const target too. And then you've 
going to have problems doing normal updates. This constness just 
insinuates itself everywhere.


--
bartc


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-13 Thread bartc

On 13/10/2017 07:16, Gregory Ewing wrote:

Steve D'Aprano wrote:

On Fri, 13 Oct 2017 03:37 pm, Gregory Ewing wrote:


If the compiler can tell where p is initially pointing, it could
put the pointer in read-only memory.


If it's read-only, how can the compiler write to it?

(I come from the days when ROM was actual ROM, burned in at the factory.)


So, the factory is allowed to write to it. Possibly
it's writing data that came from... a compiler?

A memory that couldn't be written to at all, ever, would
be a bit useless!



It's read-only in the same sense as a printed book; you can't change the 
marks already on the page.


I've programmed EPROMS. Neither the C language nor the concept of 
'const' attributes for data ever came into it. While executable code 
doesn't really need it.


It is simply not a necessity. You just arranged for writeable portions 
of memory to be at different locations than that containing the code and 
fixed data. Sometimes it was only data.


'const' is anyway the wrong sort of attribute to use, as I've already 
explained. For example:


  const int A = rand();  // inside a function

A is written to multiple times at runtime. It can't go into actual 
read-only memory like a ROM. And it might have trouble going into a 
memory page with read-only attributes.


'const' tries to do too many things, most of them poorly, although it 
does a very good job at adding clutter.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-13 Thread bartc

On 13/10/2017 12:49, Peter J. Holzer wrote:

On 2017-10-13 10:37, Steve D'Aprano  wrote:



or written by a dedicated hardware device:

https://en.wikipedia.org/wiki/Programmable_read-only_memory


And in this case there will be a tool which will read the object file
and send the contents of the read-only sections to the device which
writes the ((E)E)PROM.


First time I did this was with a home-made programmer directly connected 
to a keyboard. I had to press the right key to generate the 7-bit 
pattern I wanted (I can't remember what I did about the 8th bit), burn 
it into the current location then step the address counter to the next.


No mistakes were tolerated. It worked.


And finally, the most frequent case: The OS will will read the
executable into RAM, mark those pages from the read-only sections as
read-only in the page table and start it.


Or as I did it, on a home-made computer with two banks of 16KB RAM, one 
bank had the editor, compiler and source code, the other the generated 
code. Just before running it, I would flip a switch to write-protect the 
first bank in case something went wrong. (I didn't have floppies only 
slow, unreliable tape, so things had to be memory-resident as much as 
possible.)


And, actually, even now machines don't have that much control: you 
create a large table of data at runtime, but it is still in writeable 
memory, and accidental or malicious code could write into it.


No matter that the C source may have had a few consts sprinkled about. 
(It's bit like those incredibly annoying anti-piracy messages and videos 
you get on DVDS. No actual pirate would ever see them, only honest 
people who have no intention of copying!)


Even if data is actually in write-protected memory, attempts to write to 
it will cause a crash. On my home-made system, they just did nothing. 
Much more graceful.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-13 Thread bartc

On 13/10/2017 14:16, Chris Angelico wrote:

On Sat, Oct 14, 2017 at 12:00 AM, bartc  wrote:

Even if data is actually in write-protected memory, attempts to write to it
will cause a crash. On my home-made system, they just did nothing. Much more
graceful.


The novice thinks his job is to stop the program from crashing. The
expert knows that a crash is actually far FAR better than silently
doing nothing.



For a novice, seeing 'Segmentation fault (core dumped)' is better?

There, a friendlier, more useful error message is called for ('writing 
into read-only memory' is a good start).


But the idea of having memory which is permanently or temporarily 
write-protected is also useful: you can do what you like to it and it 
won't change, and such an attempt wouldn't necessarily be an error.


For example, you're drawing a series of points or connected lines into a 
window to form a shape. But part of the shape is outside the window. So 
you fix the logic and try again. You don't want it to crash if you gave 
it coordinates (corresponding to memory beyond the window limits) 
outside the boundaries.


It's just a technique, like greying out certain menu options - clicking 
them will do nothing, but you won't get an error message and you don't 
want to allow them anyway, risking more serious consequences.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-13 Thread bartc

On 13/10/2017 14:22, Marko Rauhamaa wrote:


BTW, the original reason for C requiring declarations in the first place
wasn't readability. Rather, it was to make compilation possible in the
first place. It is interesting that C++ and Java have taken steps to
remove such information where the compiler can know or guess it from the
context.



The compiler might be able to, after analysing 100,000 lines of prior 
code and applying complex algorithms.


But what about the poor user reading the code? Or can that now only be 
done with the aid or a browser that analyses 100,000 lines and applies 
that same algorithm?


We mustn't forget the person writing the code, who may have a certain 
type in mind for X, but their (I nearly said 'his') analysis may not 
match the compiler's.


Annotations can be useful.

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-13 Thread bartc

On 13/10/2017 15:59, Julien Salort wrote:

Le 12/10/2017 à 17:57, bartc a écrit :

With a const struct, you are stopped from directly modifying elements, 
but if an element is a pointer, nothing stops you writing to what the 
pointer points to, unless that has a const target too. And then you've 
going to have problems doing normal updates. This constness just 
insinuates itself everywhere.


That is not very different from the mutable/immutable concept in Python, 
is it ?
A tuple is immutable, but if it contains a mutable object, nothing 
prevents you from mutating it.

Does it mean you think the mutable/immutable concept of Python is flawed?


When you put it like that, then yes!

But it depends on how you define the value of a tuple. If that is a 
recursive definition that includes all nested object levels, then it 
would be harder to keep the whole thing constant.


If you look only one level deep, then it can be fully immutable (never 
mind that some elements could be functions that will give a different 
result each time they are evaluated).



--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-13 Thread bartc

On 13/10/2017 16:33, Steve D'Aprano wrote:

On Sat, 14 Oct 2017 01:30 am, Chris Angelico wrote:


For a novice, seeing 'Segmentation fault (core dumped)' is better?


Better than silently doing nothing? YES. Absolutely it is.


Chris, you forget that for Bart, his user-base is only himself. If he programs
his home-made system to silently ignore writes to write-protected memory,
that counts as the "...unless explicitly silenced" part of "Errors should
never pass silently...". If that means his software is riddled with bugs, it
will affect only himself, and no novices will be harmed.


You're making light of a scheme that was extremely effective in a 
computer system with otherwise unprotected memory, that could write 
anywhere, including over all the code and over the OS.


Without that write protection, what would have happened? Either it would 
go completely haywire, or hang, or could subtly change resident programs 
in dangerous ways.


Or I could put that switch in then I could be CERTAIN that essential 
programs and data were untouched no matter what happened.


So if it worked well then without needing to abort and report a message, 
why can't a scheme like that work now?


BTW, when you're developing a new bit of hardware or software, and 
you're not part of team, then the user-base is normally just yourself. 
Nothing wrong with that, but you seem to like belittling people with 
such comments. What was the userbase when GvR started Python?


--
Bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-13 Thread bartc

On 13/10/2017 15:39, Steve D'Aprano wrote:

On Fri, 13 Oct 2017 11:54 pm, Gregory Ewing wrote:


Neil Cerutti wrote:

I can tell at a glance if a parameter is expected to be
modifiable just by looking at the function signature.


The question is why doesn't anyone feel the need to be
able to do that for Python functions? Whether a function
modifies things passed to it is just as important to
know in Python as it is in C.


Lots of people would like Python to have a "freeze" function that can make
immutable objects, it is a moderately common feature request.

Some people (myself included) would like a "const" declaration that gives us
names that can only be bound to once:

const spam = "NOBODY expects the Spanish Inquisition!!!"  # Okay
spam = "foo"  # Error.


Presumably also:

const def f:
const class c:
const import i



I don't mind if that is a runtime error, although a compile time error would
be nicer.


This would be of most use when the byte-code compiler (assuming there is 
one) knows about them. But many will be inside imported modules whose 
contents, AIUI, are not visible to the byte-code compiler.


And then they would be accessed as:

  i.spam

So this would be a const attribute.

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: An endless loop

2017-10-15 Thread bartc

On 15/10/2017 03:10, Stefan Ram wrote:

   I made an error I made a thousand times before.

   I had programmed an endless loop.

   But never did I see before so clear why it's called
   an endless loop. (Tested in IDLE.)

from turtle import *

reset(); reset(); shape( 'turtle' ); showturtle()

def poly( n, length ):
 i = 0
 while i < n:
 forward( length )
 left( 360/n )

poly( 5, 100 )
done()


I assume you're talking about the while-loop (because on my machine, it 
hangs just using 'from turtle...' or 'import turtle').


That looks to be a repeat-N-times loop. There isn't a dedicated 
statement for that, the closest Python feature would be 'for i in 
range(n)' with i a dummy loop variable.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: An endless loop

2017-10-15 Thread bartc

On 15/10/2017 12:20, Chris Angelico wrote:

On Sun, Oct 15, 2017 at 9:15 PM, bartc  wrote:



I assume you're talking about the while-loop (because on my machine, it
hangs just using 'from turtle...' or 'import turtle').


(Machine was screwed up I think, as I had to restart it shortly after 
for other reasons. When the turtle graphics worked.)



That looks to be a repeat-N-times loop. There isn't a dedicated statement
for that, the closest Python feature would be 'for i in range(n)' with i a
dummy loop variable.


You can use that or "for _ in range(n)" as a pretty effective form of
that loop. I've never had a problem with it. Python doesn't need
another type of loop.


I could understand that sentiment if there were already dozens. But I 
believe there's only, what, two loop types? To implement a number of 
basic looping requirements which, if not that numerous, are somewhat 
more than two.


Not exactly taxing the grey matter which already has those extra loop 
types in mind, and has to find a way to express them in terms of only two.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


  1   2   3   4   5   6   7   8   9   10   >