Kaggle — Learn Python Challenge: Day 2

Editor: Ishmael Njie

DataRegressed Team
DataRegressed
6 min readJun 12, 2018

--

If you have not seen Day 1 to this Python sprint:

  • Here is my story on it! — There you can find links to my Kaggle Kernel of the Exercises as well as the introductory notebook by Colin Morris.

Now onto Day 2!

Day 2 of the challenge was centred around Functions and Getting Help. This consisted of functions in Python, user defined functions, using the help function and small debugging tips. The introductory notebook is very key for the exercises ahead so I suggest you read through that notebook first!

In this post, I am going to give an outline of the Exercises in Day 2:

  • Exercise 1:

This first exercise needed to be completed to fit the docstring. A docstring is a string that conventionally comes after the header of a user defined function so that when the help() function is called on our function, it will show the docstring. It is there to provide insight as to what the function is supposed to output.

The following function is to produce a rounded number to 2 decimal places.

def round_to_two_places(num):
"""Return the given number rounded to two decimal places.

>>> round_to_two_places(3.14159)
3.14
"""
return round(num,2) <- CODED THIS

As you can see, the docstring provides information about the function and an example of its correct output. Check out my notebook for the use of the help function for this particular problem.

  • Exercise 2:

This exercise was geared to demonstrate the use of the round() function with a negative number as its second argument.

round(122.54,-2)

A negative number as the second argument of this round function will round to the nearest powers of 10.

-1 will round to the nearest 10, -2 will round to the nearest 100 etc. So the expected output of the cell above will be 100.0

  • Exercise 3:

In Day 1’s set of exercises, exercise 4 was on sharing candies between Alice, Bob and Carol.

The exercise wanted to produce the number of candies to smash given that they had shared the other candies equally between the 3 of them; using the modulus operator.

In today’s exercise, the aim was to create a function that returned the candies to be smashed. However, the twist was that the function should consider scenarios where there are not only 3 friends, but say, an n number of friends.

def to_smash(total_candies, friends = 3): <- CODED 'friends = 3'
"""Return the number of leftover candies that must be smashed after distributing the given number of candies evenly between n friends, where 3 friends is the default.

>>> to_smash(91,3)
1

>>> to_smash(91,4)
3
"""
return total_candies % friends

In the function, ‘friends = 3’ is a default setting of the function, meaning that if a second argument is not defined, ie. if a number of friends is not explicitly defined, then the function is going to assume 3 friends.

  • Exercise 4:

Part 1:

This exercise focused on reading errors and eventually correcting the errors.

Given the cell below:

ruound_to_two_places(9.9999)

We can tell that there is something wrong with this line of code. If we refer to Exercise 2, we defined a function ‘round_to_two_places’ to round a number to 2 decimal places. However, because the function above is spelt wrong, Python cannot recognise this function being called, that is why an exception is thrown:

---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-13-9547bd109d11> in <module>()
----> 1 ruound_to_two_places(9.9999)

NameError: name 'ruound_to_two_places' is not defined

To handle the error, just simply spell the function name correctly!

Part 2:

x = -10
y = 5
# Which of the two variables above has the smallest absolute value?
smallest_abs = min(abs(x, y))

The error here is not as straightforward if you are unsure about what arguments each function is to take.

Error Message:

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-15-65ed4db8c6e3> in <module>()
2 y = 5
3 # Which of the two variables above has the smallest absolute value?
----> 4 smallest_abs = min(abs(x, y))

TypeError: abs() takes exactly one argument (2 given)

The error message here tells us that the abs() function can only take one argument, however, in the code above, it has taken 2 arguments, x and y.

To handle this error, we need to take the absolute value of each value separately, then apply the min function on the 2 stored variables:

def smallest_abs(a,b):
i1 = abs(a)
i2 = abs(b)
return min(i1,i2)

Part 3:

def f(x):
y = abs(x)
return y

print(f(-5))

The error here is fairly clear to see given you understand user defined functions in Python. The ‘return’ keyword needs to be indented into the function.

def f(x):
y = abs(x)
return y # Correct indentation of 'return'

print(f(-5))
  • Exercise 5:

For this exercise, the ‘time’ module will be used. The time function gives an output of the number of seconds that have passed since the Epoch.

The sleep function pauses the environment for a number of seconds.

For the following function, we had to code the main body for the function in accordance with the docstring.

def time_call(fn, arg):
"""Return the amount of time the given function takes (in seconds) when called with the given argument.
"""
t1 = time() # Time before
fn(arg)
t2 = time() #Time after
Time_Taken = t2-t1 #Difference in time
return Time_Taken
pass

For a given function (sleep), ‘time_call’ will output the time taken for a function to run given an argument pertaining to that particular function.

For example, if we call the time_call function on the sleep function and an argument of 5 seconds, we would assume that the time_call will output a number close to the number 5.

  • Exercise 6:

This exercise uses the function ‘time_call’ from exercise 5. We are to create a function that returns the amount of time taken by the slowest of 3 function calls.

def slowest_call(fn, arg1, arg2, arg3):
"""Return the amount of time taken by the slowest of the following function calls: fn(arg1), fn(arg2), fn(arg3)
"""
# Function taken from cells in question 5
t1 = time_call(fn,arg1)
t2 = time_call(fn,arg2)
t3 = time_call(fn,arg3)

return max(t1,t2,t3) #Max time taken = slowest time


pass

Here, I created variables for the time taken for each function call on a given argument, then returned the max of the 3 times which would output the time of the slowest function call.

slowest_call(sleep, 2, 4, 6)

Given the function above, one would assume that the function will return a number close to 6, as 6 seconds would be the slowest time for the sleep() function on the 3 arguments.

  • Exercise 7:

This was a demonstration on nested Python code.

print(print("Spam"))

The output for this line of code would be:

Spam
None

This is because Python evaluates nested function calls from the inside out. So first it evaluates the inner print function; which would print the string ‘Spam’. Then the outer print function becomes print(None) which will print None.

  • Exercise 8:

The last exercise was testing a function to its limits. Based on the docstring, the function is to return which ever of the string arguments is the smallest number.

def smallest_stringy_number(s1, s2, s3):
"""Return whichever of the three string arguments represents the smallest number.

>>> smallest_stringy_number('1', '2', '3')
'1'
"""
return min(s1, s2, s3)

If we test the function:

smallest_stringy_number('1', '2', '3')

This will output ‘1’, which is correct. However, if the string ‘10’ is included as an argument instead of the ‘1’, we encounter a problem.

smallest_stringy_number('10', '2', '3')

This outputs ‘10’. We expected the output to be ‘2’. The problem is that the min function in Python returns the argument that comes first in lexicographic order; the logic that is used to order dictionaries. It has looked at the first character in the ‘10’ string and recognised that it is a ‘1’; it has then ordered this string as the first number, which indicates that it is the smallest.

To modify this, we will pass in a function using the ‘key’ argument.

def smallest_stringy_number(s1, s2, s3):
return min(s1, s2, s3,key=int)

We pass the ‘int’ function using the ‘key’ argument. The function will now return the string value that has the lowest value given the ‘int’ function.

Another reminder to view the Kaggle Kernel for this story, and keep an eye out for Day 3!

--

--