[sf-lug] [PyClass] the print token keyword statement function builtin magic

jim jim at well.com
Fri Sep 26 12:44:51 PDT 2008




At our first python lesson with asheesh at the grind, there 
was a question about the print print() function that in 
release 3.0 replaces the print statement that's used in 
previous releases of Python. 


The reference for the entire Python language is here: 
http://docs.python.org/ref/


Links specific to the print statement/function issue: 

http://www.python.org/dev/peps/pep-3105/ 
# "Make a print function" PEP : Guido's rationale for the change 

http://mail.python.org/pipermail/python-dev/2005-September/056154.html 
# some of guido's arguments in favor of the change 

http://www.comp.leeds.ac.uk/nde/papers/teachpy3.html 
# see 2.4 and following re asymmetric console I/O. 

http://www.python.org/download/releases/3.0/ 
# release page for python 3.0 (see the what's new link) 

http://www.win.tue.nl/~wstomv/edu/python/python-observations.html 
# Tom Verhoeff's personal assessment of Python 2.2.2 design points 


about PEPs and Python: 

http://www.python.org/dev/peps/ 
# TOC of PEPs, categorized 

http://www.python.org/dev/peps/pep-0001/ 
# PEP #1: "What is a PEP", a PEP about PEPs 


My comments per discussion and terms in the lesson: 

   programs are made of source code that we type, and typically 
consist of a set of one or more (usually lots more) "statements". 
   older programming languages have a character that is used to 
end a statement. python does not have such a statement terminating 
character. 
   thinking like a computer scientist, it seems to me, includes 
knowing that there's an interpreter or compiler that is reading 
our code. formally, interpreters and compilers are built as rules 
engines, aka state machines. they begin in a neutral state and 
start reading our code, breaking our code down into a stream of 
tokens. 
   as part of evaluating each token, they change their state, 
usually reducing the number of legal possibilities for the 
subsequent token. at some point there's no further reduction or 
other adjustment, which means they're done reading the token 
stream. 
   the statement terminating character tells the interpreter or 
compiler that the programmer intends that the interpreter or 
compiler return to a neutral state so's to be ready to work on 
the next stream of tokens (i.e. "statement"). if the programmer 
puts the statement terminating character in the wrong place, 
the interpreter or compiler generates an error and quits. 

   in python, statements are delimited by newlines. to write a 
long statement, you use the \ (backslash) character as the last 
character on the line and continue writing your statement on 
the line below. the python interpreter will ignore the newline 
that immediately follows the \ character and continue 
interpreting the token stream as part of the same statement. 

   it strikes me as unfortunately muddying that the word 
statement is used in the discussion of python keywords. 
http://docs.python.org/ref/keywords.html 

   programming languages can be thought of as consisting of a 
set of keywords (such as "if", "while", "def", "import", the 
now notorious "print", and so on) along with a set of operators 
(such as +, -, (), =, ==, !=, >, and so on) and also including 
a set of syntax rules that tells the programmer how to use the 
keywords and operators and the all-important identifiers that 
the programmer makes up as names of variables, functions, 
classes, and objects. 

   the term "expression" often pops up in discussions along 
these lines. i think a useful definition of "expression" is 
"a combination of one or more operands with zero or more 
operators". mathematicians would probably disagree, but the 
definition is useful nonetheless. 
   the idea of an expression is that the interpreter or 
compiler resolves the expression to a single value. thus the 
expression 1 + 1 is resolved to the single token value of 2. 
the expression 4 * 5 + 2 * 3 is similarly resolved to a 
single value, but only by following the proper syntax rules. 
   beginners looking at 4 * 5 + 2 * 3 might multiply 4 * 5 to 
get 20 and then add 2 to get 22 and then multiply by 3 to get 
66. the syntax rules force multiplication first, which means 
multiplying 4 * 5 to get 20 and then multiplying 2 * 3 to get 
6 and then adding 20 with 6. knowing the syntax rules means 
knowing the rules of operator precedence, among other things 
(knowing that multiplication is done before addition). 
   it's helpful to think of 4 * 5 + 2 * 3 as a complex 
expression made of sub-expressions: 4 * 5 is one 
sub-expression and 2 * 3 is another sub-expression. 
   evaluate 4 * 5 first to get 20. then evaluate 2 * 3 to 
get 6. now we've resolved our two sub-expressions to single 
values 20 and 6. as there are no other sub-expressions to 
work on, we have reduced our original to 20 + 6, a simple 
expression that we can resolve to a single value 26. 
   it's helpful to group sub-expressions with the () 
(parentheses) characters. so we could rewrite the original 
expression as (4 * 5) + (2 * 3) to make things clearer. 
be careful, as the rules of precedence govern the use 
of the () characters, too. if we write 4 * (5 + 2) * 3, 
the rules of precedence force resolution of things in 
parentheses absolutely first: so 5 + 2 is resolved to a 
single value of 7, to produce 4 * 7 * 3. because the only 
operators are multiplication, precedence doesn't have an 
effect (and the interpreter or compiler resolves from 
left to right in this case), so 4 * 7 becomes 28 and 
28 * 3 becomes the single value of 84. 
   we can think of the following as an expression: 
x = 4 * 5 + 2 * 3 
   how many operands are there above? x, 4, 5, 3, and 2, 
five operands. how many operators? =, *, +, and *, four 
operators. which operator has the highest precedence? 
the * operator. which operator is next? the + operator. 
which is last? the = operator. 
   so resolving the expression can be notated as follows: 
x = ((4 * 5) + (2 * 3)) 
x = ((20) + (6)) 
x = (26) 

   each of the above, written as is, is not only an 
expression but a statement in python. notice that there 
are no keywords (no "global", "pass", "except", "else", 
and so on) in the above statements. 

   the concept of a "function" needs some unwraveling. 
some older programming languages distinguish between a 
"function: and a "procedure". in this mindframe, you can 
think of a function as being a procedure that returns a 
single value (and a procedure as doing something without 
returning any value). 
   in python, the word "function" covers both cases (the 
word "procedure" isn't needed, a function doesn't have 
to return a value). 
http://www.penzilla.net/tutorials/python/functions/ 

   programmers create functions by using the "def" keyword. 

def doit(): 
   x = ((4 * 5) + (2 * 3)) 
   print x 
   return x 
print "hi" 

   the "def" keyword is followed by the name of the 
function, in this case "doit". but the programmer must 
follow the function name with the () characters. the 
result tells the python interpreter that this is a 
function name and the code that defines it will be 
indented in a block following the : character. 
   the block of code for the doit() function is indented. 
note that indenting is vital. the final 
print "hi" 
statement is not part of the doit() function definition. 
   the function definition begins with a statement that 
assigns 26 to the variable x, then a print x statement, 
then a return x statement. 
   to use the doit() function we name it somewhere in 
our program. 

doit() 
the above is a function call that is a statement that 
tells the python interpreter to run the code that 
defines the doit() function. 
   as the program runs, 26 is displayed on the console. 

   below is a complete python program (also file is attached) 



# doing.py  20080926  jim at well.com  --------------- 


# function definitions on top so they're globally available 
def doit(): 
   # this is how to create a function 
   x = ((4 * 5) + (2 * 3)) 
   print "From the doit() function: x = ", x
   return x 


# using print statements throughout the program let you 
# see the program flow--if any error messages occur, the 
# previous and following print statements let you identify 
# the part of your code that's suspect. 
print "\n\nstarting to run\n" 

# this calls the previously defined doit() function 
doit() 

# the first use of the doit() function ignored the value 
# that doit() returned. this next use shows how to capture 
# a function's return value and use it. 
print "\n\nadding a feature" 

y = doit() 
print "\ncaptured doit's return as y and adding one: ", (y + 1) 

print "\n\nend of program\n\n\n\n" 

# ---------------End Of Program---------------



Here's the same program with a bug. run it just as it is. 
notice the error message. see the carot character pointing 
up to the end of the word print. can you find the error in 
the code? (file is attached) 


# doingwrong.py  20080926  jim at well.com  --------------- 


# function definitions on top so they're globally available 
def doit(): 
   # this is how to create a function 
   x = ((4 * 5) + (2 * 3) 
   print "From the doit() function: x = ", x
   return x 


# using print statements throughout the program let you 
# see the program flow--if any error messages occur, the 
# previous and following print statements let you identify 
# the part of your code that's suspect. 
print "\n\nstarting to run\n" 

# this calls the previously defined doit() function 
doit() 

# the first use of the doit() function ignored the value 
# that doit() returned. this next use shows how to capture 
# a function's return value and use it. 
print "\n\nadding a feature" 

y = doit() 
print "\ncaptured doit's return as y and adding one: ", (y + 1) 

print "\n\nend of program\n\n\n\n" 

# ---------------End Of Program---------------


   in the two (very similar) programs above, the lines 
doit() 
   and 
y = doit() 
   are both statements. 
   likewise, any of the lines with the print keyword, such as 
print "\n\n starting to run\n" 
   are also statements. it's helpful to distinguish between 
the keywords of a language and the concept of a statement 
as the language's rules of notation dictate. 

   the lesson uses various terms that seem not fully explained. 
you'll probably look things up. the following two terms ought 
to help a bit. 


Builtin and magic:  

   the python interpreter is constructed to read python code, 
compare the code to its keywords, operators, and rules of 
syntax, and also let you use some functions that are not 
keywords or operators but are built in as part of the python 
interpreter. 

http://docs.python.org/lib/built-in-funcs.html 

   in release 3.0, the interpreter will not implement a 
print keyword but rather provide a print() function as one 
of its builtins. 

   Magic is technology we don't understand (or don't yet 
understand, there are variations of the thought). the word 
"magic" in Python has a particular meaning: identifiers with 
double underscores. 
   the term "identifier" means some name that some programmer 
makes up. in the above example programs, x and y are both 
identifiers, and doit is an identifier, too. you make up 
names for variables, functions, and classes: those are 
identifiers. when you use programs written by other 
programmers (which are in libraries and other modules), 
those programs have identifiers, too. 
   one of the biggest issues of python is that of name 
spaces. the idea is that if you have separate name spaces, 
then you can use the same identifier in each of the name 
spaces without confusing the python interpreter. 

   the following link is a particularly good intro to some 
python features (IBM has some excellent information on Python) 
that shows a few "magic" identifiers (such as __name__ and 
a couple of others): 
http://www-128.ibm.com/developerworks/library/l-cheatsheet3.html 

   the following link shows an email thread between two 
"pythonistas" discussing issues of magic. 
http://mail.python.org/pipermail/python-list/2007-June/444043.html 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: doing.py
Type: text/x-python
Size: 920 bytes
Desc: not available
URL: <http://linuxmafia.com/pipermail/sf-lug/attachments/20080926/9dba65b4/attachment.py>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: doingwrong.py
Type: text/x-python
Size: 924 bytes
Desc: not available
URL: <http://linuxmafia.com/pipermail/sf-lug/attachments/20080926/9dba65b4/attachment-0001.py>


More information about the sf-lug mailing list