Rapid Python Programming

Chapter 3

Input - Data structures, Modules Create a file called ’input.py’ with the following two lines below. Execute the program with ’python ./input.py’ and input the number '2' Next, run it again and input the letter 'd'.

#input.py
x = input("Enter a number: ")
print "The square of number is", x*x

Results when running ’python input.py’:

Enter a number: 2
The square of number is 4

Again type ’python input.py’:

Enter a number: d
Traceback (most recent call last):
File "input.py", line 1, in <module>
x = input("Enter a number: ")
File "<string>", line 1, in <module>
NameError: name ’d’ is not defined

As you can see ’d’ is not defined and so it crashes! What if ’d’ was defined in the code? Create a new file with the following as save as ’input-hack.py’.

#input-hack.py
d=5
x = input("Enter a number: ")
print "The square of number is ", x*x

When you run the program you can now enter any number, and when you enter the letter ’d’ it’s already defined and should return 25. The ↓’input()’ function is very dangerous, because it uses ’rawinput’ and converts the data to a number using ↓’eval()’. Run the program again and type 2+2. It should return 16. If you change the code from ’x*x’ to ’x+x’, and run the script again with ’rawinput()’ like in the next example. The string of your choice will be duplicated twice. This is a warning to advise you not to use ’input()’ as it can create inconsistencies in the results as well as an opportunity to hack the code.

3.1.2 rawinput()

Let’s create another file ’rawinput.py’

#rawinput.py
x = raw_input("Enter a number or string: ")
print "you entered ", x

Please test the results and you will notice greater consistency. Further improvements can be made by reviewing the errors, substitute ’x’ with ’x*x’ and you will get an (↓’TypeError’: can’t multiply sequence by non-int of type (’str’) when you enter a number.

3.1.2.1 Guess Program

#guess.py
number = 10
guess = int(raw_input(’Enter a number between 1 & 20: ’))
if guess == number:
	print ’Congrats! Correct number is’, number
elif guess < number:
	print ’No, try a little higher’
else:
	print ’No, try a little lower’

The guess program has ’rawinput’ wrapped to an integer called ’int’. So the string is converted to an integer after you enter the number and hit return. If you change the ’rawinput()’ to guess = rawinput("Enter an integer between 1 and 20: ’). The ’if else’ statement will try to process the string, and default to the last else statement.

You can wrap this code with a while statement as follows:

#whileguess.py
number=10
while True:
	guess = int(raw_input(’Enter a number between 1 & 20: ’))
if guess == number:
	print ’Congrats! Correct number is’, number
	break
elif guess < number:
	print ’No, try a little higher’
else:
	print ’No, try a little lower’

Notice I added the break statement if the value is true it exits out of the loop.

3.1.3 Declare a Function

The most common function to declare is a simple ’hello’ statement.

#hello.py
def hello():
	print "Hello"
	return
hello()

You call the function with ’hello()’. A more practical function would be to process the square of a number.

def square(x):
	return x*x
print square(2) # call the function

You can expand this function with ’rawinput’.

#inputfunction.py
def square(x):
	return x*x
x = int(raw_input("Enter a number "))
print "input without function ",x
print "input with function ",square(2)

This is also a mild example of local vs global where the square is local to the function. The input is global.

3.1.4 Functions with Parameters

#function with parameter
#functionpar.py
def areaSquare(a,b):
	return a*b
print areaSquare(2,3)
z=4
y=2
print areaSquare(z,y)

3.1.5 Functions with Default Arguments

functions with default ’args’:

#functionarg.py
def tableLeaf(a,b=5):
	return a*b
print tableLeaf(5,10)
print tableLeaf(5)

Here is another way to write this that might be easier for others to follow.

#functionarg.py
def tableLeaf(a,b=5):
	print "area of table:", a*b
tableLeaf(5,10)
tableLeaf(5)

Another example with input.

#functionarg-input.py
def tableLeaf(a,b=5):
	print "area of table:", a*b
x = int(raw_input("enter a number: "))
tableLeaf(x)

You can expand this by adding another ’rawinput’ and assign it to ’y’. Then call ’tableLeaf(x,y)’.

3.2 Data Structures

3.2.1 help(list)

The features for ↓list are extensive from counting items in the list to inserting, removing, appending and sorting. Roughly 50 attributes exist to manipulate a list.

#mylist.py
mylist = [’cpu’, ’monitor’, ’printer’, ’keyboard’, ’mouse’]
print ’mylist contains the following:’,
for i in mylist:
	print i
print "I have",↓len(mylist), ’items in mylist’
print "I am adding ink to mylist"
mylist.append(’ink’)
print "mylist append: ",mylist
mylist.sort()
print "mylist sorted: ",mylist
print "first item in mylist: ",mylist[0]
print "second item in mylist: ",mylist[1]
del mylist[1]
print "removed second item in mylist: ",mylist

3.2.2 help(tuple)

Tuples are similar to lists except they are ↓immutable like strings. You would use them when you are sure that they will not change.

#mytuple.py
mytuple = (’pen’, ’pencils’, ’paper’)
print ’mytuple contains: ’,mytuple
print ’I have’,len(mytuple), ’in mytuple’
drawer = (’ruler’, ’paperclips’, mytuple)
print ’mytuple and drawer contain: ’,drawer
print ’first item in first tuple is : ’,drawer[2][0]

3.2.3 Tuple in Print Statement

The following attributes “%s” for string “%d” for integer, and “%f” float which defaults to 6 decimal places.

#tupleprint.py
book = "Wheel of Time Dragon Reborn"
cost = 45.9
print ’This %s book is %d’ % (book, cost)
print ’This %s book is %f’ % (book, cost)
print ’This %s book is %6.4f’ % (book, cost)
print ’This %s book is %6.2f’ % (book, cost)

3.2.4 Dictionary

help(’dict’)

A dictionary is like an address book. This example will use an ↓inventory system.

#inventory.py
inv = {’monitors’: ’two’, ’printers’: 5, ’keyboards’:3}
print inv["printers"]
inv[’printers’] = 6
print inv[’printers’]
print inv
del inv[’keyboards’]
print inv
for i,j in inv.iteritems():
	print i, j

3.2.5 Sequence

The main feature of sequence is the ability to access the item in the index directly or to slice them.

#seq.py
x = ["monitor","keyboard","cpu","printer","mouse","paper", "cables","laptops"]
print x[0]
print x[0:1]
print x[2:5]
print x[:4]
print x[4:]
print x[-4]

3.2.6 More on Strings

Everything in python is an object especially a string. String is of the class ’str(object)’.

Here are the most common features used:

  • find(...)
  • join(...)
  • split(...)
  • startswith(...)

basic string manupulation:

Pay ATTENTION to indentation!

#string.py
mystring = "Learning Practical Python"
if ’earning’ in mystring:
	print ’found earning’
else:
	print ’did not find string pattern’
if mystring.startswith(’Learn’):
	print ’found Learn startswith’
if mystring.find(’earn’) != -1:
	print ’found earn with find’
change = mystring.↓split()
print change
delimit = ’;’
new = delimit.↓join(change)
print new
comm = new.split(’;’)
print comm

3.3 Modules

Python comes with a large library of modules that can be used for all sorts of tasks from database programming, web programming, to graphics and games. A module is a file that contains functions and variables defined for reuse. One of the first modules used was the string module that has a series of functions designed to manipulate strings. To use the module you ↓import it as follows:

import string

Of course string is a standard library. You can build and save functions in another file and load them using import. Make sure the file you import has a ’py’ extension. For example these two files:

#hellomodule.py
def hello():
	print "hello"

Create another file ’helloprog.py’ and add the following:

#helloprog.py
import hellomodule
hellomodule.hello()

Then run ’python ./helloprog.py’

It should print out ’hello’ and it will also create a new file called ’hellomodule.pyc’: The ’.pyc’ is a byte compiled file. It pre-compiles the file that is imported for speed on repeat usage. This is useful because importing libraries can take time to load depending on the library and the resources of the computer you are using.

3.3.1 ↓sys Module

This is an important module that is used often when handling a list of arguments.

# arg1.py
import sys
print "script name", sys.argv[0]
#print "script arg", sys.argv[1]
#print "script arg list", sys.argv[1:]

First run the script as follows: ’python ./arg1.py’ Then uncomment out ’sys.argv1’ and run ’python ./arg1.py 1 d hello’

output:

script name arg1.py
script arg hello
script arg [’1’, ’a’, ’hello’]

So now you get the idea that the first field in the list is the script name itself. A loop can easily cycle through the list.

# arg.py
import sys
for i in sys.argv:
	print i

Now run it: ’python ./arg.py’

Watch it loop through the arguments in the list. You can control your list using an ’if’ statement.

# arg2.py
import sys
if len(sys.argv) > 1:
	print "Number of arguments:", len(sys.argv)-1
	for i in sys.argv[1:]:
		print i
else:
	print "no arguments..."

Run the following code above: python ./arg2.py arg1 arg2 hello As you see it’s using a ’greater than 1’ operator. There is always at least one item in the list which is the file itself. You need to separate the file name from the arguments. To do this, you will need to use -1.

3.3.2 Practical Usage:

Here is a practical example. Pay ATTENTION to indentation!

# square.py
import sys
def square(x):
	return x*x
x = int(sys.argv[1])

print ’square is %g’ % square(x)

Run the program as follows: ’python ./square.py 4’ and it should return 16. However if you run it without an argument it will error. To fix you can easily add the ’if’ statement below to the file above the function ’def square(x):’. No need to add the ’else’ label as it is already implicit.

#square1.py
import sys
def square(x):
	return x*x
if len(sys.argv) !=2:
	print ’Need an integer’
sys.exit(1)
x = int(sys.argv[1])
print ’square is %g’ % square(x)

Run the following:”python ./square1.py 4” then run it again “python ./square1.py” The ’if’ evaluates that an argument exists or not. If not equal (’!=)’ then exit. Remember that the first field in ’sys.argv[0]’ is the file itself. Should you choose to use more than one integer or a string, the script will error out. Using ’sys.argv’ can be very useful when you find yourself using another program or script to talk to your python applications. You would be surprised how often this happens in the real world. The goal here is that you can create programs that require arguments and if the user doesn’t enter an argument your code will catch it and print out a help statement that explains how to use the program.

3.3.3 from import

You can use both options ’from import’ but note that it can make your code difficult to read. For example ’from sys import argv’ and you could use ’argv’ rather than ’sys.argv’. You can import all names in sys such as ’sys.exit, sys.path’ in one shot like: ’import sys *’. This could also make executables larger if compiled on windows. If you are following a coding style like “PEP 8”, you will need to be specific and import only the modules you plan to use.

3.3.4 Testing a Module

Since all modules are objects, you can (and should) test them as you write. Make sure you use two underscores with no spaces between the underscores. For example: Pay ATTENTION to indentation!

# amodtest.py
if __name__ == ’__main__’:
	print ’access directly’
else:
	print ’from import’

Now run ’python ./amodtest.py’. output: access directly

Run interactive prompt and confirm you are in same directory as ’amodtest.py’. >>> import amodtest from import >>>

As you can see when the file is imported, the ’else’ statement prints since it is not loaded directly. A more practical method would be:

# fmodtest.py
def square(x):
	return x*x
if __name__ == ’__main__’:
	print "testing square(4) directly", square(4)

If you run it directly, it should print out 16. Next, let’s build another file and import it as follows:

# testmodf.py
import fmodtest
print "from import square(16)", fmodtest.square(16)

Notice this will only print the modules function ’def square(x)’ from ’amodtest.py’ and nothing after.

3.3.5 Summary

At this point you can build any algorithm you want. Having the ability to create your own functions gives you the power to create custom algorithms without importing additional libraries.

3.3.6 Exercises

  1. Go through the examples above using the interactive interpreter.
  2. Convert ’whileguess.py’ into a function and call it ’guess()’.
  3. Create a function to calculate Celsius and convert to Fahrenheit upon user input. Use a while loop to process the temperature until user enters ’x’ to exit.
  4. Using the following list (list="I will master strings"). Use a for loop to print the word ’master’.

To post a comment you need to login first.