Here are our solutions for the day 12 exercises in the 30 Days of Python series. Make sure you try the exercises yourself before checking out the solutions!
1) Define four functions: add
, subtract
, divide
, and multiply
. Each function should take two arguments, and they should print the result of the arithmetic operation indicated by the function name.
There are a couple of additional details we have to keep in mind for this problem.
First, for some operations, the order of the operands is important. 12 / 4
is not the same thing as 4 / 12
, after all, while 5 + 7
and 7 + 5
are identical operations. In cases where the order of the operands is important, we should treat the first argument to the function and the left operand, and the second argument as the right operand.
This means that 12 / 4
will be called as divide(12, 4)
.
The other thing we have to keep in mind is that division by 0
is going to produce an exception. If we try, we're going to get a ZeroDivisionError
:
Traceback (most recent call last):
File "main.py", line 1, in <module>
8 / 0
ZeroDivisionError: division by zero
There's nothing wrong with letting this error bubble up to the surface, but in our case we're going to check if the second operand for division is 0
, and we're going to print a message to the user rather than crashing the program.
Let's start by defining the add
function. You can use whatever parameter names you like for these functions. I'm just going to call the operands a
and b
.
def add(a, b):
print(a + b)
Here we've defined two parameters, which means add
requires two arguments. These argument values get assigned to our parameters when we call the function, and we can refer to these values using the parameter names in our function body.
We're going to assume the user passes us numbers, so we can just print the result of the expression, a + b
.
subtract
and multiply
are very much the same, but we have to be careful to keep the order of the operands correct for subtract
:
def add(a, b):
print(a + b)
def subtract(a, b):
print(a - b)
def multiply(a, b):
print(a * b)
Don't forget to put two empty lines between the function definitions!
divide
is ever so slightly more complicated, because we have to check that the second parameter is not 0
. We can accomplish this with a simple conditional statement:
def add(a, b):
print(a + b)
def subtract(a, b):
print(a - b)
def multiply(a, b):
print(a * b)
def divide(a, b):
if b == 0:
print("You can't divide by 0!")
else:
print(a / b)
You might be thinking, what if b
is 0.0
? The condition will still work in this case. Python is smart enough to know that 0.0
and 0
are the same thing.
Make sure to test all of your functions work correctly, and make sure you test both a zero and non-zero value for divide
.
2) Define a function called print_show_info
that has a single parameter. The argument passed to it will be a dictionary with some information about a T.V. show. The print_show_info
function should print the information stored in the dictionary, in a nice way.
The goal of this exercise is to define a function called print_show_info
that can take in a dictionary like this:
tv_show = {
"title": "Breaking Bad",
"seasons": 5,
"initial_release": 2008
}
And output a string like this:
Breaking Bad (2008) - 5 seasons
Our print_show_info
, and it's going to take a single parameter, which I'm going to call show
. show
is going to expect a dictionary in the format above.
def print_show_info(show):
pass
Here I've written pass
, which just means "do nothing". It's useful for when we're creating structures in our code that require a body, but we don't know what it should be yet. If we leave it blank, Python will complain, so pass
is a very useful placeholder.
In this case, we want our function to print the show data in a nice format, and I'm going to use the example above as a template. We can just access the values in the provided dictionary by accessing keys of show
.
def print_show_info(show):
print(f"{show['title']} ({show['initial_release']}) - {show['seasons']} season(s)")
Now we just have to call our function!
def print_show_info(show):
print(f"{show['title']} ({show['initial_release']}) - {show['seasons']} season(s)")
tv_show = {
"title": "Breaking Bad",
"seasons": 5,
"initial_release": 2008
}
print_show_info(tv_show)
3) Below you’ll find a list containing details about multiple TV series. Use your function, print_show_info, and a for loop, to iterate over the series list, and call your function once for each iteration, passing in each dictionary.
series_data = [
{"title": "Breaking Bad", "seasons": 5, "initial_release": 2008},
{"title": "Fargo", "seasons": 4, "initial_release": 2014},
{"title": "Firefly", "seasons": 1, "initial_release": 2002},
{"title": "Rick and Morty", "seasons": 4, "initial_release": 2013},
{"title": "True Detective", "seasons": 3, "initial_release": 2014},
{"title": "Westworld", "seasons": 3, "initial_release": 2016},
]
Since we already have our function defined, there's not much for us to do other than write the actual loop. I'm going to use show
as a loop variable, so my loop definition is going to look like this:
for show in series_data:
pass
Now we just have to call our function in the loop body, passing in show
as an argument, since one of our dictionaries is going to get assigned to show
for each iteration of the loop:
for show in series_data:
print_show_info(show)
The full solution therefore looks like this:
def print_show_info(show):
print(f"{show['title']} ({show['initial_release']}) - {show['seasons']} season(s)")
series_data = [
{"title": "Breaking Bad", "seasons": 5, "initial_release": 2008},
{"title": "Fargo", "seasons": 4, "initial_release": 2014},
{"title": "Firefly", "seasons": 1, "initial_release": 2002},
{"title": "Rick and Morty", "seasons": 4, "initial_release": 2013},
{"title": "True Detective", "seasons": 3, "initial_release": 2014},
{"title": "Westworld", "seasons": 3, "initial_release": 2016},
]
for show in series_data:
print_show_info(show)
This should give us output like this:
Breaking Bad (2008) - 5 season(s)
Fargo (2014) - 4 season(s)
Firefly (2002) - 1 season(s)
Rick and Morty (2013) - 4 season(s)
True Detective (2014) - 3 season(s)
Westworld (2016) - 3 season(s)
4) Create a function to test if a word is a palindrome. A palindrome is a string of characters that are identical whether read forwards or backwards.
This exercise is a little bit tricky, and it's actually a fairly common interview question. We have a few different ways of going about this, and I'll show off a few different methods.
First things first, we need to define our function, which is going to take in a word
. We're going to want to clean this string up a bit, by removing any whitespace and changing all the characters to the same case.
def is_palindrome(word):
word = word.strip().lower()
From here, we can take a number of approached. The first approach I want to show is using lists and the reversed
function.
We have to be a little careful with reversed
, because it's going to give us a lazy type, and its value is not going to be equivalent to a string in any case. We're going to have get the characters out of the reversed
object. We're going to do this by converting it to a list in this case.
def is_palindrome(word):
word = word.strip().lower()
reversed_word = reversed(word)
if list(word) == list(reversed_word):
print(True)
else:
print(False)
Note that for the comparison we also have to convert the word
to a list. That's because Python doesn't consider something like "hannah"
to be the same as ["h", "a", "n", "n", "a", "h"]
.
We can test our function with a few cases like so:
def is_palindrome(word):
word = word.strip().lower()
reversed_word = reversed(word)
if list(word) == list(reversed_word):
print(True)
else:
print(False)
is_palindrome("Hannah") # True
is_palindrome("Fred") # False
That all seems to be working.
Instead of using lists, we could also use join
to create a string from the reversed
object:
def is_palindrome(word):
word = word.strip().lower()
reversed_word = reversed(word)
if word == "".join(reversed_word):
print(True)
else:
print(False)
is_palindrome("Hannah") # True
is_palindrome("Fred") # False
Here our join
string is empty, which means we want nothing to go between the items in word
when we create our new string.
As you can see, the result is the same.
A similar approach uses the reverse
method for list. In this case, we turn word
to a list, and we create a copy of it. We can then reverse this copy and compare the lists.
We have to be careful with this approach though, because we just want a copy of the values. If we try to do something like this:
def is_palindrome(word):
word = list(word.strip().lower())
reversed_word = word
reversed_word.reverse()
Both names refer to the same list. If we reverse that list, both names now refer to the same reversed list.
There are a couple of ways around this. First, we can pass the word
to list
when performing the reversed_word
assignment:
def is_palindrome(word):
word = list(word.strip().lower())
reversed_word = list(word)
reversed_word.reverse()
list
creates a new list, so we create a second list with identical values. Lists also have a method called copy
for doing this as well:
def is_palindrome(word):
word = list(word.strip().lower()):
reversed_word = word.copy()
reversed_word.reverse()
Either of these is fine. We can then perform a direct comparison of the lists:
def is_palindrome(word):
word = list(word.strip().lower())
reversed_word = word.copy()
reversed_word.reverse()
if word == reversed_word:
print(True)
else:
print(False)
is_palindrome("Hannah") # True
is_palindrome("Fred") # False
The final method I want to show you is using slices, as they offer an extremely elegant solution in this case:
def is_palindrome(word):
word = word.strip().lower()
if word == word[::-1]:
print(True)
else:
print(False)
is_palindrome("Hannah") # True
is_palindrome("Fred") # False
The [::-1]
is covered in another blog post, but it basically means, "give me the whole sequence in reverse order".
This means we can check word
against the reverse of word
without needing to do any type conversions, or using join
.
If you prefer, we could use variable names to better describe what this value means:
def is_palindrome(word):
word = word.strip().lower()
reversed_word = word[::-1]
if word == reversed_word:
print(True)
else:
print(False)
is_palindrome("Hannah") # True
is_palindrome("Fred") # False
If you want to have a go at a more complicated version of this exercise, check out our post on finding palindromes. We walk through a lot of these solutions in more detail, and we talk about finding palindromes when punctuation is involved, or when we're dealing with full sentence palindromes.