Re: What is not working with my "map" usage?

2018-09-22 Thread ROGER GRAYDON CHRISTMAN
On Sat, Sep 22, 2018, Victor (vhnguy...@yahoo.com) wrote 
Let me use a different input args and display them below.  Basically, I am
hoping to add up all elements of each nested list.  So at first it should start
with [1,11,111] ==> 1+11+111 = 123.  But instead, it appears to take the 1st
element from each nested list to add up [1,2,3] = 6.   How should it be
corrected?  Thx.
>

>> alist = [[1,11,111], [2,22,222], [3,33,333]]
>
>> list(map(add_all_elements,*alist)
>
>


Trylist(map(add_all_elements, alist)) instead.
If you give a map a single list as a second argument, it will visit eachelement
of that single list (which in this case are the sublists you want).
But that * is replacing the single list with the list contents as separate
arguments,so you are literally telling map to visit all three sublists in
parallel,and it does exactly what you told it to.
The * and ** prefixes really should be avoided as much as possible,unless you
know exactly what you are getting out of them.
Roger ChristmanPennsylvania State University


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


Re: Stock quote AP

2018-03-12 Thread ROGER GRAYDON CHRISTMAN

On Mon, Mar 12, 2018 12:00 PM, Irv Kalb wrote:
>
> On Mar 10, 2018, at 9:26 PM, Chris Angelico  wrote:
>> 
>> On Sun, Mar 11, 2018 at 4:18 PM, Irv Kalb  wrote:
>> Hi,
>> 
>> I teach courses on beginning Python (Python3).  In one of my
>topics, I explain how we can write simple programs that reach out to the
>internet and download data (request/response).
>> 
>> I show a number of examples using:   urllib.request.urlopen(
> )  to get things like weather data, currency
>exchange rates, etc.
>> 
>> I just tried my examples again, and they are all working fine, except for
>one.  I had an example where I used the call above to get simple
>(American) stock quotes from Yahoo.  However, with this example, now
>I get a bunch errors.  In tracking it down, I found that Yahoo has shut down
>this public API, discontinued this service.
>> 
>> So ... I am looking for a replacement.  I have done quite a bit of
>searching, but I have not been able to find a simple way to get a stock quote
>(no need for historical data - most recent price is fine).  I have
>found many examples where people have built custom packages for doing this type
>of thing.  However, I am in a college environment, and I cannot install any new
>packages on the computers there.  I've also seen examples of people building
>SQL-style queries to get this type of information, but that's beyond what I am
>trying to teach.
>> 
>> Wondering if anyone has any example of an API where I could just make a
>call using Python Standard Library interfaces to get stock quotes?
>> 
>> 
>> Check out https://www.alphavantage.co/ for something you can query for
>> free. Extensive and amazingly useful. One of my students did some
>> second-tier analysis on the data they provide as a capstone project on
>> stock trading analysis.
>> 
>> You may want to consider, though, modifying the "no new packages"
>> rule. The 'requests' library is WAY better for teaching Python and web
>> APIs than the raw urllib. Get just a small handful of pip-installable
>> packages whitelisted and your life will be better.
>> 
>> ChrisA
>> 
>
>Hi Chris,
>
>Thank you very much for this.  It is very close to what I am looking for.  I
>had seen this early in my searches but I didn't go into it in detail because it
>looked like it was designed to give way more information than I was looking for
>- for example, the first example is about time series data.  
>
>I did look into it today, and I got a free API key to check it out.  It does
>have the ability to give just a stock quote for a symbol, but it looks like the
>minimum I can get back is a csv:
>
>symbol,price,volume,timestamp
>MSFT,96.1800,--,2018-03-09 16:01:30
>
>which is easy enough for me to break apart.  I just wish there was a way to
>eliminate the header line so I wouldn't have to go through an explanation about
>that.  
>
>Thanks very much.  If I can't find another one that just give back a price,
>I'll probably use this one.
>
>Irv
>
>
>


Have you introduced the concepts of dictionaries in your Python course yet?
In my introductory course, I present dictionaries even before if statements and
for loops,
since they have so many very useful features for data manipulation.

That first line in the csv file is perfect for use with a dictionary.
You would just need to get a dictionary Reader from the csv module,

import urllib.request

import io, csv

file = urllib.request.urlopen(site + filename)

data = io.TextIOWrapper(file, newline="", encoding="utf-8")

reader = csv.DictReader(data)

for row in reader:


At this point, you could get your data from row['symbol'], row['price']
If you want to pretend that you don't actually know what the headings are,
you could simply enumerate that row dictionary value, at it will tell
you both the heading the value.   Each line in the file would be a new
dictionary.

Roger Christman
Pennsylvania State University



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


Re: RFC: Proposal: Deterministic Object Destruction

2018-02-28 Thread ROGER GRAYDON CHRISTMAN

On Wed, Feb 28, 2018, Rick Johnson wrote: >
On Wednesday, February 28, 2018 at 5:02:17 PM UTC-6, Chris Angelico wrote:
>
>> Here's one example: reference cycles. When do they get detected?
>> Taking a really simple situation:
>>
>> class Foo:
>> def __init__(self):
>> self.self = self
>
>*shudders*
>
>Can you provide a real world example in which you need an
>object which circularly references _itself_? This looks like
>a highly contrived example used to (1) merely win the
>argument, and (2) Bump fib() up one position from it's
>current position as "the worst introductory example of how
>to write a function in the history of programming tutorials"

If you want something that looks like a real world example,
consider the very common doubly-linked list:
[ 1 ] <---> [ 2 ] <---> [ 3 ] <--.--> [ N ]

This is chock-full of reference cycles, everywhere you see a <-->

Then you have a wrapper List object that has a head referencing
the 1 node and a tail referencing the N node.

And you decide you don't need that List any more.

You could:
1) Take the time the code to carefully delete every single node
in this linked list, taking the time to set all of the internal references to
None, or
2) Just discard your List object, and let the GC take care of the rest.

Note that removing the list alone does not clear any of the 
reference counts in the picture above, because those internal
<--> references are all still there.  You either have to manually
remove all the references, or rely on the garbage collector.

Oh, and for those who claim that reference counting is 'efficient',
do bear in mind that every single assignment statement increases
the reference count of one value and possibly reduces the reference
count of another.  So down in the machine or byte-code world,
every assignment operation is really two arithmetic computations
and three assignments, which takes 5 times as many operations
as not doing any reference counting at all.

So if you have a program that can get by leaving unused memory
allocated, and can still terminate the program before all the memory
is claimed, your reference count system is far less efficient than
relying on a garbage collector that happens to not get activated
before your program ends.

Roger Christman
Pennsylvania State University


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


Re: Python Learning

2017-12-16 Thread ROGER GRAYDON CHRISTMAN

On Sat, Dec 16, 2017, Marko Rauhamaa wrote: >
Chris Angelico :
>
>> On Sat, Dec 16, 2017 at 11:41 PM, Marko Rauhamaa  wrote:
>> r...@zedat.fu-berlin.de (Stefan Ram):
>>   As a start, one should learn:
>>
>> 1.) how to install Python
>> (if not already installed)
>>
>> 2.) how to start the Python console
>> (if not already started)
>>
>> 3.) how to type characters into a line of the
>> console and how to submit the line (using
>> the Enter key) (if this is not already known)
>>
>> A good list. Even more important, though, is the installation, use and
>> understanding of a text editor. What is the difference of MS Word,
>> Notepad and a Python-aware text editor? What text editors are there?
>> What is a newline? What is whitespace? (Advanced: what is a TAB.) What
>> is the difference between lower case and upper case? What is trailing
>> whitespace? What is an underscore? What is the difference between a
>> parenthesis, bracket and a brace?
>>
>> What is a file? What is a filename? What is a directory/folder? What is
>> a pathname? What is a terminal (emulator)? What is standard input? What
>> is standard output?
>>
>> How do I see the listing of files? How do I erase a file? How do I
>> rename a file? What is the current working directory? How do I change it
>> and why?
>>
>> ... at which point you realize that you're deep in TL;DR territory and
>> none of what you mentioned will be even thought about.
>
>Hm. I don't think you can get away from getting acquainted with all of
>the above before you can write your first "Hello, World!" program in
>Python.
>
>It was simpler when I first learned Basic. There were no files, and your
>REPL was your editor. The ingenious line numbers took the role of the
>text editor.
>
>Unfortunately, Python's indentation mechanism makes the REPL too
>frustrating an environment to type in even the simplest of function
>definitions, let alone a whole class.
>
>
>Marko
>


On the contrary, I think I think you can getaway with a lot of those items:
Let's see:

All the stuff about files, folders, directories, etc:

Running the Python IDLE environment that comes for free along with the
free download, creates its own little folder for all the work, saves the files
in that folder, and makes it easy for you to see what is in there, recover
your previous programs, etc.  I have never had any difficulty in using the
File menu to Open a Recent File, etc.

Of course, I assume the ability to obtain the Python environment, that
requires pointing your browser at the appropriate web site, find the
download page, and so on.   I guess I am assuming that most of my 
students have either used the web before, or have downloaded software
(such as their favorite games or apps).   It has been about twenty years
since I felt a need to teach my students how to find the on/off switch.

MS Word, vs. Notepad, vs. vi, vs. Emacs, vs. vs. vs. vs.
Since Python IDLE has its own development environment,
that is sufficient.   And it even addresses the tab vs. space
indentation issues all by itself, and lets you Indent and Dedent
whole blocks of code cleanly and easily.   

So, Hello World is trivial.  In fact, there are two trivial ways to do it
with Python IDLE.

You get the Shell for free, and just type your print call there.

Or you go to the File Menu, Open a new file, type in one statement,
and activate the Run option on the menu bar.

Now, as far as those other items you think impose an excessive
burden on our poor students:

Difference between parenthesis, bracket, and a brace:
These are simple syntactic punctuation, introduced one item at a time.
They should already know about parentheses from even elementary
arithmetic courses, if not basic algebra.
Brackets can be postponed until you are ready to reach about lists.
Braces can be postponed until you are ready to teach about dictionaries.
Put them in their proper context, and then thinking in the proper context
should make the correct choice of punctuation automatic.

"Python's indentation mechanism ... frustrating ...
even the simplest function definitions, let alone a whole class."
When first reading this, I was wondering why you were even 
considering class definitions in a first course.If you find
print("Hello, world!"   to be too complicated for this first course,
how can you expect any meaningful coverage of OOP?

But aside from that, indentation can also be postponed.
I went four-five weeks into my course before needing any indentation
whatsoever.   All the code was straight down top to bottom
with no function definitions, conditional statements, or loops.
I did make use of some short lists and dictionaries, since 
those conveniently have many useful methods defined within them,
so could solve several interesting straightforward problems
without introducing too much of the language.

Oh, and when the time comes, as above, the Python IDLE
environment does a perfectly 

Re: Python Learning

2017-12-16 Thread ROGER GRAYDON CHRISTMAN
On Sat, Dec 16, 2017, Bill wrote:
>
Varun R wrote:
>> Hi All,
>>
>> I'm new to programming, can anyone guide me, how to start learning python
programming language,...plz suggest some books also.
>>
>> Thanks all
>
>Are you sure you want to learn Python first?
>Python does enough things "behind the scene"
>that it makes me question the wisdom of that.
>Other points of view are welcome, of course.
>Learning the primitives of C++ first, may make for an easier transition.
>Surely this has been discussed before?
>


Having taught introductory courses both with C++ and Python
 as first languages, I really think Python is a better choice.

Consider this nice simple Python program:

print('Hello, world!')
How much background does a student need to understand this,
or to produce programs of equivalent complexity?

Do you really want to get into explaining why you need to
refer to the iostream library, consult the std namespace,
and define a function named main, and why it returns zero?

Is any of that really necessary to understand how to print output?


Or by primitives, do you first get into the integer data type,
how to declare variables, and how to do arithmetic (all of which
are nice and primitive and C++) and postpone all input and output
until the third month of the course, after you have had adequate
time to to explain in detail the meanings of function declarations,
namespaces, streams and #include?

>From my experience, both as instructor and student, with
introductory programming courses with half a dozen different
first languages  to use for those courses, I think C++ is one
of the worst choices!   (In my humble opinion, of course)

Roger Christman
Pennsylvania State University

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


Re: Python homework

2017-12-13 Thread ROGER GRAYDON CHRISTMAN
On Wed, Dec 13, 2017, Lorenzo Sutton wrote:
>
On 05/12/17 06:33, nick martinez2 via Python-list wrote:
>> I have a question on my homework. My homework is to write a program in
>which
>> the computer simulates the rolling of a die 50 times and then prints
>> (i). the most frequent side of the die (ii). the
>average die value of all
>> rolls. 
>
>For this kind of problem I think the collections module [1] can be very 
>useful. In this case in particular have a look at the Counter package ;)
>
>Lorenzo.
>
>[1] https://docs.python.org/3.6/library/collections.html
>
>


A nice answer at face value, and for general questions, but
perhaps not the best given the subject line and the first sentence
in the OP's note.

Counting is such a fundamental programming skill, that I expect
whoever teaches this course expects students to know how to
count, without appealing to a third-party object to do all their
work for them.   

When I teach my course, I have no desire to have
all my students turn into cargo cultists.

At least this particular student did post his intended solution,
instead of outright begging for code.  And most of the responses
I see did attempt to work within the perceived constraints 
regarding what language tools the student was expected to use.

Roger Christman
Pennsylvania State University

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


Re: Python-list Digest, Vol 171, Issue 7

2017-12-06 Thread ROGER GRAYDON CHRISTMAN
On Wed, Dec  6, 2017, ssghotra1997 wrote:
import random

def rollDie(num):
sides = {'One':0, 'Two':0,'Three':0,'Four':0,'Five':0,'Six':0}

for i in range(num):
rolls = int(random.randint(1, 6)
if rolls == 1:
sides['One'] += 1
if rolls == 2:
sides['Two'] += 1
if rolls == 3:
sides['Three'] += 1
if rolls == 4:
sides['Four'] += 1
if rolls == 5:
sides['Five'] += 1
if rolls == 6:
sides['Six'] += 1

return sides,max(sides,key=sides.get)

print(rollDie(50)


*** OUTPUT *
({'One': 10, 'Two': 7, 'Three': 7, 'Four': 11, 'Five': 7, 'Six': 8}, 'Four')

You should always be suspicious if any case where you see identical
or nearly-identical code duplicated more than three times, because that
strongly suggests that there is a much better way that avoids such 
code duplication.

This problem of identifying a most frequent die roll could be applicable
to imaginary dice of any size, since the concept would e the same.
Imagine how much tedious work you would have to do if the question
was about a 20-sided die or a 34-sided die!

Of course, there is the special feature here of using words ('One', 'Two'..)
to stand for the numbers, but even those could be addressed very neatly
with a hand data structure and no code complexity.

It might not make much difference for a homework assignment of this
size at this point in your curriculum.  But later on, you would pay a heavy
price for choosing implementations that require 5, 10, or 20 times as much
code as necessary.   The increase in program size would have a multiplicative
effect on writing time and debugging time and would have an adverse affect
on a course grade, product delivery date, customer satisfaction, and
job security.

So learn how to find the efficient solutions now while you still have
instructors around to help you.

Roger Christman
Pennsylvania State University


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


Re: Python-list Digest, Vol 171, Issue 7

2017-12-06 Thread ROGER GRAYDON CHRISTMAN
I think I also came up with 4 as "the most frequent number". 
It is unclear ot me how you came up with 3.36 as the most common number,
because I tried rolling a six-sided die myself several times,
and somehow 3.36 didn't come up even once!

On Wed, Dec  6, 2017, D'Arcy Cain wrote:
>
On 12/05/2017 07:33 PM, nick.martinez2--- via Python-list wrote:
>> I have a question on my homework. My homework is to write a program in which
the computer simulates the rolling of a die 50
>> times and then prints
>> (i). the most frequent side of the die
>> (ii). the average die value of all rolls.
>> I wrote the program so it says the most frequent number out of all the rolls
for example (12,4,6,14,10,4) and will print out "14" instead of 4 like I need.
>
>How did you come up with 4?  I come up with 3.36 with those numbers.
>

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


Re: Python-list Digest, Vol 170, Issue 34

2017-11-27 Thread ROGER GRAYDON CHRISTMAN
I'll answer your question with a couple questions:

Why do you expect to get the results you seem to expect?

What part of your code should repeat (and why)?

A key factor in recognizing the difference between 'if' and 'while' is knowing
what effect they have on the indented statements that follow them.

Roger Christman
Pennsylvania State University

On Mon, Nov 27, 2017 Cai Gengyang wrote:
>

>Message: 38
>Date: Mon, 27 Nov 2017 04:54:21 -0800 (PST)
>From: Cai Gengyang 
>Subject: While, If, Count Statements
>Message-ID: 
>Content-Type: text/plain; charset="UTF-8"
>
>
>Input :
>
>count = 0
>
>if count < 5:
>  print "Hello, I am an if statement and count is", count
>
>while count < 10:
>  print "Hello, I am a while and count is", count
>  count += 1
>
>Output :
>
>Hello, I am an if statement and count is 0
>Hello, I am a while and count is 0
>Hello, I am a while and count is 1
>Hello, I am a while and count is 2
>Hello, I am a while and count is 3
>Hello, I am a while and count is 4
>Hello, I am a while and count is 5
>Hello, I am a while and count is 6
>Hello, I am a while and count is 7
>Hello, I am a while and count is 8
>Hello, I am a while and count is 9
>
>The above input gives the output below. Why isn't the output instead :
>
>Hello, I am an if statement and count is 0
>Hello, I am a while and count is 0
>Hello, I am an if statement and count is 1
>Hello, I am a while and count is 1
>Hello, I am an if statement and count is 2
>Hello, I am a while and count is 2
>Hello, I am an if statement and count is 3
>Hello, I am a while and count is 3
>Hello, I am an if statement and count is 4
>Hello, I am a while and count is 4
>Hello, I am a while and count is 5
>Hello, I am a while and count is 6
>Hello, I am a while and count is 7
>Hello, I am a while and count is 8
>Hello, I am a while and count is 9
>
>

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


Re: Python-list Digest, Vol 170, Issue 34

2017-11-27 Thread ROGER GRAYDON CHRISTMAN
I'll answer your question with a couple questions:

Why do you expect to get the results you seem to expect?

What part of your code should repeat (and why)?

A key factor in recognizing the difference between 'if' and 'while'
is knowing what effect they have on the indented statements 
that follow them.

Roger Christman
Pennsylvania State University

On Mon, Nov 27, 2017 Cai Gengyang wrote:
>

>Message: 38
>Date: Mon, 27 Nov 2017 04:54:21 -0800 (PST)
>From: Cai Gengyang 
>Subject: While, If, Count Statements
>Message-ID: 
>Content-Type: text/plain; charset="UTF-8"
>
>
>Input :
>
>count = 0
>
>if count < 5:
>  print "Hello, I am an if statement and count is", count
>
>while count < 10:
>  print "Hello, I am a while and count is", count
>  count += 1
>
>Output :
>
>Hello, I am an if statement and count is 0
>Hello, I am a while and count is 0
>Hello, I am a while and count is 1
>Hello, I am a while and count is 2
>Hello, I am a while and count is 3
>Hello, I am a while and count is 4
>Hello, I am a while and count is 5
>Hello, I am a while and count is 6
>Hello, I am a while and count is 7
>Hello, I am a while and count is 8
>Hello, I am a while and count is 9
>
>The above input gives the output below. Why isn't the output instead :
>
>Hello, I am an if statement and count is 0
>Hello, I am a while and count is 0
>Hello, I am an if statement and count is 1
>Hello, I am a while and count is 1
>Hello, I am an if statement and count is 2
>Hello, I am a while and count is 2
>Hello, I am an if statement and count is 3
>Hello, I am a while and count is 3
>Hello, I am an if statement and count is 4
>Hello, I am a while and count is 4
>Hello, I am a while and count is 5
>Hello, I am a while and count is 6
>Hello, I am a while and count is 7
>Hello, I am a while and count is 8
>Hello, I am a while and count is 9
>
>

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


Re: Problem in defining multidimensional array matrix and regression

2017-11-19 Thread ROGER GRAYDON CHRISTMAN
On Sun, 19 Nov 2017, shalu.ash...@gmail.com wrote: >
Hi, All,
>
>I have 6 variables in CSV file. One is rainfall (dependent, at
>y-axis) and others are predictors (at x). I want to do multiple
>regression and create a correlation matrix between rainfall (y) and
>predictors (x; n1=5). Thus I want to read rainfall as a separate
>variable and others in separate columns, so I can apply the algo. However, I am
>not able to make a proper matrix for them. 
>
>Here are my data and codes?
>Please suggest me for the same.
>I am new to Python.
>
>RF P1  P2  P3  P4  P5
>120.2350.234   -0.012  0.145   21.023  0.233
>200.14 0.512   -0.021  0.214   22.21   0.332
>185.3620.147   -0.32   0.136   24.65   0.423
>201.8950.002   -0.12   0.217   30.25   0.325
>165.2350.256   0.001   0.2231.245  0.552
>198.2360.012   -0.362  0.215   32.25   0.333
>350.2630.98-0.85   0.321   38.412  0.411
>145.25 0.046   -0.36   0.147   39.256  0.872
>198.6540.65-0.45   0.224   40.235  0.652
>245.2140.47-0.325  0.311   26.356  0.632
>214.02 0.18-0.012  0.242   22.01   0.745
>147.2560.652   -0.785  0.311   18.256  0.924
>
>import numpy as np
>import statsmodels as sm
>import statsmodels.formula as smf
>import csv
>
>with open("pcp1.csv", "r") as csvfile:
>readCSV=csv.reader(csvfile)
>
>rainfall = []
>csvFileList = [] 
>
>for row in readCSV:
>Rain = row[0]
>rainfall.append(Rain)
>
>if len (row) !=0:
>csvFileList = csvFileList + [row]   
>
>print(csvFileList)
>print(rainfall)
>
>Please suggest me guys
>Thanks
>


There seems to be a conceptual disconnect here.
Do you happen to know what the letters C,S,V
stand for in CSV file?   Because I don't see any C's
in your data, and I don't see anything in your code
to use anything other than C to S your V's.

I'm thinking that is the first place you should look.
You could either modify your data file (with a nice global replace/change)
or you could give a different value to one of the default parameters
to the functions you use to open the file.

Roger Christman
Pennsylvania State University


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


Re: Shoulid constants be introduced to Python?

2017-11-16 Thread ROGER GRAYDON CHRISTMAN
On Thu, Nov 16, 2017, Saeed Baig wrote:
>
Message: 7
>Date: Thu, 16 Nov 2017 17:16:11 +1100
>From: Saeed Baig 
>To: python-list@python.org
>Subject: Should constants be introduced to Python?
>Message-ID: <5d4da7b2-504a-4a3a-bace-ffadea1d2...@icloud.com>
>Content-Type: text/plain;  charset=utf-8
>
>Hey guys I am thinking of perhaps writing a PEP to introduce constants to
>Python. Something along the lines of Swift?s ?let? syntax (e.g. ?let pi =
>3.14?).
>
>Since I?m sort of new to this, I just wanted to ask:
>- Has a PEP for this already been written? If so, where can I find the
>link/info to it?
>- Do you guys think it would be a good idea? Why or why not? Do you think
>there?s a better way to do it? I?d like to know what others think about this
>idea before making any formal submission.


Well, pi already does have a value:

>>> import math

>>> math.pi

3.141592653589793

but it's not a constant in the sense you are looking for:

>>> math.pi = 2

>>> math.pi

2



The only PEP I saw that makes any mention of constants is the PEP 8 Style Guide,
which recommends all constants be named with all caps, such as "math.PI".
(Why the math module doesn't do that beats me, unless it is there for
hyster^H^H^H^H^Historical reasons.)

But certainly if we saw code like this:

AVOGRADO_NUMBER = x + 2

I would believe that code to be 'obviously' since it is clearly attempting to
modify
a constant -- and the naming convention tells me so.

Do you have any particular reason you wish to promote constants?
Is it anything beyond "because C++ and Java, etc. have them"?

Because do note all of those constants in those languages are *declared*
to be constants, and declarations (esp variable declarations) are notably
absent.
I took a peek at the PEP 484 about Type Hints, and I didn't see anything there
about constants either.

So if you want to make a proposal, I think you should provide a compelling
argument in favor of a name change.   Suggesting that an interpreted language
have all the features of a compiled language just does not seem to be sufficient
cause.   After all:

Python pretends to have 'private' and 'protected' data, by having 'hidden'
variables with leading underscores, but they really are none of the above.

Python claims to have immutable data types, but those immutable data types
may contain mutable elements, which are indeed quite mutable.

Python does range checking on list indexes, but will not at all complain if
your code accidentally goes one step before [0] and ends up at [-1].

Python allows these loopholes in with the expectation that the programmer
should know better.   I think the same thing would be true with constants.

If you need this crutch to protect yourself from accidentally clobbering
constants,
then do better.   If you only need it to for documentation purposes, just tweak
the documentation.

Roger Christman
Pennsylvania State University

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


Re: Ideas about how software should behave

2017-11-09 Thread ROGER GRAYDON CHRISTMAN

On Thu, Nov 9, 2017, Gregory Ewing wrote:>
But ideas are not software -- they don't actively
>*do* anything, so trying to anthropomorphise them
>doesn't really work. 


Generally true.   I just remember the notable exception:

Colorless green ideas sleep furiously.

That case of anthropomorphism works just as well as it was intended.

As far as this whole thing about criticism being taken personally,
I just can't get a certain sketch out of my head:

".. but I came here for an argument!"
"Oh, oh!  I'm sorry!  This is abuse!... You want room 12A next door."

It is hard to tell the difference sometimes.

But on this count, I would still try to find the distinction about
whether a particular idea seems to ridiculous, or arrogant, as
an anomalous statement from the presenter vs. it being 
representative of a regular pattern.   I think many of the posters
here appear commonly enough to place the spirit of a particular
post in the context of their general presentation style.

Roger Christman
Pennsylvania State University
On Thu, Nov  9, 2017, Gregory Ewing wrote:But ideas are not software -- they
don't actively
*do* anything, so trying to anthropomorphise them
doesn't really work. 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: replacing 'else' with 'then' in 'for' and 'try'

2017-11-06 Thread ROGER GRAYDON CHRISTMAN
Just a little two-cent opinion from the peanut gallery:


I've been following all the discussion on this go by, sometimes getting

a bit heated at times, and just sitting nice and safe and secure in my

little ivory tower, where I simply tell my students to not use 'break'.


As a stodgy educator, I usually restrict them for these two reasons:

1) the loop condition should describe your expected loop conditions, and

2) the exception handling structure allows more control over where

 the exceptional circumstances will be handled (including which function)


When it comes to searching an iterable collection, my ivory-tower

view point tells me that the looping condition is based on whether the

item is found, and is not a for loop traversing the entirety.

To me, that is the 'one obvious way to do it'


If I expect the item will be found, but fear that it will not, I can always
compare

a subscript to len(), or if that seems too hard, catch the StopIteration
exception.

I only recommend the for loop when the true expectation is to visit

the entire collection (which can later be moderated with iter's sentinel

parameter, or some of the filters in itertools)


And I see that simply removing 'break' from my vocabulary, this

whole 'else on a loop' issue completely dissolves.


So thank you for, even unintentionally, helping me to feel good

about living inside my ivory tower!


Roger Christman

Pennsylvania State University
-- 
https://mail.python.org/mailman/listinfo/python-list


FW: Reading a remove csv file

2017-11-02 Thread ROGER GRAYDON CHRISTMAN
I have a partial answer to my own question:
This seems to work for me:

---
link = urllib.request.urlopen(urlpath)
data = link.read().decode('utf-8').split('\n')

reader = csv.DictReader(data)
for row in reader:
---

I think here my concern is that now 'data' is now a variable
in my program's memory (all of the data),
instead of streamlike.   I suppose I did read
somewhere about setting a stream option.

Roger Christman
Pennsylvania State University

 Forwarded Message 


 Just a quick question on how best to read a remote CSV
file.


So far, I
tried:




filelink =
urllib.request.urlopen(path)


dictread =
csv.DictReader(filelink)


for row in
dictread:
...


But I'm running
into the difference between strings and bytes.


I'd
like to squeeze a note that talks about the utf-8
encoding,


but although I find that as an option for a
local file (with open())


I did not see that on my
first glance at the two functions
above.




Is there an easy way to read a
remove CSV file with utf-8 encoding


without copying
the whole file locally first?




Roger
Christman


Pennsylvania State University
-- 
https://mail.python.org/mailman/listinfo/python-list


Reading a remove csv file

2017-11-02 Thread ROGER GRAYDON CHRISTMAN
 Just a quick question on how best to read a remote CSV file.
So far, I tried:

filelink = urllib.request.urlopen(path)
dictread = csv.DictReader(filelink)
for row in dictread:...
But I'm running into the difference between strings and bytes.
I'd like to squeeze a note that talks about the utf-8 encoding,
but although I find that as an option for a local file (with open())
I did not see that on my first glance at the two functions above.

Is there an easy way to read a remove CSV file with utf-8 encoding
without copying the whole file locally first?

Roger Christman
Pennsylvania State University
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: why it append one more letter after decode?

2017-10-30 Thread ROGER GRAYDON CHRISTMAN
On Sun, Oct 29, 2017 11:06 PM, Ho Yeung Lee wrote:
>
if run these function to decode in python interactive console,
>it can decode correct, 
>
>but when run with a big project, it append a letter Y
>
>
>On Monday, October 30, 2017 at 9:48:36 AM UTC+8, Ho Yeung Lee wrote:
>> def leftrotate(l, n):
>> return l[n:] + l[:n]
>> 
>> def rightrotate(l, n):
>> return l[-n:] + l[:-n]
>> 
>> def encode(s, k, kk):
>> l = [ord(i) for i in s]
>> return leftrotate(''.join([chr(i + k) for i in l]), kk)
>> 
>> def decode(s, k, kk):
>> l = [ord(i) for i in rightrotate(s, kk)]
>> return ''.join([chr(i - k) for i in l])
>> 
>> 
>> yesterday i add above code and run it with batch file 
>> it can decode a correct password
>> 
>> then i install cx_freeze to produce executable file
>> 
>> but today when i run it, i see the source of encrypted password is correct
>> but the decode one, it append one more letter Y at the end of string
>> 
>> why?
>> is cx_freeze change the source python 2.7?
>
>i discover when 
>it 
>decode("\\",1,2)
>in interactive console
>is [
>
>but decode in big project
>it see as
>decode(r"\\",1,2)
>[[
>
>it double
>
>


My first inclination is that the data could have changed.
For example, obtaining a string from the keyboard using input()
would suppress the carriage return.   But obtaining
a string from a file might preserve the carriage return
at the end of the line.   I could imagine then that the
extra carriage return contributed an extra character to your data.

But then I see you had an example with "\\" in one case,
and r"\\" in the other case.  These are not equal to each other,
and naturally would not give equal results from your function.

So that leads to the second possibility that you are not calling
the function in the same way.

In either case, you cannot blame the function for giving you
different results if you give it different data.

Roger Christman
Pennsylvania State University 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Coding style in CPython implementation

2017-10-29 Thread ROGER GRAYDON CHRISTMAN
NOTE:   The case in question was never comparing to True;  it was comparing to
NULL.

There is no "No: if x == None" below, because None is not Boolean.
Similarly comparing a pointer to NULL is not the same as comparing it to a
Boolean.

So I would favor the "Explicit is better than Implicit" in the example cited.

Roger Christman
Pennsylvania State University

On Sun, Oct 29, 2017, Setfan Ram wrote: >
=?UTF-8?B?zqPPhM6tz4bOsc69zr/PgiDOo8+Jz4bPgc6/zr3Or86/z4U=?=
 writes:
>>I guess the following parts from "Zen of Python" apply to this case:
>
>  If we would agree to apply Python rules to C,
>  then we could also use this excerpt from PEP 8:
>
>|o Don't compare boolean values to True or False using ==.
>|
>|Yes:   if greeting:
>|No:if greeting == True:
>|Worse: if greeting is True:
>
>

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


Just a quick question about main()

2017-10-27 Thread ROGER GRAYDON CHRISTMAN
While teaching my introductory course in Python, I occasionally see
submissions containing the following two program lines, even before
I teach about functions and modules:

if __name__ = '__main__':
...  main()

When I ask about it, I hear things like they got these from other instructors,
or from other students who learned it from their instructors, or maybe
from some on-line programming tutorial site.

I'm all on board with the first of these two lines -- and I teach it myself
as soon as I get to modules.

My question is more about the second.

Do "real" Pythonista's actually define a new function main() instead
of putting the unit test right there inside the if?

Or am I correct in assuming that this main() is just an artifact from
people who have programmed in C, C++, or Java for so long that
they cannot imagine a program without a function named "main"?

I guess I'm not stuck on that habit, since my programming experiences
go way back to the old Fortran days


Roger Christman
Pennsylvania State University
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Save non-pickleable variable?

2017-10-21 Thread ROGER GRAYDON CHRISTMAN
On Sat, Oct 21, 2017, Israel Brewster wrote: >
tldr: I have an object that can't be picked. Is there any way to do a
>"raw" dump of the binary data to a file, and re-load it later?
>

>Details: I am using a java (I know, I know - this is a python list. I'm
>not asking about the java - honest!) library (Jasper Reports)
>that I access from python using py4j (www.py4j.org
>). At one point in my code I call a java
>function which, after churning on some data in a database, returns an object
>(a jasper report object populated with the final report data) that I
>can use (via another java call) to display the results in a variety
>of formats (HTML, PDF, XLS, etc). At the time I get the object back,
>I use it to display the results in HTML format for quick display, but the user
>may or may not also want to get a PDF copy in the near future. 
>
>Since it can take some time to generate this object, and also since the data
>may change between when I do the HTML display and when the user requests a PDF
>(if they do at all), I would like to save this object for potential
>future re-use. Because it might be large, and there is actually a fairly good
>chance the user won't need it again, I'd like to save it in a temp file
>(tat would be deleted when the user logs out) rather than in memory.
>Unfortunately, since this is an object created by and returned from a java
>function, not a native python object, it is not able to be pickled (as the
>suggestion typically is), at least to my knowledge.
>
>Given that, is there any way I can write out the "raw" binary data to
>a file, and read it back in later? Or some other way to be able to save this
>object? It is theoretically possible that I could do it on the java side, i.e.
>the library may have some way of writing out the file, but obviously I wouldn't
>expect anyone here to know anything about that - I'm just asking about the
>python side :-)
>
>

Since you suggest a file is a suitable medium, perhaps you can try the JSON
format
I have heard about (but never actually used myself).   Apparently there is
module
support for both Java and Python for this format, which is considered to be
language
independent.

And since the Python view of this data would be a Python data structure,
it should also be pickleable.

The "Json.org" web site should give you a place to download the modules
you would need for each of the two languages.  Hope this helps.

Roger Christman
Pennsylvania State University


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


Re: Lies in education [was Re: The "loop and a half"]

2017-10-13 Thread ROGER GRAYDON CHRISTMAN
On Sat, Oct 14, 2017, Gregory Ewing wrote:
>
Message: 5
>Date: Sat, 14 Oct 2017 01:54:49 +1300
>From: Gregory Ewing 
>To: python-list@python.org
>Subject: Re: Lies in education [was Re: The "loop and a half"]
>Message-ID: 
>Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>
>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.
>


I'm just trying to put myself in the position of the programmer
who is in this position of identifying the modifiable parameters
in the function signature.

Where are you getting the function signature?

Are you looking at the source code?   Or from the help() that access the module?

In both cases, the docstring is an easy solution.
The documentation itself in certainly state whether it modifies any parameter.
And it is directly visible along with the function signature either way.

We don't need any annotations or attributes or whatnot if we have
the perfectly normal function documentation.

Or is that kind of habit no longer practiced in 'the real world'?

Roger Christman
Pennsylvania State University


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


Re: Python-list Digest, Vol 169, Issue 23

2017-10-12 Thread ROGER GRAYDON CHRISTMAN
The opinions I give in this post are not as strong as
the opinions I expressed before about the loop claiming
to count all the way to 2**64.   But I'll give them anyway.

I don't mind having return's inside an if statement, when
the function ends with that if statement.   It becomes very clear
then that there is a choice of possible results, and that exactly
one of those choices apply.

def foo():
... if condition:
.. return 1
... else
.. return 2

I would expect this to be the same as the "# with multiple exits"
with a possibly very minor increase in clarity.

I have used several IDE's that let you mask out chunks of code
based on their indentation level.   Sometimes I use that concept
as an estimate of readability (minimizing how much a reader 
has to look at to understand the structure of the code.
Contrast my multiple-exit with the one I quoted:

def foo(): def foo():
if (condition) if (condition0
[...][...]
else: return 2
[...]

If someone was only reading lines indented once, and skimming the rest as
details unimportant to the structure, he might have a misleading assumption 
about the return value in the code on the right.On the left, he would look
be forced to look one level deeper to find the return's, and find two outcomes.

This same level-of-indentation measure also argues against break and continue,
since statements would also be further indented, which might make them easier
to miss.

But, in any case, I do not mind multiple return's clearly marked with if/else.

On the other hand, I still recommend against return statements inside of loops.
It shouldn't be hard to find the appropriate way to leave the loop, and return
afterwards.   My position is also in line with one of my hard and fast rules for
early programming students:

Rule:  If the operation does not repeat, do not put it into a loop.

I don't even make an exception for return statements.   And my justification
for not making an exception is not only to simply the pedagogy
(absolutism is much easier to explain), but also goes along with the
other maxim:

The code should be obvious!

There are just so many times when I see students expect a return
statement within a loop to be able to return more than one value.
It happens both when reading code, and when writing code,
and even happens for upperclassmen, who should know better.
Clearly, if such a misinterpretation is prevalent, the code is not obvious.

And that's even ignoring the benefit of being able to
set a breakpoint at the very bottom of a function when debugging.

Roger Christman
Pennsylvania State University


On Thu, Oct 12, 2017 12:26 AM, Steve D'Aprano wrote:
>

>
>Message: 3
>Date: Thu, 12 Oct 2017 12:26:07 +1100
>From: Steve D'Aprano 
>To: python-list@python.org
>Subject: Re: Looping [was Re: Python and the need for speed]
>Message-ID: <59dec4b0$0$14935$b1db1813$d948b...@news.astraweb.com>
>Content-Type: text/plain; charset=utf-8
>
>
>But from the point of view of the subroutines, the rule "one exit" is
>like the
>rule "no break" for loops: it makes the code more complex and less
>efficient.
>If you're done, you're done, and you might as well return out of the function
>rather than write boilerplate code to pad it out until you get to the very
>end. With only a single condition to test, there's not much difference
>between the two:
>
># with single exit  # with multiple exits
>def foo():  def foo():
>if condition:   if condition:
>result = 1  return 1
>else:   return 2
>result = 2
>return result
>
>
>but as the number of decision points increase, the complexity required to keep
>a single exit also increases.
>  
>
>

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


Re: Python-list Digest, Vol 169, Issue 23

2017-10-12 Thread ROGER GRAYDON CHRISTMAN
On Thu, Oct 12, 2017 08:05 AM, Steve D'Aprano wrote:>
On Wed, 11 Oct 2017 10:57 pm, Stefan Ram wrote:
>
>>  FWIW, in is book "Touch of Class" (2009) Bertrand
>Meyer writes:
>> 
>> |Such instructions are just the old goto in sheep's clothing.
>> |Treat them the same way as the original:
>> |
>> |/Touch of Methodology/:
>> | Sticking to one-entry, one-exit building blocks
>> |Stay away from any "break" or similar control mechanism.
>
>I have a great deal of respect for Meyer, but in this case I think he has it
>badly wrong on both counts (`break` and "one-entry,
>one-exit").
>
>Unrestricted GOTO (as in BASIC, circa 1970, where you could jump to any
>line
>in the code, or as in assembly) is rightly considered harmful (albeit
>necessary in assembly). But if Meyer means *any* sort of jump
>("similar
>control mechanism"), then that would rule out not just `break` and
>`continue`
>but also:
>
>* while loops
>* for loops
>* if...else
>* case/switch statements
>* calling subroutines (functions or procedures)
>* exception handling
>
>Remember that a function call is basically a GOTO in disguise: execution jumps
>to the function, and jumps back when the function returns. In BASIC, there
>was a GOSUB intermediate between a GOTO and a procedure call.
>
>Surely Meyer doesn't mean to say we should never call functions or use
>`while`, `for` or `if`. So he has to distinguish between kinds of jumps:
>
>Good jumps (I presume):
>
>* function calls
>* if...else
>* looping
>
>Evil jumps:
>
>* unrestricted BASIC-style GOTO/GOSUB any line number
>* break/continue
>
>Not sure:
>
>* GOTO where there are restrictions on where you can jump
>* COMEFROM
>
>(I kid: I'm sure Meyer would oppose COMEFROM, and I expect that even
>Pascal-style restricted GOTO would be on his "evil" list to
>avoid.)

This seems like a veritable straw man if any.
I am fairly sure that "one entry, one exit"
does not precisely mean "no branching whatsoever"
Nor does discouraging unrestricted GOTO
suggest that either.

Clearly a while or for loop without break i
is single-entry and single exit.
The if-else has a clear single entry at the test condition,
and a single exit could be imagined at the program
point immediately after the if-else., etc.

The case/switch does have a single exit in the same
way as the if.   Unfortunately, it does in itself sort of
violate the single entry idea when a break does not
precede the next case.
That just leaves the multiple returns in a functionand the exception handling.
>So the question becomes, why are such harmless, simple to understand,

innocuous jumps like `break` and `continue` in the evil list, when they not

only simplify code but make it more efficient?


# with break

for i in range(2**64):
if isprime(i):
print(i, "is prime")
break


# without break
still_searching = True
for i in range(2**64):
if still_searching and isprime(i):
print(i, "is prime")
still_searching = False

# without break, attempt number 2
still_searching = True
i = 0
while still_searching and i < 2**64:
if isprime(i):
print(i, "is prime")
still_searching = False


# without break, the way it should be:
i = 0
while not isprime(i):
... i = i+1
print(i, "is prime")

I believe this is far simpler _and_ more efifcient than
any of your answers above.   

Do you really believe that there are no prime numbers
less than 2**64?   Can you imagine any circumstance
when "i < 2**75" would become false in this application?
Can you really claim that a solution is more efficient
when it repeatedly tests a condition that can never
posslbly be false?

That is the biggest objection programming teachers

like me dislike the break statement -- it leads to very
careless programming.   Once you imagine that you will
use a break to exit your loops, you might stop thinking
about what your loop conditions are.  And then you find
yourself in a corner where the only way out is to break.

It's like:  I know that I can always call a tow truck
whenever my car runs out of gas on the highway,
so I'll no longer bother checking or filling my tank.
I'll just drive until I'm beyohd fumes, break down,
call a tow, and then tell my boss how I was unavoidably
late because I broke down on the highway.

Ironically, after telling us to stick to code with one entry and one exit,
Meyer then contradicts himself by recommending exceptions:

> |You can use exception handling as a technique of last resort
> |to handle unexpected events for which the normal control
> |structures let you down.

Even more ironically, exception handling is most similar to a COMEFROM, which
was invented as a joke.

The exception handler itself has one entry (the exception)
and one exit.  And, unlike goto's and set_jmp()
is easiliy incorporated into other control structures
depending on where you want to go after any recovery steps.

The code that generated the exception, of course, seemingly
has more than one 

Re: how to replace multiple char from string and substitute new char

2017-10-12 Thread ROGER GRAYDON CHRISTMAN
On Thu, Oct 12, 2017, Iranna Mathapati wrote:
>

>Hi Team,
>
>
>How to replace multipal char from string and substitute with new char with
>one line code
>
>Ex:
>
>str = "9.0(3)X7(2) "  ===>  9.0.3.X7.2
>
>need to replace occurrence of '(',')' with dot(.) chars
>
>output:
>
> 9.0.3.X7.\



My first gut response was to key on the words "replace" and "string"
and think there is a very handy method already existing that can
help with that.   It would be one line of code, if you don't mind having
wo function calls in that one line of code.

If you want only one function call and you want to do even more
substitutions than just those below, there is another handy functionin the
string object that can do so very nicely.

What did you try?

Roger Christman
Pennsylvania State University
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-11 Thread ROGER GRAYDON CHRISTMAN
Actually, FORTRAN and COBOL and Algol (for its control structures)
Trying to support both of the first two was entertaining --
when you declared a variable, it wasn't enough to say it was an Integer:
you had to also declare whether it was represented in Binary or Decimal,
and also specify the desired precision.

The IBM/360 architecture supported both binary and decimal integers,
where the decimals were stored as BCD nybbles of arbitrary fixed length
(as opposed to binary integers matching the machine word size)

The world migrated away from PL/I back in those days because of
the one-size fits none consequences of trying to do everything.
So I always find myself looking askance when language designers
try to repeat the exercise.

You know, like designing a largely-interpreted object-oriented
language with libraries supporting a functional programming style.
I think I've seen a language like that somewhere around this forum.

But I like it anyway

Roger Christman
Pennsylvania State University

On Wed, Oct 11, 2017 12:07 PM, Dennis Lee Bieber wrote:
>
On Wed, 11 Oct 2017 00:21:46 -0400, Bill 
>declaimed the following:
>
>>PL-I has already been taken.  That is a pretty free-wheeling language 
>
>   I think I once heard PL-1 described as trying to combine FORTRAN and
>COBOL...
>
>
>

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


Re: Pedagogical style [was Re: The "loop and a half"]

2017-10-06 Thread ROGER GRAYDON CHRISTMAN
On Thu, Oct  5, 2017 8:18 PM, Ben Bacarisse  wrote:
>
Steve D'Aprano  writes:
>
>> There's no link to the original paper, only to secondary sources that discuss
>> it, e.g.:
>>
>> http://phys.org/pdf128266927.pdf
>
>
>> [1] Anecdotes are not data, but for what it is worth, just in the last two
>> days I came across two examples of this. Teaching a boy in Year 10 maths
>> about logarithms, he struggled with purely algebraic questions involving
>> solving exponential equations by using logs, but when given a concrete
>> problem involving an investment he was able to solve it immediately.
>>
>> The second example involved a girl in Year 8 maths, who again struggled with
>> abstract questions about adding and multiplying fractions. In particular, she
>> overgeneralised from fraction multiplication to addition, thinking that 1/4 +
>> 1/4 must add to 2/8. But when put into concrete geometric terms, showing
>> physical shapes divided into quarters, she could instantly tell that 1/4 plus
>> 1/4 must be 1/2.
>>
>> As I said, anecdotes are not data, but when research claims to show that
>> apples fall upwards in contradiction to anecdotal evidence that they fall
>> downwards, we would be wise to be cautious before accepting the research as
>> fact.
>
>I think the paper is this one:
>
>http://faculty.psy.ohio-state.edu/sloutsky/pdf/KSH-published.pdf
>
>(You can find more recent papers by searching the Ohio State University
>site.)
>
>>From what I've read, your anecdotes are not in contradiction to the
>paper's claims.
>
>


Thank you for finding the paper, since I too was skeptical that
the abstraction-first approach would really he profitable.
I remember all those years in the public schools where
everyone dreaded the 'word problems' in the math text.
The abstractions rarely translated intuitively into the concrete
for many of my classmates.

And after reading this paper, I remain skeptical about its results.
I cannot help but think that the experiment it constructs is inherently flawed.

The claim is that this is an exercise in equivalence classes, obeying the same
rules as modulo-3 arithmetic.  There is the symbolic abstract model with the
circles and diamonds, the fabricated children's game, and the 'concrete'
problems with the liquid containers (shown in the paper), tennis balls, and
pizza slices (not explicitly described).

The paper argues that those who were given the concrete models to start
with did not understand the children's game, simply because they could
not transfer their knowledge to the new environment without the abstract
thought.

That's not a flaw in the student; that's a flaw in the model.

Looking at the liquid picture, one can very easily see the concrete values
1, 2, and 3, and can easily recognize the modular arithmetic involved.
It sounds to me that the same thing would be true for the tennis balls and
pizza slices.   And then he tells this group that the children's game is 
exactly analogous to what they have already experienced.

So here they are, all ready to do some more modulo-3 addition, and
the rug gets pulled out from under them.There is no visible quantity
of 1, 2, or 3 in those circles and diamonds; and probably no 1, 2, or 3
in the children's game either.

How is it any surprise that they did not figure out the children's game
as quickly?

Roger Christman
Pennsylvania State University 


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


Re: Introducing the "for" loop

2017-10-06 Thread ROGER GRAYDON CHRISTMAN

On Thu, Oct  5, 2017 7:45 PM, breamore...@gmail.com wrote:
>
On Friday, October 6, 2017 at 2:05:58 AM UTC+1, Irv Kalb wrote:
>>  
>> The range function is discussed after that.
>>  
>
>FWIW range isn't a function in Python 3.  From
https://docs.python.org/3/library/functions.html#func-range "Rather than being
a function, range is actually an immutable sequence type, as documented in
Ranges and Sequence Types ? list, tuple, range.".
>
>
>


Despite the documentation, I would still be tempted to say that range is a
function.
Taking duck-typing to the meta-level, every time I use range, I use its name
followed
by a pair of parentheses enclosing one to three parameters, and I get back an
immutable sequence object.   It sure looks like a function to me.

I would similarly say that map is a function, or an iterator generator I write
myself
with yield statements is a function, both of which also return sequences.
It is not clear to me what the difference really is between my conception
and the official definition -- is it a question about whether it returns a
first-class object?

Or more simply, what is the clear and obvious distinction that I can give to my
non-scientific laypeople about why range isn't a function, if it looks like one?

Oh, and since I think this was snipped from the thread mentioning textbook
usage,
I'll just toss in my note that I am using an on-line textbook developed by
zyBooks.com,
and those guys are nice enough to actually collaborate with the instructor about
what goes into the text, and in what order.

I actually like that they choose to present lists and dictionaries before any
control 
structures, because a lot of interesting simple programming problems can be
solved
by making use of those structures -- like simple table-lookup applications.

A C++ teacher really cannot present arrays before control structures, because
there is nothing in the language to manipulate the arrays (without appealing to
the libraries).
But with these objects as built-in's, we can encourage nice and simple code
without
unnecessarily complicated control structures.

Unfortunately, it seems the zyBooks authors still succumb to the same
temptations
as any other programmer who learned control structures before data structures.
Soon after introducing those control structures, they have an exercise to do a
string
translation, using an ugly 12-way if-else construct nested within a loop  where 
a dictionary would very easily trim the if-else and str.translate() would
eliminate the loop.

(This is fresh in my mind because I plan to illustrate both their solution
and mine in my very next class)

Roger Christman
Pennsylvania State University


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


Re: Python-list Digest, Vol 169, Issue 7

2017-10-05 Thread ROGER GRAYDON CHRISTMAN
On Wed, Oct 4, 2017 22:42 Stefan Ram (r...@zedat.fu-berlin.de) wrote:
>
Steve D'Aprano  writes:
>>So, "bottom-up" in this case means: iterators should be
>>taught before for-loops.
>>Why? 
>
>  The syntax for is (from memory):
>
>for  in : 
>
>  . As an example, I might show:
>
>for i in range( 3 ): ...
>
>  . This raises the question:
>
>  "What is the value of ?range( 3 )??".
>
>  "Bottom up" means that the simple and constituent parts
>  are taught before the complex and compound parts. I.e.,
>  ?range( 3 )? is explained before ?for i in range( 3 ):?.
>
>


The easy answer here is to not use the range in the first for loop.

I introduce for with actual collections  (e.g. lists, strings, dictionaries)

It is very easy to figure out what  "for i in [2, 6,32, 7, 5]" means.

This is very easy to understand, and I teach it early, to avoid this common
error:

"if i == 2 or 6 or 32 or 7 or 5"

which plagues Python and C programmers alike (only Java complains about that
one)

You can even access the proper subscripts for a list without using range(),
if you are willing to use enumerate().  

So, by teaching the for loop without the range, not only do you get to postpone
the details of what range() does   (and can even point out -- hey, that's
exactly
the same numbers as enumerate listed!)   but you also get your students to
believe that there is a better way to access the elements of a list than
counting
down the subscripts.

I still see a lot of instructors and programmers who newly migrate to Python
that use counting a range() as their first choice in traversing a list.
Teaching the for loop without using range, I believe, is the best way 
to forestall that habit.

Oh, and it also steers people from this error I often see:
"for i in len(list)"

Roger Christman
Pennsylvania State University


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


Re: newb question about @property

2017-10-04 Thread ROGER GRAYDON CHRISTMAN

On Wed, Oct  4, 2017 14:03 PM, bartc  wrote >
"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.
>
>



I think you might be missing a small feature buried in the language:

class any():..  __slots__ = ["x","y"]

>>> p = any()
>>> p.x = 10
>>> p.y = 20
>>> p.z = 30
Traceback (most recent call last):
  File "", line 1, in 
p.z = 30
AttributeError: 'any' object has no attribute 'z'
>>> p.c = 40
Traceback (most recent call last):
  File "", line 1, in 
p.c = 40
AttributeError: 'any' object has no attribute 'c'

 >>> p.__slots__
['x', 'y']   

So, you can prevent new fields from being added
without forcing yourself into an immutable named tuple.

And if you really need to know what is in there, it tells you!

Oh, and as regards to it being different each time:
>>> p.__slots__ = ['x','y','z']

Traceback (most recent call last):
 File "", line 1, in 

p.__slots__ = ['x','y','z']

AttributeError: 'any' object attribute '__slots__' is read-only

Oh, and here's a little thing from the Python 3.6.2 Glossary:

__slots__ 

A declaration inside a class that saves memory by pre-declaring space for 
instance attributes and 
eliminating instance dictionaries. Though popular, the 
technique is somewhat tricky to get right and 
is best reserved for rare cases 
where there are large numbers of instances in a memory-critical application. 


Roger Christman
Pennsylvania State University

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


Re: The "loop and a half"

2017-10-04 Thread ROGER GRAYDON CHRISTMAN
I teach a course in programming to students who have no plans to be
programmers, scientists, or engineers.And I deliberately lied today about
the for loop.

In my lecture slide, I said that the for loop could only be used if you had
a collection of values (e.g. list, tuple, dict, string, or range)
where all the data was in hand, and should only be used when 
truly planning to visit the entire collection.

The slide essentially claimed, you could not use the for loop to
input a series of values from the keyboard, until seeing a blank line or zero.
or to search a list until you found the first even value, and stopping when you
get there.
If you want to stop repeating for an arbitrary reason, you must use a while
loop.

Deliberate lie.

Verbally I said it was actually a fib, and that there was a way to
do these cleanly with a for loop, but it's a method that I postpone until
halfway through the second course for students in the major,
not the sort of thing I would teach to this particular audience this early.

But yes, we can use yield, and iter(), and itertools to do both of these
examples very clearly with a for loop (and without an explicit break statement),
but I'd rather keep my course content small and simple.


Roger Christman
Pennsylvania State University
>

>

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


Re: Python-list Digest, Vol 169, Issue 5

2017-10-04 Thread ROGER GRAYDON CHRISTMAN

On Wed, Oct  4, 2017  14:54, Chris Angelico  wrote:
>
On Wed, Oct 4, 2017 at 2:48 PM, Steve D'Aprano
> wrote:
>> On Wed, 4 Oct 2017 01:40 pm, Chris Angelico wrote:
>>
>> You know, you don't HAVE to economize on letters. It's okay to call
>> your parameters "prompt" instead of "prmt". Remember, that's part of
>> your API.
>>
>>
>> Whn u wste vwels lik that, dn't b srprsd whn u run ot n hav shrtg of vwel wth
>> nt nuff 4 vrybdy.
>>
>
>And then English will turn into an abjad like Arabic. Yes, I see how
>it is. Python is a sneaky plan by Islamic extremists to make us use up
>all our vowels.
>
>(I'd end the post there, except that I've learned from past experience
>that there is no statement so ridiculous that people will know for
>sure that you're joking. So for the humour-impaired: THIS POST WAS A
>JOKE. Okay? Good.)
>
>


Gotta watch out for all those Islamic extremists.

Somewhere along the line when I wasn't paying attention,
they got us all using Arabic numerals.

Roger Christman
Pennsylvania State University

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


Re: when is the filter test applied?

2017-10-03 Thread ROGER GRAYDON CHRISTMAN
On Tue, Oct  3, 2017 15:38:42, Neal Becker  wrote:
>
I'm not certain that it isn't behaving as expected - my code is quite
>complicated.
>
>On Tue, Oct 3, 2017 at 11:35 AM Paul Moore  wrote:
>
>> My intuition is that the lambda creates a closure that captures the
>> value of some_seq. If that value is mutable, and "modify some_seq"
>> means "mutate the value", then I'd expect each element of seq to be
>> tested against the value of some_seq that is current at the time the
>> test occurs, i.e. when the entry is generated from the filter.
>>
>> You say that doesn't happen, so my intuition (and yours) seems to be
>> wrong. Can you provide a reproducible test case? I'd be inclined to
>> run that through dis.dis to see what bytecode was produced.
>>
>> Paul
>>
>> On 3 October 2017 at 16:08, Neal Becker  wrote:
>> > In the following code (python3):
>> >
>> > for rb in filter (lambda b : b in some_seq, seq):
>> >   ... some code that might modify some_seq
>> >
>> > I'm assuming that the test 'b in some_seq' is applied late, at the start of
>> > each iteration (but it doesn't seem to be working that way in my real
code),
>> > so that if 'some_seq' is modified during a previous iteration the test is
>> > correctly performed on the latest version of 'some_seq' at the start of
each
>> > iteration.  Is this correct, and is this guaranteed?
>
>

I think one must always be very careful about modifying anything
that you are iterating across -- if not avoiding that sort of thing entirely.
In particular, avoid anything that might add or remove elements
in the middle of the sequence.

YMMV, but you can imagine the iterator behaving like some of these
(all naturally implementation-dependent)

Traversing an indexable sequence (such as a list or string)
might maintain an internal counter that increments for each iteration.
Traversing a linked sequence (such as a linked list)
might maintain an internal reference that advances down the chain.
If you were to remove the element that you were currently visiting
(such was done in   "for c in x:   x.remove(c)")) you may end up
missing items.   For example, if you remove element 10 from a 
list or string, element 11 moves forward to position 10, but the
internal counter mentioned above would still advance to 11 --
skipping over the item that followed what you removed.
Similarly, if you to remove the linked list node that contained
the data you tried to remove, you might have an unspecified
behavior of where the linked list advancement would take you.

It would be safer to make a deep copy of the data iterable data
and iterate down the copy, so you can be sure that all your 
intended changes to the original data do not interfere with 
your iteration.

Here is an illustration of something going awry:
('.'s added in case my mailer destroys indents)
x = list('aaabcadaae')

for c in x:

...  if c == 'a':

...   x.remove('a')
''.join(x)
'bcaadaae'
Of the original 18 a's, 10 were removed.
The test for (c == 'a') only applied to every other a,
because the deletions removed some a's forward,
while the iterator kept advancing.
(And of course, it always deleted the first a in the list,
even if that is not where my iterator was looking)


And yes, I would expect the filter to be a lazy application
to the iterable you are filtering, so anything that removes
from your iterable is going to cause you filter so skip something.
That can also be fixed by copying the iterable first.

Or alternatively, you can go more functional and instead
create a new iterable set of data from the old, instead of
mutating what you have.

Roger Christman
Pennsylvania State University


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


Re: Beginners and experts

2017-09-30 Thread ROGER GRAYDON CHRISTMAN
Not in response to any particular note, but to the thread as a whole.

Regarding how beginners make tweaks and changes at random,
hoping that the bug will disappear, where experts tend to be a bit
more methodical in their bug-fixing.

Here at academia I have taught a little bit of partial correctness,
using assertions and what-not to determine whether the code
is correct using mathematical proof techniques.

And then I would ask a test question for them to apply those
proof techniques to a perfectly good function, which contains
no errors of any kind.

And invariably I get those answers that randomly perturb the code instead.
Roger Christman
Pennsylvania State University
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Aliasing [was Re: [Tutor] beginning to code]

2017-09-27 Thread ROGER GRAYDON CHRISTMAN

On Tue, Sep 26, 2017 11:00 PM, Steve D'Aprano 
wrote:
>
The critical distinction here is whether the names refer to each other:
>
>a <---> b
>
>or whether they merely refer to the same value:
>
>a ---> [ value ] <--- b
>
>
>Python uses the second model. Var parameters in Pascal and references in C++
use
>the first. Since the term "aliasing" is well-established for the first, using
>it in Python *without making the difference clear* is wrong.
>
>
>

Aha!  There is the fundamental problem.
In your first diagram below, if a is a pointer to b, and b is a pointer to a,
then where is the value?

If the value of 1 (or 2) is in a, then a cannot point at b;

Or are you saying now that all variables in Pascal and C
are _both_ values and pointers, simultaneously?

Does that mean then that the value 1 (or 2) is in _both_  a and b?
So that an assignment to either must change both copies of the value?

No, I think it is more likely to be that the second diagram applies
in all cases.   Simply declaring a variable like A would lead to

a --> [ uninitialized ]

int& b creates an alias to a leads to

a -> [ uninitialized ] <- b

and then any assignment to a or b in the non-Python languages
under consideration would fill in that box, allowing the change
to be visible to both.

But in Python, _all_ assignments are aliases.

And I'll leave off further discussion by referring back to my
previous note about what happens when we do "b = c"
in the non-Python languages and in Python.

>From the ordering of the notes in this forum, I will just assume
you did not get a chance to read it before this post I am responding to.

Roger Christman
Pennsylvania State University

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


Re: Aliasing [was Re: [Tutor] beginning to code]

2017-09-26 Thread ROGER GRAYDON CHRISTMAN

On Tue, Sep 26, 2017 12:00 PM, Steve D'Aprano 
wrote:
>
> a = 1
>> b = a
>> b = 2
>> 
>> a is not 2.
>
< snip >
int main () {
>   int a;
>   int& b = a;  // reference variable or alias
>
>   a = 1;
>   printf("a: %d, alias b: %d\n", a, b);
>   b = 2;
>   printf("a: %d, alias b: %d\n", a, b);
>   return 0;
>}
>
>
>And here is the output:
>
>
>a: 1, alias b: 1
>a: 2, alias b: 2
>
>
>So I stand by what I said: assignment in Python is NOT an alias operation. If
it
>were an alias operation, as you claim, then we could write this:
>
>a = 1
>b = a  # alias to a
>b = 2  # assigning to be is like assigning to a (as in the C++
>example)
>assert a == 2
>
>But Python is not like that, assignment is not an alias operation, and the
>assert will fail.
>

I think you are being a bit choosy in your analysis of the examples.
You essentially claim that "assignment is not an alias operation" by
assuming that some assignments are not an alias operations,
and then conclude that it is inconsistent for the rest to be.

Here is a discussion of the code in light of the claim that assignment
is an alias operation, meaning _all_ assignments are aliases,
and not just the ones you choose to prove your point.

a = 1 # 'a' is an alias to the value 1
b = a # 'b' is an alias to the value named by a, which is also an alias to 1
b = 2 # 'b' is now an alias to the value of 2, and no longer an alias to
'a' or 1

Your C++ counterexample is invalid, because, indeed, only the second
of the three assignments is an alias operation, and only because you
specifically declare variable b to be a reference variable.  You are not
really 'assigning' to b -- you are initializing the reference variable named
b..  

If we were to add an additional statement into both examples.

b = c

In Python, this would be another aliasing operation, causing b to
refer to the same thing as c refers to (assuming c has been assigned).

But in C++, that statement would be completely invalid -- once you
associate a reference to a reference variable, you cannot change
the binding.This further emphasizes that the statement "int  = a"
is not an assignment statement, which means it is rather irrelevant
to the semantics of assignment statements.

Roger Christman
Pennsylvania State University

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


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

2017-09-25 Thread ROGER GRAYDON CHRISTMAN
I would claim that these two paragraphs do not agree.

What is stored in the variable in Pascal?

In declared variables and value parameters, the value itself.
Let's just temporarily stipulate that for reference parameters
and pointer variables actually store a pointer to the object.

Where is it recorded whether this is a pointer to an integer
or a float or a character or a thingamajig?

Neither in the value nor the assumed pointer to the variable.
In Pascal (and most compiled languages) that value type
is maintained separately by the compiler, and then discarded
in the compiled code.

In the case of Python, the 'pointer' you refer to also has
no type information.  Instead, the type of the value is
frequently inferred at run-time, based on additional
information stored with the value.   There is no equivalent
information available at run-time in Pascal.

Now, when you say 'Python's assignment semantics
are wholly contained by those of Pascal', please show me
the equivalent Pascal code to mimic the following
(and not by defining a brand new complex object type
in Pascal, since I am not doing so in Python).

x = 5
x = 'abc'

I think the larger discussion was about value and reference parameters.
Yes you can do both of those in Pascal.
But if you were stuck with just those two choices,
which applies to this function definition?

def add_to_self(arg):
   arg += arg
x = 'abc'
add_to_self(x)
# now x = 'abcabc'
x = 5
add_to_self(x)
# x is still 5

is 'arg' a value parameter or a reference parameter?
Can you replicate this behavior in Pascal without any if statement,
since, as you say, the semantics are wholly contained by
those of Pascal (aside from the += operator itself not
appearing in the Pascal language)

Roger Christman
Pennsylvania State Universtiy

On Mon, Sep 25, 2017 12:00 PM, python-list@python.org wrote:
>
   A pointer to the object is stored in the variable.
>
>Of course, I'm using terminology that is not conventional in Python
>circles. However, I'm doing it to demonstrate that there's nothing
>particularly different between Python's assignment semantics and those
>of, say, Pascal. Python's assignment semantics are wholly contained by
>those of Pascal.
>
>

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


Re: python console menu level looping

2017-09-25 Thread ROGER GRAYDON CHRISTMAN


On Mon, Sep 24, 2017 09:41 PM, Daiyue Weng  wrote:
>
Hi, I tried to make a menu using print statements in Python 3. The code is
>as follows,
>
>print('insert data into: ')
>data_insert_method = ['new collection', 'existing collection']
>for index, elem in enumerate(data_insert_method):
>print(index, '-', elem)
>
>while 1:
>how_to_insert = input('Choose a method for inserting data: ')
>if how_to_insert:
>try:
>how_to_insert = int(how_to_insert)
>how_to_insert = data_insert_method[how_to_insert]
>break
>except ValueError:
>print('Please type in an integer corresponding to the data insert method')
>continue
>except IndexError:
>print('insert method index out of range')
>continue
>
>if how_to_insert == 'new collection':
>
>print('Set up collection name : ')
>db_name_setup = ['manual setup', 'return to the main menu']
>for index, elem in enumerate(db_name_setup):
>print(index, '-', elem)
>
>while 1:
>how_to_setup = input('Choose a method for setting up collection: ')
>if how_to_setup:
>try:
>how_to_setup = int(how_to_setup)
>how_to_setup = db_name_setup[how_to_setup]
>break
>except ValueError:
>print('Please type in an integer corresponding to the collection setup
>method')
>continue
>except IndexError:
>print('collection setup method index out of range')
>continue
>
>if how_to_setup == 'manual setup':
>print('Please type in collection name: ')
>elif how_to_setup == 'return to main menu':
>print('return to main menu')
>
>It is a 2-level menu, on the 2nd level menu 'new collection', there is an
>option - 'return to the main menu', I am wondering how to loop back to the
>1st level menu, i.e. ['new collection', 'existing collection'],
>whenever 'return
>to the main menu' is selected.
>



As one of those pesky teacher purists, my first response is 'ick'.

I see 'break' statements used for 'normal' loop exits.

I see 'continue' statements that have no effect, so serve no purpose.

I see lists being used just for display purposes, and not to actually solve any
problem

and then the question about 'how to loop back' at the end

-- if you want to go from the bottom of a loop to the top of loop,

all you have to do is make sure they are the same loop


I would take this approach:


I am inserting .'s to indent, because I do not trust my mailer

to preserve the indentation


data_insert_method = ['exit program',new collection','existing collection']   

db_name_setup = ['return to previous menu','manual setup']


first_menu = -1# feed the first loop

while first_menu != 0::

. . for counterin range(len(data_insert_method)):

. . . . index = (counter+1) % len(data_insert_method)

. . . . print(index,'-',data_insert_method(index)

. . . . # the quit option is always 0, and appears last

. . . . # obtain and verify integer input here

. . . . if first_menu == 1:# new collection

. . . . . . second_menu = -1

. . . . . . while second_menu != 0:

. . . . . . . . # the same thing as the outer loop, just nested

. . . . . . . < trim >

. . . . elif first_menu == 2:# existing collection



There are still some wide open design problems here:

It seems the only difference between 'new collection' and

'existing collection' is whether data already exists.

But the code structure as presented seems to suggest that

there will be one whole section to the program that works

on an empty set, and different whole section that works on

a non-emtpty set -- which suggests a humongous amount

of unnecessary code duplication.


Do you really expect to go back to the outer menu for

'new collection' more than once, when running this program,

or does it seem more likely that initalizing an empty data base

would happen only once at program startup, after which it

behaves just like an 'existing collection' with less data?



As someone else pointed out, your tests along the lines of

if how_to_insert == 'new collection':

are error prone, just from typing errors.If you are going to

have a user type in discrete integers, you might as well

just test using those integers.


On the other hand, if you intend to make the code's decisions

appear to be self-documenting, then skip the integers completely,

and instead use string inputs, like single letters or short keywords.

That would then eliminate any worry about ValueErrors.

A dictionary can easily associate the short inputs with the

longer method descriptions, and could even conceivably

link directly to a function object.


Roger Christman

Pennsylvania State University


 

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


Re: [Tutor] beginning to code

2017-09-23 Thread ROGER GRAYDON CHRISTMAN
On Fri, Sep 22, 2017 12:03 PM, Dennis Lee Bier  wrote:>
On Fri, 22 Sep 2017 23:30:34 +1000, Steve D'Aprano
>
 declaimed the following:
>

>The exercise is to demonstrate pass by reference semantics. That requires
>
>demonstrating the same semantics as the Pascal swap procedure:
>
>
>
>procedure swap(var a, var b):
>
>  begin
>
>tmp := a;
>
>a := b;
>
>b := tmp;
>
>  end;
>
>
>
>(ignoring the type declarations for brevity).
>
>
>
Or FORTRAN (since call-by-reference has been the standard in that
>
language from the start -- no special keywords needed to enable reference
>
semantics)... It's been 20 years, and I'm using an F90 text, so this is
>
going to be less than perfect:
>
subroutine iswap(a, b)
integer :: a
>
integer :: b
>
a = IEOR(a, b)
>
b = IEOR(a, b)
>
a = IEOR(a, b)
>
return
>
end
>
>{That's a bitwise exclusive OR; no temp storage needed}
>
> a = 123
>
> b = 321
>
> a = a ^ b
>
> a
>
314
>
> b = a ^ b
>
> b
>
123
>
> a = a ^ b
>
> a
>
321
>
>
>


And then along comes someone who asks for
to swap array elements a[I] and a[j], where I and j
just happen to be equal.You don't preserve the
values, as would be anticipated, but instead clear
the argument(s) to zero.

Saving one temp storage is a very tiny gain for the potential cost
of a program malfunction.   And if you go so far as to bring in 
a compiled language like Fortran into the mix, where the
'temp storage' is just a machine register, and not RAM,
you really have saved nothing at all.


I usually do not encourage people to optimize correctness out of their code.

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


Re: [Tutor] beginning to code

2017-09-13 Thread ROGER GRAYDON CHRISTMAN
I have not yet mastered how to respond to a particular note in a threadwith the
mailer that I use, so this is not in response to anyone in particular,but just
to some of the sentiments as a whole.
>  if x:>  # do something
Completely out of context, I would dislike it just because it is far too
vague.Is it testing for zero?  for an empty list?  or for some object's
completelyarbitrary definition of truthiness?
x.._bool__() seems to me to be just as efficient, but we don't like calling
dunders.bool(x) should mean the same thing, perhaps with an extra function
invocationto look for the dunder.
But even so, nothing here sheds light on what that Boolean outcome means.
I would agree that testing any of those for '== True' or the like is
pointlessredundancy, which may or may not be slower, depending on optimization
issues.
--
but in context is another thing entirely.
was x assigned to recently?   is the type of x obvious so its truthiness is
also obvious?Then fine -- if it is clear that x is a list, I'm happy to use
this to test for an empty list.But if x is some other creation, like a user
defined type, I would really prefer to seesomething analogous to:
if not x.is_empty() orx.exists() orx.has_brain()
And most definitely if x is assigned outside my control, I would definitely
wantsome way to test or verify x's type before I start using it, lest my
randomnumber generator with its
(A + B * C) % D
finds itself concatenating strings and formatting data.
Roger Christman
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Simple game board GUI framework

2017-09-11 Thread ROGER GRAYDON CHRISTMAN
I would echo the recommendation of teaching something you are already
familiar with doing.   Perhaps you can find a different class hierarchy to work
with.

I remember that the first time I really began to grok OOP was in a
text-based MUD environment.   In the application area, clearly
everything was an object (sword, bag, apple, etc.)   Some objects
were living (like player charaters and NPCs).   Many objects also
served as containers (bags had contents, rooms had contents,
players had an inventory).   And the polymorphism that came with
OOP allowed me to even simulate a ship, which was one object
whose inventory included several rooms, so as the ship moved,
so did everything on board.

And there was no GUI required for it -- so no issues there.

It's been a couple decades or so, but that interpreted object-oriented
language LPC might still be out there somewhere.


Roger ChristmanPennsylvania State University
On Mon, Sep 11, 2017 12:00 PM, Paul Moore wrote:
>

>My student has told me that he would like to understand classes so
>that he can better understand the logic behind the class-based
>features in the stdlib. That's why I'm trying to find a useful,
>understandable, example to work with.
>
>>My problem is that I've never written any sort of game code for
>>Python, which is basically what this is.
>>
>>   Get proficient first, then teach.
>
>I'll assume you don't mean that to be as critical of me as it sounds.
>I have no intention of trying to teach anyone "how to write a GUI
>program" or "how to use pygame". Any more than I'm trying to
>teach how
>the Python interpreter works. I'm simply trying to find (or build) an
>environment that helps me explain the concepts that I *am* trying to
>teach better than a command line REPL can do.
>
>>   And as I said, I would prefer to teach the standard
>>   frameworks and libraries that are distributed with the
>>   standard distribution of Python before I teach additional
>>   frameworks.
>
>As I said, I've been doing that, but need to help the student
>understand classes to give them a better understanding of why the
>stdlib is designed the way it is.
>
>>   Ok, if you teach at a gaming academy of when the title
>>   of the class contains the word "game", then you might have
>>   to teach game programming, but in this case you should
>>   really become proficient in it first.
>
>Well, obviously. I'm not sure why you think I'd consider it otherwise :-(
>
>Thank you for your comments, but clearly you have a very different
>environment and/or set of students than I have.
>
>Paul
>
>

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


Re: A question on modification of a list via a function invocation

2017-09-04 Thread ROGER GRAYDON CHRISTMAN
>Does a poor job AFAIAC of explaining the difference between foo and bar in
foll def foo(x): x += 2
 def bar(x): x.append(2)
 a=10
 b=[10]
 foo(a)
 a
>10
 bar(b)
 b
>[10, 2]
 
Or with just one function: >>> def baz(x,y):
 x += y 
>>> a = 10
>>> b = [10]
>>> baz(a,a)
>>> a
10
>>> baz(b,b)
>>> b[10, 10]




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


Re: Who are the "spacists"?

2017-03-18 Thread ROGER GRAYDON CHRISTMAN
Just a couple minor notes from my experience:

1) 
Some of the course management software I use doesn't like me typing tab
characters.
When I want to post sample code into a course page using this software, tabs
are either
ignored or does something really broken (like post an incomplete file).  So, I
must necessarily
type spaces when posting that code -- and of course, downloading that sample
from the page
has spaces in it instead of tabs.

Point in favor of using spaces.

2)
Tabs are one byte; spaces are one byte; so unless all of your indents are only
one space at a time,
a source file with tabs takes less memory than a source file with tabs.
It's not a significant difference.

Very minor point in favor of using tabs.

I'm still a spacer myself. 


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


Namespace for timeit

2016-10-14 Thread ROGER GRAYDON CHRISTMAN
Trying to use timeit within a function:

def test(name, sorter, size):
"""Tests and times the sorting algorithm on given array size"""
print(name,end='\t')
array = [0]*size
for i in range(size):
array[i] = randrange(20)
timeit('sorter( array, size )', number=1)

Since 'sorter' is a name local to test, it is not yet recognized by timeit,
so I know I must somehow define a new namespace for that,
but the documentation doesn't really help me with how to do that

timeit('sorter( array, size )', number=1, globals='test')

That tells me the namespace isn't supposed to be a string
test.__dict__ is just an empty dictionary

so where do I find 'sorter', 'array', and 'size'?

Roger Christman
Pennsylvania State University


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


Re: Linear Time Tree Traversal Generator

2016-09-21 Thread ROGER GRAYDON CHRISTMAN
Since I was asked how I got different running times for my two code
fragments, I'll try to apply them to a very simple tree:
  4
2   6
   1 3 5 7

>def __iter__(node):
>  for x in iter(node._left):
>   yield x
>  yield node._value
>  for x in iter(node._right)
>   yield x

Nodes 1, 3, 5, 7 each yield exactly 1 value -- total 4 yield statements
Node  2  yields  1, 2, 3 3 yield statements
Node  6  yields  5, 6, 7 3 yield statements
Node  4  with its for loops yields all 7 values  7 yield statements

Total number of yields is 17
4 values (approx n/2) had to be yielded 3 times (approx log n)
Hence total time is O(n log n)

> def to_list(node,result):
>   """append node information to result"""
>   result = to_list(node._left, result)
>   result.append(node._value)
>   return to_list(node,_right, result)

Initially called at root (Node 4) with result = []
Empty result is based from Node 4 to Node 2 to Node 1 -> [1]
Node 2 appends 2, then Node 3 appends 3
These are returned to Node 4, who appends 4, etc.

Total number of append operations is 7, far less than 17

Now I suppose my new lists are also being 'sent upward'
with those return statements, but it is also very clear that
the total number of return statements executed is also 7,
far less than 17.

Hence total time is still O(n)

---

I saw one or two responses that said that it was inherently
flawed to do this as a binary tree in the first place.
Well, certainly updating the binary tree is faster than
a regular array or relational database, since it does not
require linear-time insertions and removals.

And for those who favor using dict for its very fast access,
you display your search keys in sorted order while they
are still in the dict.  The sorted() function copies all 
those out into an array and sorts the array, which
is of course, expected to be O(n log n).

Which only highlights my disappointment that my tree
traversal itself was O(n log n), unless I gave up on yield.
As a teacher I'm stuck with either
a) a data structure that can only get its maximal speed
   by not having any iterator in the normal sense
   (which in my mind sounds non-Pythonic)
b) can support iteration, but then is no better than a
   dict in any way, except for maybe some rare operation like
   "identify the minimal value"

Roger Christman
instructor
Pennsylvania State Universtiy


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


Re: Linear Time Tree Traversal Generator

2016-09-20 Thread ROGER GRAYDON CHRISTMAN

On Tue, Sep 20, 2016 at 9:46 AM, ROGER GRAYDON CHRISTMAN <https://webmail.psu.edu/webmail/retrieve.cgi?mailbox=inbox=CAO1D73Eho37guUZkM6Kk9Nu5WB43oN721G33XGNis0LhSu7xVQ%40mail%2egmail%2ecom=view_num=10800=50=0=4=default_view=1=1=0=20160920201523#;>d...@psu.edu>
 wrote:
>I am trying to find a better (i.e. more efficient) way to implement a generator
>
that traverses a tree.
>
>
The current model of the code (which is also used by a textbook I am teaching
>
from does this)
>
>
   def __iter__(node):
>
 for x in iter(node._left):
>
  yield x
>
 yield node._value
>
 for x in iter(node._right)
>
  yield x
>
>
This is nice, simple, and straightforward, but has an O(n log n) running time,
>
since
>
values from the leaves of the tree have to be yielded multiple times to the top
>
of the tree.
>





Justin Walters <walters.justi...@gmail.com> responded:



> Are the left and right attributes collections of more nodes or are they 
> simply references to the node's position in the tree? 
> From the code provided it seems like the former is true and a node's left 
> attribute is a reference to another node?

They are references to other nodes, which in turn have values and left and 
right references to more nodes, etc.
as in a particular tree.  There are no 'collections' in the sense of set or map 
or Python list, just recursive sub-trees.



> I don't know how flexible you are with the structure of your tree, 
but you could try taking the modified pre-order tree traversal approach.



> This article explains it in the context of a database, but the idea is the 
> same: <https://www.sitepoint.com/hierarchical-data-database-2/> 



> Each node would then have a parent attribute as well as left and 
right attributes. The parent would be a reference to a parent node, and 
the left and right would be integers that position the element in the 
tree. 



> The upside to this is that traversal and lookup is much faster 
since you do not need to have an iterator nested in an iterator. This is
 because the top level node will always have the lowest integer as it's 
left attribute and the highest integer as it's right attribute. That 
means that you can instead have a single iterator that iterates through a
 range of integers to yield the node with the specified left and right 
values.

I am in academia, and the current unit is the binary search tree in its 
conventional sense, instead of the tabular version.
Indeed that table would be faster for iteration, but at the increased cost of 
slowing down adding and removing elements.
If I were to use any array-based model, as this database link shows, all 
insertions and deletions would be linear-time
operations instead of logarithmic time.  

I would contrast the time to insert N elements and then to traverse the tree 
once, where the N elements arrive in any order:
Tabular approach N linear-time insertions -> quadratic time plus a linear-time 
tree traversal afterwards.
Tree approach:   N logarithm-time insertions plus an iteration that takes a 
time proportional to all that -- it still wins.
Since traversal is 'rare', I don't want to penalize the common behaviors to 
accelerate this traversal.

But I would still like to see if there is a linear traversal possible with the 
help if the itertools chain

Roger Christman
instructor
Pennsylvania State University


 

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


Linear Time Tree Traversal Generator

2016-09-20 Thread ROGER GRAYDON CHRISTMAN
I am trying to find a better (i.e. more efficient) way to implement a generator
that traverses a tree.

The current model of the code (which is also used by a textbook I am teaching
from does this)

   def __iter__(node):
 for x in iter(node._left):
  yield x
 yield node._value
 for x in iter(node._right)
  yield x

This is nice, simple, and straightforward, but has an O(n log n) running time,
since
values from the leaves of the tree have to be yielded multiple times to the top
of the tree.

Now, I could certainly implement a linear-time traversal without the gnerator:

def to_list(node,result):
  """append node information to result"""
  result = to_list(node._left, result)
  result.append(node._value)
  return to_list(node,_right, result)

but then that requires the extra memory space to build the list into, which
is basically what the generator is supposed to avoid.

Now, I did see that itertools has a chain method for concatenating
iterators, so it would be nice to concatenate the results from the 
recursive calls without the for loops, but I have no idea how to
squeeze the 'yield node._value' in between them.

Is there hope for a linear-time tree-traversal generator, or will
I have just have to settle for an n-log-n generator or a linear time
behavior with linear extra space?

Roger Christman
instructor
Pennsylvania State University


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


Re: Is duck-typing misnamed?

2016-08-27 Thread ROGER GRAYDON CHRISTMAN
Your response is appreciated.   I just thought I'd comment a little more on the
script:

Woman:  I'm not a witch! I'm not a witch!

V:  ehh... but you are dressed like one.

W:  They dressed me up like this!

All: naah  no we didn't... no.

W:  And this isn't my nose, it's a false one.

(V lifts up carrot)

V: Well?

P1:  Well we did do the nose

V: The nose?

P1:  ...And the hat, but she is a witch!


They took a woman who originally, I think we might agree, was not a witch,
and they added features that were understood to be part of the protocol
for witchiness.

I think this is very much like me defining methods __iter__ and __next__
and voila, I've turned something into an iterator by witch --  er.. duck-typing!

Perhaps she inherited her weight from her latent duckness.

Thoughts?

Roger Christman

On Sat, Aug 27, 2016 06:27 PM, python-list@python.org wrote:
>
On 26Aug2016 19:58, ROGER GRAYDON CHRISTMAN <d...@psu.edu> wrote:
>>"If it walks like a duck, quacks like a duck,... "
>>so there is indeed precedence for this so-called 'duck typing'
>>
>>but wouldn't it be more Pythonic to call this 'witch typing'?
>>"How do you know she is a witch?"
>>"She looks like one."
>>etc.
>>
>>I do grant that ultimately, the duck does come into play, since the witch
>>weighs the same as a duck.
>
>I disagree. They want to burn her because she's supposedly a witch, but the 
>scientific test was that she weighed as much as a duck. So I think your second 
>example is also duck typing: functioning like a duck.
>
>Cheers,
>Cameron Simpson <c...@zip.com.au>
>
>
>

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


Is duck-typing misnamed?

2016-08-27 Thread ROGER GRAYDON CHRISTMAN
"If it walks like a duck, quacks like a duck,... "   

so there is indeed precedence for this so-called 'duck typing'


but wouldn't it be more Pythonic to call this 'witch typing'?

"How do you know she is a witch?"

"She looks like one."

etc.


I do grant that ultimately, the duck does come into play, since the witch
weighs the same as a duck.

Roger Christman
Electrical Engineering and Computer Science
Pennsylvania State University


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