def print_range(start, end):
print(start)
if start == end:
return
elif start > end:
print_range(start - 1, end)
else:
print_range(start + 1, end)
start = int(input("Enter start of range: "))
end = int(input("Enter end of range: "))
print_range(start, end)
def gcd(a, b):
"""Return greatest common denominator of a and b.
Returns None on bad input.
This code is based on Euculid's algorithm where gcd(a, b) = gcd(b, r)"""
if a <= 0 or b <= 0:
return None # limit our solution to only positive numbers
if a < b:
return gcd(b, a) # if a is less than b, just reverse the args
r = a % b
if r == 0:
return b # if no remainder then we found the gcd
else:
return gcd(b, r) # otherwise recursiveely call gcd using the remainder as the new divisor
def test(a, b):
print("gcd(%s, %s) = %s" % (a, b, gcd(a, b)))
if __name__ == "__main__":
print("testing gcd() function...")
test(10, 15)
test(24, 16)
test(-1, 34)
test(17, 15)
% python gcd.py
gcd(10, 15) = 5
gcd(24, 16) = 8
gcd(-1, 34) = None
gcd(17, 15) = 1
def gcd(a, b):
r = a % b
if r == 0:
return b
else:
return gcd(b, r)
print("gcd of 12 and 8 is", gcd(12, 8))
print("gcd of 10 and 5 is", gcd(10, 5))
print("gcd of 20 and 24 is", gcd(20, 24))
gcd of 12 and 8 is 4
gcd of 10 and 5 is 5
gcd of 20 and 24 is 4
a < b
are gone. Why?while test_expression_1:
statement_block_1 # these statements executed as long as test_expression_1 evalutes to true
if test_expression_2: break
if test_expression_3: continue
else:
statement_block_2
a = 0
b = 10
while a < b:
print(a, end=' ')
a = a + 1
print()
0 1 2 3 4 5 6 7 8 9
The end=' '
argument to the print
function indicates that a space character should be printed
following the value of a
, rather than the usual
newline ('\n'
) character. The final print
function call terminates the line by printing a newline character.
y = 67
x = y // 2
while x > 1:
if y % x == 0:
print(y, "has factor", x)
break
x = x - 1
else:
print(y, "is prime")
67 is prime
If y <= 2, then the test expression is never true and the "else" part of the loop is executed,
which is what we want.
for target_name in object:
statement_block_1
if test_expression_1: break
if test_expression_2: continue
else:
statement_block_2
word = "hello"
for x in word:
print(x)
h
e
l
l
o
for n in range(10):
print(n, end=' ')
print()
0 1 2 3 4 5 6 7 8 9
For the perfectionists:
There is a space character at the end of the output line.
How do we get rid of it?
first = True
for n in range(10):
if first:
first = False
else:
print(end=' ')
print(n, end='')
print()
0 1 2 3 4 5 6 7 8 9
Operation | Interpretation |
---|---|
str = "" | An empty string |
str = "tom's office" | Double-quoted string |
strblk = """lots-of-text""" | Triple-quoted block |
str1 + str2 | Concatenation |
str * i | Repetition |
str[i] | Index |
str[i:j] | Slice |
len(str) | Length |
"this is a number: %d" % 100 | Formatting |
for x in str: | Iteration |
"m" in str | Membership test |
s1 = "Now is the time for all"
s2 = " good people to cast their vote."
s1 + s2
'Now is the time for all good people to cast their vote.'
len(s1)
23
len(s1+s2)
55
s1[0] # index: note that string offsets begin at zero
'N'
s2[6:12] # slice: up to, but not including upper bound
'people'
s1[1:-1] # slice: negative offsets count from the end
'ow is the time for al'
for x in s1:
print(x, end=' ')
N o w i s t h e t i m e f o r a l l
"N" in s1 # test membership for character N in s1
True
s1 == s2 # test for equality
False
if 'vote' in s1+s2:
print('found word "vote"')
found word "vote"
capitalize() | isalnum() | lstrip() | splitlines() |
center() | isalpha() | partition() | startswith() |
count() | isdigit() | replace() | strip() |
decode() | islower() | rfind() | swapcase() |
encode() | isspace() | rindex() | title() |
endswith() | istitle() | rjust() | translate() |
expandtabs() | isupper() | rpartition() | upper() |
find() | join() | rsplit() | zfill() |
format() | ljust() | rstrip() | |
index() | lower() | split() |
s = 'Now iS tHe TIme for ALL gOOd PeoPLe'
s.lower()
'now is the time for all good people'
uc = s.upper()
print(uc)
NOW IS THE TIME FOR ALL GOOD PEOPLE
# find a substring within a string
s = 'The stock market has tanked this week.'
s.find('has')
17
s.find('have')
-1
s.find('the')
-1
s2 = s.lower()
s2.find('the')
0
s.lower().find('the') # equivalent
0
bytes
data type is used to store binary data.
To interconvert between the str
and bytes
,
one needs an encoding scheme.'A'
= 65 and ✁ = 9985.s = 'Now iS tHe TIme for ALL gOOd PeoPLe'
print(repr(s))
b = s.encode("utf-8") # "utf-8" may be omitted since it is the default
print(repr(b))
print(repr(b.decode("utf-8")))
print(repr(s.encode("utf-16")))
'Now iS tHe TIme for ALL gOOd PeoPLe'
b'Now iS tHe TIme for ALL gOOd PeoPLe'
'Now iS tHe TIme for ALL gOOd PeoPLe'
b'\xff\xfeN\x00o\x00w\x00 \x00i\x00S\x00 \x00t\x00H\x00e\x00 \x00T\x00I
\x00m\x00e\x00 \x00f\x00o\x00r\x00 \x00A\x00L\x00L\x00 \x00g\x00O\x00O
\x00d\x00 \x00P\x00e\x00o\x00P\x00L\x00e\x00'
s = "text string" # s now references a string object
help(s.find)
Help on built-in function find:
find(...)
S.find(sub [,start [,end]])) -> int
Return the lowest index in S where substring sub is found,
such that sub is contained within s[start:end]. Optional
arguments start and end are interpreted as in slice notation.
Return -1 on failure.
END <== type q to quit help
print
function writes strings to
the computer screen with some default formatting.
By default, print
adds a space between items separated
by commas, and a newline after all output.
To change the final output charactor, provide an end
argument, e.g., end=' '
.
To suppress the space between items, build up the output string using
the concatenation operator or formatting commands.
print('a', 'b')
a b
print('a' + 'b')
ab
s1 = 'Now is the time for all good people'
s2 = 'to cast their vote.'
print(s1, s2)
Now is the time for all good people to cast their vote.
print
function are converted
to strings automatically using a default format.
To output the data in a particular format, you must first create a string
from your data using a "format specification" that you provide.
The general form of a format specification is...
'The answer for question %d is %s.' % (2, 'wrong')
The answer for question 2 is wrong.
Here %d and %s are "formatting codes"
and (2, 'wrong') is a tuple of values (an integer and a string in this example).
Code | Conversion |
---|---|
%s | string |
%c | single character |
%d | decimal integer |
%f | floating-point (e.g., 3.141590) |
%e | floating-point (e.g., 3.141590e+00) |
%% | a literal '%' |
Character | Meaning |
---|---|
\n | newline |
\t | horizontal tab |
\' | single quote |
\" | double quote |
\\ | backslash (just one, not two) |
\0nn | octal value nn (e.g., \000 for a null character) |
str1 = "tom's book"
print('Did you know that %s\nis lost.' % str1)
Did you know that tom's book
is lost.
import math
n = math.pi
print('pi approximately equal to %f or %e using scientific notation' % (n, n))
pi approximately equal to 3.141593 or 3.141593e+00 using scientific notation
'The answer for question %d is %s.' % ('wrong', 2)
Traceback (most recent call last):
File "test.py", line 1, in ?
TypeError: %d format: a number is required, not str
def printProduct(i, j):
print(i * j, end=' ')
def printRow(n):
for i in range(1, 10): # this is a "for" loop (more about this in week 3)
printProduct(i, n) # call function printProduct 10 times
print() # start a new line
def printTable():
for i in range(1,10):
printRow(i)
printTable() # function printTable must be defined before here
Produces:
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
def printProduct(i, j):
print("%2d" % (i * j), end=' ')
...(everything else is the same as before)
Produces:
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
%
format operator
in Python 3 as well.
For example, you can control the field width used when printing values,
the precision of floating point numbers, whether numbers are zero padded,
if a blank space should be left before a positive number, and more.
format
method for strings.
Instead of using %
placeholders, the format
method looks for {}
instead.
"hello %d %s" % (3, "world")
'hello 3 world'
"hello {} {}".format(3, "world")
'hello 3 world'
"hello {howmany} {who}".format(who="world", howmany=3)
'hello 3 world'
print()
is a function which means
the parentheses are required...
print('pi is a very special number. It equals %f.' % n)
print
is a statement,
and the parentheses are optional. In fact,
if you include the parentheses when trying to print
multiple comma-separated values, it would be interpreted
as trying to print "a single tuple of values", rather than
"several values one after the other".end
argument is used to
control the final character printed, while in Python 2,
the only control one has is to supply a trailing comma to
suppress the output of the newline.
print("Here's some text", end="")
print(" and some more.")
Here's some text and some more.
Must be done like this in Python 2...
print "Here's some text",
print " and some more."
Here's some text and some more.
Operation | Interpretation |
---|---|
i = open('filename', 'r') | Open an existing text file for reading |
o = open('filename', 'w') | Create a new (or overwrite an existing) text file for writing |
i = open('filename', 'r+') | Open an existing text file for reading and writing |
str = i.read() | Read entire file into string 'str' |
str = i.read(N) | Read N characters into 'str' |
str = i.readline() | Read next line into 'str'. Returns an empty string upon end-of-file. |
for str in i: | Read next line into 'str'. Exit loop upon end-of-file. |
L1 = i.readlines() | Read all lines into list 'L1'. |
o.write(str) | Write string 'str' into the file |
o.writelines(L1) | Write strings in list L1 into the file |
i.seek(0) | Set current read pointer to beginning of the file |
o.close() | Close the file |
Operation | Interpretation |
---|---|
i = open('filename', 'rb') | Open an existing binary file for reading |
o = open('filename', 'wb') | Create a new (or overwrite an existing) binary file for writing |
i = open('filename', 'rb+') | Open an existing binary file for reading and writing |
bytes = i.read() | Read entire file into 'bytes' |
bytes = i.read(N) | Read N bytes into 'bytes' |
o.write(bytes) | Write 'bytes' into the file |
i.seek(0) | Set current read pointer to beginning of the file |
o.close() | Close the file |
out = open('/tmp/test', 'w')
s1 = "Now is the time for all good men\n"
s2 = "to come to the aid of their country.\n"
out.writelines([s1, s2])
out.close()
% cat /tmp/test
Now is the time for all good men
to come to the aid of their country.
i = open('/tmp/test', 'r')
s = i.read() # read entire file at once
print(s)
'Now is the time for all good men\nto come to the aid of their country.\n'
i.close()
i = open('/tmp/test', 'r')
i.readline() # read a line at a time
'Now is the time for all good men\n'
i.readline()
'to come to the aid of their country.\n'
i.readline()
'' <== empty string means end-of-file
io.TextIOWrapper
class may be used to
convert a binary data stream into a text stream.
The default encoding used by io.TextIOWrapper
is UTF-8 but may be replaced by other encodings.import urllib.request, io
binary_stream = urllib.request.urlopen(url)
text_stream = io.TextIOWrapper(binary_stream)
input()
for reading from the keyboard.
When input()
is called, it collects characters typed on the keyboard,
then when the user hits the Return or Enter key,
it returns a text string containing all the characters as the return value of the function.
It's a good idea to prompt the user to provide input,
and if a text string is supplied as an argument to input()
this string
is printed before collecting any input characters. So for example...
myString = input('Enter reaction constant: ')
reactK = float(myString)
print(reactK)
Produces...
Enter reaction constant: 22.59
22.59
Enter reaction constant: unknown
Traceback (most recent call last):
File "stdin", line 1, in ?
ValueError: invalid literal for float(): unknown
This type of error is easy to handle, but not until we learn about Python exception handling
using "try" and "except" statements in week 5.
raw_input()
instead of input()
.fin = open('words.txt', 'r')
for line in fin:
word = line.strip() # remove any leading or trailing white space characters like space and \n
if len(word) > 20:
print(word)
def has_no_e(word):
if word.find('e') == -1:
return True
return False
fin.seek(0) # reset file pointer to beginning of the file
numWords = 0
numNoEs = 0
print("\nThe words containing no e's are:")
for line in fin:
numWords += 1
word = line.strip()
if has_no_e(word):
numNoEs += 1
print(word)
print("Percentage of words with no e's = %f" % (float(numNoEs)/numWords/100.))
def uses_only(word, letters):
for c in word:
if c not in letters:
return False
return True
fin.seek(0)
print("\nThe words containing only the letters 'acefhlo' are:")
for line in fin:
word = line.strip()
if uses_only(word, 'acefhlo'):
print(word)
def is_abecedarian(word):
i = 0
while i < len(word)-1:
if word[i+1] < word[i]:
return False
i += 1
return True
fin.seek(0) # reset file pointer to beginning of the file
numWords = 0
numAbeced = 0
print("\nThe abecedarian words are:")
for line in fin:
numWords += 1
word = line.strip()
if is_abecedarian(word):
numAbeced += 1
print(word)
print("Percentage of abecedarian words = %f" % (float(numAbeced)/numWords/100.))