Matthieu Choplin
A type or a class is what is going to create an object
Type and object seen so far:
Types | Objects | Constructor |
---|---|---|
Integer | 1, 3, 4, 5, 999, -3, -4 | int() |
Float | 1.333, -0.5, 0.001 | float() |
String | "Foo", 'bar', "" | str() |
You can find the method of an object with the function dir(), which returns the attributes of an object.
>>> dir("abc")
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
NB: the dunder methods (with double underscore), are "special methods" in python that can be overridden. We will come back on that later.
The methods of an object can only be called on an object.
>>> "speak louder".upper()
'SPEAK LOUDER'
A builtin function does not need an object to be called.
>>> len("number of character")
19
NB: len() give the number of element in a sequence
Creating list using the list constructor
list1 = list() # Create an empty list
list2 = list([2, 3, 4]) # Create a list with elements 2, 3, 4
list3 = list(["red", "green", "blue"]) # Create a list of strings
list4 = list(range(3, 6)) # Create a list with elements 3, 4, 5
list5 = list("abcd") # Create a list with characters a, b, c
That is the equivalent of:
list1 = [] # Same as list()
list2 = [2, 3, 4] # Same as list([2, 3, 4])
list3 = ["red", "green"] # Same as list(["red", "green"])
You can find the different methods of a list thanks to the function dir()
>>> dir([])
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
We are going to look at: 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'
Look at the builtin help:
>>> help([].append)
Help on built-in function append:
append(...) method of builtins.list instance
L.append(object) -> None -- append object to end
Experiment in the interpreter:
append(x: object): None | Add an item x to the end of the list. |
insert(index: int, x: object): None | Insert an item x at a given index. Note that the first element in the list has index 0. |
remove(x: object): None | Remove the first occurrence of the item x from the list. |
index(x: object): int | Return the index of the item x in the list. |
count(x: object): int | Return the number of times item x appears in the list. |
sort(): None | Sort the items in the list. |
reverse(): None | Reverse the items in the list. |
extend(L: list): None | Append all the items in list L to the list. |
pop([i]): object | Remove the item at the given position and return it. The square bracket denotes that parameter is optional. If no index is specified, list.pop() removes and returns the last item in the list. |
Write a program that reads integers from the user and stores them in a list (use input() and append()). Your program should continue reading values until the user enters 'q' (the sentinel value). Then it should display all of the values entered by the user in order from smallest to largest, with one value appearing on each line. Use either the sort method or the sorted built in function to sort the list.
Solution
Hide solution
data = []
num = input("Enter an integer ('q' to quit): ")
while num != 'q':
data.append(int(num))
num = input("Enter an integer ('q' to quit): ")
data.sort()
print("The values, sorted into ascending order are:")
for element in data:
print(element)
>>> list1 = [2, 3, 4, 1, 32]
>>> len(list1)
5
>>> max(list1)
32
>>> min(list1)
1
>>> sum(list1)
42
>>> import random
>>> random.shuffle(list1) # Shuffle the items in the list
>>> list1
[4, 1, 2, 32, 3]
The list is a sequence on which you can iterate.
With for:
With while:
We define the function like this:
def main():
print('The function', main.__name__, 'has been called')
And we call the functions like this:
main()
NB: notice the brackets: when we define and when we call!
Try to use functions in the next exercises.
Simplify the exercise we saw at the end of session 2 by using a list of string storing all the animals name, instead of multiple if and elif statement.
Solution
Hide solution
def main():
year = int(input("Enter a year: "))
animals = ["monkey", "rooster", "dog", "pig", "rat", "ox",
"tiger", "rabbit", "dragon", "snake", "horse", "sheep"]
print(year, "is", animals[year % 12])
main()
Example: a function that returns a reversed list
The function reverse actually exists for doing the same thing
Complete this program to get the minimum number of the list and its index
import random
random_list = [random.choice(list(range(1, 100))) for _ in range(10)]
def get_min(random_list):
# to complete
pass
get_min(random_list)
Solution
Hide solution
import random
random_list = [random.choice(list(range(1, 100))) for _ in range(10)]
def get_min_index(any_list):
min = 100
index = 0
for i in any_list:
if i <= min:
min = i
min_index = index
index += 1
print("the min is", min)
print("its index is", min_index)
print(random_list)
get_min_index(random_list)
Solution
Hide solution
import random
random_list = [random.choice(list(range(1, 100))) for _ in range(10)]
def get_min_index(any_list):
print("the min is", min(any_list)) # using the min builtin
print("its index is", random_list.index(min(random_list))) # using the index method
print(random_list)
get_min_index(random_list)
The string is a sequence
The items of a sequence can be accessed through indexes
Items (characters) | a | b | r | a | c | a | d | a | b | r | a |
---|---|---|---|---|---|---|---|---|---|---|---|
Indexes | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Get the first element of the sequence:
my_string_variable = "abracadabra"
first_elem = my_string_variable[0]
You can also access element of a list with indexes BUT you can also modify them:
contrary to the string type.
+ is for concatenating list
* is for repeating a list
[ : ] is the slice operator, for extracting a sublist from a list
>>> list1 = [2, 3]
>>> list2 = [1, 9]
>>> list3 = list1 + list2
>>> list3
[2, 3, 1, 9]
>>> list3 = 2 * list1
>>> list3
[2, 3, 2, 3]
>>> list4 = list3[2:4]
>>> list4
[2, 3]
>>> list1 = [2, 3, 5, 2, 33, 21]
>>> list1[-1]
21
>>> list1[-3]
2
>>> list1 = [2, 3, 5, 2, 33, 21]
>>> 2 in list1
True
>>> list1 = [2, 3, 5, 2, 33, 21]
>>> 2.5 in list1
False
>>> list1 = [x for x in range(0, 5)]
>>> list1
[0, 1, 2, 3, 4]
>>> list2 = [0.5 * x for x in list1]
>>> list2
[0.0, 0.5, 1.0, 1.5, 2.0]
>>> list3 = [x for x in list2 if x < 1.5]
>>> list3
[0.0, 0.5, 1.0]
You can convert a string to a list with the split function on string.
>>> items = "Welcome to the UK".split()
>>> print(items)
['Welcome', 'to', 'the', 'UK']
>>> items = "34#13#78#45".split("#")
>>> print(items)
['34', '13', '78', '45']
You can convert back a list to a string with the join function on string
>>> print(items)
['Welcome', 'to', 'the', 'UK']
>>> print(" ".join(items))
'Welcome to the UK'
Write a function that returns a new list by eliminating the duplicate values in the list. Use the following function header:
def eliminateDuplicates(lst):
Write a test program that reads in a list of integers, invokes the function, and displays the result. Here is the sample run of the program:
Enter ten numbers: 1 2 3 2 1 6 3 4 5 2 The distinct numbers are: 1 2 3 6 4 5
Solution
Hide solution
def main():
# Read numbers as a string from the console
s = input("Enter numbers: ")
items = s.split() # Extracts items from the string
numbers = [ int(x) for x in items ] # Convert items to numbers
print("The distinct numbers are:", eliminateDuplicates(numbers))
def eliminateDuplicates(list):
result = []
for element in list:
if not (element in result):
result.append(element)
return result
main()
Write a function that checks whether two words are anagrams. Two words are anagrams if they contain the same letters. For example, silent and listen are anagrams. The header of the function is:
def isAnagram(s1, s2):
(Hint: Obtain two lists for the two strings. Sort the lists and check if two lists are identical.)
Write a test program that prompts the user to enter two strings and, if they are anagrams, displays is an anagram; otherwise, it displays is not an anagram.
Solution
Hide solution
def main():
s1 = input("Enter the first string: ").strip()
s2 = input("Enter the second string: ").strip()
print(s1, "and", s2, "are",
("anagram." if isAnagram(s1, s2) else "not anagram."))
def isAnagram(s1, s2):
if len(s1) != len(s2):
return False
newS1 = sort(s1);
newS2 = sort(s2);
return newS1 == newS2
def sort(s):
r = list(s)
r.sort()
result = ""
for ch in r:
result += ch
return result
main()
Often, in a program, you need to duplicate a list or a part of a list. In such cases you could attempt to use the assignment statement (=):
list1 = [1, 2, 3]
list2=list1
But you are not copying the list here! You are copying its reference.
>>> list2 = [x for x in list1]
>>> list2 = list1[:]
>>> list2 = list(list1)
>>> list2 = list(list1)
>>> import copy
>>> list2 = copy.copy(list1)
>>> list2 = copy.deepcopy(list1) # will copy the object as well
There are important differences between passing immutable or mutable objects as arguments to a function.
String and numeric values (integer and float) are immutable, they do not get changed
Lists are mutable, they can be changed
Write a hangman game that randomly generates a word and prompts the user to guess one letter at a time, as shown in the sample run.
Each letter in the word is displayed as an asterisk. When the user makes a correct guess, the actual letter is then displayed. When the user finishes a word, display the number of misses and ask the user whether to continue playing. Create a list to store the words, as follows:
words = ["write", "that", "program", ...]
(Guess) Enter a letter in word ******* > p (Guess) Enter a letter in word p****** > r (Guess) Enter a letter in word pr**r** > p p is already in the word (Guess) Enter a letter in word pr**r** > o (Guess) Enter a letter in word pro*r** > g (Guess) Enter a letter in word progr** > n n is not in the word (Guess) Enter a letter in word progr** > m (Guess) Enter a letter in word progr*m > a The word is program. You missed 1 time Do you want to guess another word? Enter y or n>
Solution
Hide solution
import random
def main():
words = ["write", "program", "that", "receive", "positive", "change", "study", "excellent", "nice"]
while True:
index = random.randint(0, len(words) - 1)
hiddenWord = words[index]
guessedWord = len(hiddenWord) * ['*']
numberOfCorrectLettersGuessed = 0
numberOfMisses = 0
while numberOfCorrectLettersGuessed < len(hiddenWord):
letter = input("(Guess) Enter a letter in word " + toString(guessedWord) + " > ").strip()
if letter in guessedWord:
print("\t", letter, "is already in the word")
elif hiddenWord.find(letter) < 0:
print("\t", letter, "is not in the word")
numberOfMisses += 1
else:
k = hiddenWord.find(letter)
while k >= 0:
guessedWord[k] = letter
numberOfCorrectLettersGuessed += 1
k = hiddenWord.find(letter, k + 1)
print("The word is " + hiddenWord + ". You missed "
+ str(numberOfMisses) + (" time" if (numberOfMisses <= 1) else " times"))
anotherGame = input("Do you want to guess for another word? Enter y or n> ").strip()
if anotherGame == 'n':
print("Finished")
break
def toString(list):
s = ""
for e in list:
s += e
return s
main()