10 Values are objects
This chapter introduces the notion of an object, one of the most central aspects of Python. Once you catch your breath, you will love that all Python values are objects.
Methods
In Python, a value like an integer or string not only holds data. It is also packaged with a lot of useful functionality relevant to the particular type of value. When a value is packaged with such relevant functionality and meta information, programmers call it an object—and in Python, all values are objects.
The associated functionality comes in the form of methods. You can think of methods as functions that are packaged together with the value. For example, string values have a method called capitalize
. Try it out:
= "banana".capitalize()
x print(x)
To call the method on the string value, you connect the string value and the method call with a dot. So, to call a method on a value, you do the following:
- Write the value (or a variable name that substitutes for a value).
- Then write a
.
. - Then write the name of the method (like
capitalize
). - Then, write two parentheses to call the method. If the method takes any arguments other than the value it belongs to, then you write those additional values between the parentheses with commas in between, just as when you call a function.
You can see that the method call looks just like a function call, and in many ways, calling a method works much like calling a function. The difference is that when we call a function, we say: “Hey function, capitalize this string!”. When we call a method, we say: “Hey string, capitalize yourself!”
So why do we need methods? Why do we need them when we have functions? It is very handy to have some relevant and ready-to-use functionality packaged together with the data it works on. You will start to appreciate that sooner than you think.
Methods are almost always used with variables. So remember to make any substitutions and reductions required. When we put a method call after a variable like below, the variable is first substituted for its value, and then the method is called on the value. Consider the second line of this example:
= "banana"
x print(x.capitalize())
Here, x
is first substituted by "banana"
and then the method is called on that value, like this: "banana".capitalize()
.
Now write and run these examples:
= "Methods Are Cool"
message print(message)
= message.upper()
shout print(shout)
= message.lower()
whisper print(whisper)
= message.replace("Cool", "Fantastic")
new_message print(new_message)
You can see what these methods do. For example: upper
returns an uppercased copy of the string.
Exercise 10-1
Write and run the following code. What do you think it does?
= '\n\tSome text\n'
line print(">{}<".format(line))
= line.strip()
line print(">{}<".format(line))
Make sure you do the substitution and reduction steps in your head. Be especially careful about the third line of code. Also, what do you think the special \t
character is?
Exercise 10-2
The string methods you have tried so far have all returned a new string. Try this example:
'ATGACGCGGA'.startswith('ATG')
and this
'ATGACGCGGA'.endswith('ATG')
What do the methods do, and what do they return?
Using the Python documentation
Now that you are well underway to becoming a programmer, you should know your way around the Python documentation. Especially the part called the Python standard library. There is a lot of details in there that we do not cover in this course. These are mainly tools and techniques for writing more efficient, extensible, robust, and flexible code. The parts we cover in this course are the minimal set that will allow you to write a program that can do anything.
Exercise 10-3
There is a string method that returns a secret agent:
print('7'.zfill(3))
You can look it up in the Python documentation.
Exercise 10-4
Browse through all the string methods to get an impression of all the functionality that is packaged with string objects.
String formatting
You have already tried string formatting in Section 10.0.0.1. String formatting is a simple but powerful technique that lets you generate pretty strings from pre-computed values. You may have noticed that many decimals are shown every time we print a floating-point number. It is not very pretty if you are only interested in two decimals. You use the format
method (surprise) to format a string. In its most straightforward use, format
replaces occurrences of {}
with the arguments that are passed to it - like this:
= "genus:{}, species:{}".format('Homo', 'sapiens') taxon
Exercise 10-5
What happens if you try this?
= "Was {} {} Swedish?".format('Carl', 'Linneaus') question
and this?
= "Was {} Swedish?".format('Carl', 'Linneaus') question
and this?
= "Was {} {} Swedish?".format('Carl Linneaus') question
In the two last examples, the number of {}
did not match the number of arguments to format
. What happens when there are too few and when there are too many?
Exercise 10-6
Consider this code:
= "{} is larger than {}".format(4, 3)
s print(s)
What will happen if you run this code? Write the code and see for yourself once you think you know. If you were wrong, make sure you understand why.
Exercise 10-7
Consider this code:
= 'Python'
language = 'sliced bread'
invention = '{} is the best thing since {}'.format(language, invention)
s print(s)
What will happen if you run this code? Write the code and see for yourself once you think you know. If you were wrong, make sure you understand why.
Exercise 10-8
Consider this code:
= '{} is the best thing since {}'
my_template = 'Python'
language print(my_template.format(language, 'sliced bread'))
print(my_template.format(language, 1900 + 89))
What will happen if you run this code? Do the substitution and reduction steps in your head.
Exercise 10-9
Think back to Section 5.0.0.3, where you calculated how many cookies you could buy for 30 kr. The bars are 7 kr. So your program looked something like this:
= 30 / 7
nr_bars print('I can buy', nr_bars, 'chocolate bars!')
and it ran like this: python chocolate.py
I can buy 4.285714285714286 chocolate bars!
String formatting lets you rewrite the program like this:
= 30 / 7
nr_bars = "I can buy {} chocolate bars!".format(nr_bars)
message print(message)
Try to replace {}
with {:.2f}
. format
reads the stuff after the colon in each set of curly brackets and uses it as directions for formatting the value it inserts. Try it out and see what happens if you change the number 2
to 3
, 4
, 5
or 10
.
Exercise 10-10
See if you can find the documentation for the format
function in the Python documentation. It can do wondrous things, for this course we will only try to control the number of digits and padding with spaces. Look at the examples below. Maybe you can figure out how it works.
= 3.14159265359
pi print("*{}*".format(pi))
print("*{:.3f}*".format(pi))
print("*{:.6f}*".format(pi))
print("*{:>5.3f}*".format(pi))
print("*{:>10.3f}*".format(pi))
Exercise 10-11
This is bonus info rather than an actual exercise. How do you think Python can figure out that adding strings is supposed to work differently than adding numbers? Remember that '1' + '2'
is '12'
not 3
. The answer is that all values you can add with the +
operator have a secret method called __add__
that defines how adding works for that type of value:
= "11"
s1 = "22"
s2 = 11
n1 = 22
n2 print(s1 + s2)
print(s1.__add__(s2))
print(n1 + n2)
print(n1.__add__(n2))
This is one of many examples of how objects allow Python to implement functionality that fits each value type. This was to show how Python does this. Like yellow and black stripes in nature means “don’t touch me!” – double underscores (__
) is Python’s way of saying “do not use this!”. You are supposed to use the +
operator, not the __add__
method.
Indexing and slicing strings
Another feature of string objects is that they allow you to extract individual parts of the string.
Each character in a string is identified by its index in the string. To access a character in a list, you write brackets after the string. Between those brackets, you specify the index of the character you want. The first character has an index of 0; the second has an index of 1, and so on.
= 'ATG'
codon print("first base is", codon[0])
print("second base is", codon[1])
print("third base is", codon[2])
You may wonder why the index of the first character is zero and not one. That is simply the convention in programming and is so for good reason. Over time you will begin to find this useful rather than annoying. You should think of the index as the offset from the start of the string.
That also means that the index is not the length of the string but the length minus one:
= 'ARNDCQEGHILKMFPSTWYV'
amino_acids = len(amino_acids)-1
last_index print("Last amino acid is", amino_acids[last_index])
If you want a sub-string from a larger string (we call that a slice), you specify a start index and an end index separated by a colon:
print(amino_acids[1:4])
When you run that, you can see that amino_acids[1:4]
is substituted for 'RND'
, so the slicing operation produces a sub-string of amino_acids
. You may wonder why the value at index 4 is not in the resulting sub-string. That is another programming convention: intervals are ends exclusive. So when you specify an interval with a start index of 1 and an end index of 4, it represents all the characters starting from 1 and up to, but not including, 4. So, the slice 1:4
corresponds to the characters at indexes 1, 2, and 3. The reason programmers handle intervals in this way is that it makes it easier to write clear and simple code as you will see in the exercises.
Exercise 10-12
What does this expression reduce to?
"Futterwacken"[7]
Exercise 10-13
What is printed here? Do all the substitution and reduction steps and compare to the exercise above.
= "Futterwacken"
s print(s[7])
Exercise 10-14
What is printed here? Do all the substitution and reduction steps – and do it twice. Next week you will be happy you did.
= 'TGAC'
dna = 0
i print(dna[i])
= 1
i print(dna[i])
= 2
i print(dna[i])
Exercise 10-15
What do you think happens here? Make up your mind and try out the code below:
= "Futterwacken"
s 6] = 'W' s[
Did you see that coming? Strings are immutable, which means that you cannot change them once you have made them. If you want "FutterWacken"
you need to produce a new string with that value. Try to figure out how to do that with the replace
method of strings.
Exercise 10-16
When you do not specify a slice’s start and/or end, Python will assume sensible defaults for the start and end indexes. What do you think they are? Make up your mind and try out the code below:
= 'abcdefghijklmnopqrstuvxyz'
s print(s[:11])
print(s[11:])
print(s[:])
Exercise 10-17
Find the documentation for how the slicing of strings works.
Exercise 10-18
What do you think happens when you specify an index that does not correspond to a value in the list:
= 'abcdefghijklmnopqrstuvxyz'
alphabet print(alphabet[99])
Read and make sure you understand the error message. You can try to Google the error message.
Exercise 10-19
Do you think you also get an error when you specify a slice where the end is too high? Try it out:
= 'abcdefghijklmnopqrstuvxyz'
alphabet print(alphabet[13:99])
and this:
= 'abcdefghijklmnopqrstuvxyz'
alphabet print(alphabet[10000:10007])
I guess that is worth remembering.
Exercise 10-20
Which character in a string named alphabet
does this expression reduce to?
len(alphabet)-1] alphabet[
Exercise 10-21
Because intervals are “ends exclusive” ,we can compute the length of a slice as end - start
:
= "ATGAGGTCAAG"
dna = 1
start = 4
end print("{} has length {}".format(dna[start:end], end-start))
Figure out what this code would look like if ends were included in intervals.
Exercise 10-22
Another advantage of “ends exclusive” intervals is that you only need one index to split a string in two:
= 'Banana'
s = 3
idx = s[:idx]
beginning = s[idx:]
end print(beginning + end)
Figure out what indexes you would need to use to split a sequence in two if ends were included in intervals.
Exercise 10-23
Did you look up the details of how slicing works in Section 10.0.0.17? Then you should be able to explain what happens here:
= 'zyxvutsrqponmlkjihgfedcba'
s print(s[::-1])
General exercises
Exercise 10-24
Will this print Bananas rule!
? Do all the substitutions and reductions.
if 'na' * 2 == "Banana"[2:]:
print("Bananas rule!")
Exercise 10-25
Will this print Bananas rule!
? Do all the substitutions and reductions.
if "{}s".format('Banana'[1:].capitalize()) == 'Ananas':
print("Bananas rule!")
Exercise 10-26
Write a function called even_string
that takes a string argument and returns True
if the length of the string is an even number and False
otherwise. E.g. even_string('Pear')
should return True
and even_string('Apple')
should return False
(remember the modulo
operator?).
Exercise 10-27
Look at the code below and decide what is printed at the end. Then, write the code and test your prediction. If you are wrong, figure out why by revisiting the chapter about functions.
def enigma(x):
if x == 4:
return x
= enigma(5)
result print(result)
Exercise 10-28
Inspect the code below and determine why it does not print that you are a super star. Test the function using various inputs and identify the mistake.
def even_number(x):
if x % 2:
return False
if even_number(4):
print('You are a super star!')