Kaggle — Learn Python Challenge: Day 3
Editor: Ishmael Njie
Here we are with Day 3 of the Learn Python Challenge hosted by Kaggle!
I also have Day 1 & 2 up so go check those out!
Now onto Day 3!
Day 3 was on booleans and conditionals. A boolean is a type in Python which can take two values: True or False. The introductory notebook covered comparison operations, combining boolean values and conditional statements (if-statements).
Let’s get into the Exercises; my notebook for this Exercise can be found here!:
- Exercise 1:
The task was to define a function called ‘sign’ which took numerical arguments and returned a certain value depending on whether it was negative (-1), positive (1) or 0 (0).
def sign(x):
if x == 0:
return 0
elif x < 0:
return -1
elif x > 0:
return 1
The ‘elif’ keyword is used to add many more conditions to the function; you may have as many ‘elif’ statements as you need. Refer to today’s notebook of mine to see the function in action!
- Exercise 2
Referring to yesterday’s and Day 1’s exercises, we looked at functions and blocks of code that related to candies being smashed as a result of sharing a number of candies equally.
In today’s exercise, we looked to add to the ‘to_smash’ function.
def to_smash(total_candies):
"""Return the number of leftover candies that must be smashed after distributing the given number of candies evenly between 3 friends.
>>> to_smash(91)
1
""" print("Splitting", total_candies, "candies")
return total_candies % 3
This function will print a message detailing the total number of candies and will then return the number of candies that are to be smashed.
However, in the case of having 1 total number of candies, the word ‘candies’ in our message is not grammatically correct!
If we run:
to_smash(1)
The output will be:
Splitting 1 candies1
1 candies does not make sense! This is how to rectify it:
def to_smash(total_candies):
print("Splitting", total_candies, "candy")
if total_candies == 1
else print("Splitting", total_candies, "candies") return total_candies % 3
Now here, the scenario of collecting 1 candy is accounted for!
- Exercise 3:
In the introductory notebook, there was a section on weather, where there were a combination of booleans to determine whether a person was prepared for the weather.
In this exercise, a function is defined to determine whether one is safe from the weather. One is safe from the weather if:
They have an umbrella…
or if the rain isn’t too heavy and they have a hood…
otherwise, they’re still fine unless it’s raining and it’s a workday
Here is the function:
def prepared_for_weather(have_umbrella, rain_level, have_hood, is_workday):
return have_umbrella or rain_level < 5 and have_hood or not rain_level > 0 and is_workday
# Change the values of these inputs so they represent a case where prepared_for_weather returns the wrong answer.have_umbrella = True
rain_level = 0.0
have_hood = True
is_workday = True
# Check what the function returns given the current values of the variables aboveactual = prepared_for_weather(have_umbrella, rain_level, have_hood, is_workday)print(actual)
Here, given the values of the arguments in the function, the function should return True; a person is safe from the weather.
However, we are told that the function is buggy; where a combination of the booleans will return an unexpected value in relation to a person being safe for the weather.
If the following values are set, the function fails to return a correct boolean value.
have_umbrella = False
rain_level = 0.0
have_hood = False
is_workday = False
This produces a ‘False’ value, where in actual fact, if the rain level is 0.0 and it is not a work day, then surely one is safe from the weather. The rain level is 0, therefore no rain; also, if it is not a work day, one does not have to leave the house.
Python evaluates the following:
(not (rain_level > 0)) and is_workday
While what we were trying to express is:
not (rain_level > 0 and is_workday)
Best to use brackets when combining boolean values like this.
- Exercise 4:
This exercise defines a function that returns True if a given argument is negative and False otherwise.
def is_negative(number):
if number < 0:
return True
else:
return False
It is stated that the function can be written in one line.
def concise_is_negative(number):
return number < 0
This concise version does the same thing, just in less lines of code!
- Exercise 5:
This exercise defined boolean functions to answer yes-or-no questions about a customer’s order. For example, if a customer does not want onions:
def onionless(ketchup, mustard, onion):
"""Return whether the customer doesn't want onions.
""" return not onion
So if a customer wants Ketchup and mustard but no onion:
onionless(True, True, False)
This will return True, because the boolean for onion is False in this case; as the customer does not want any onions.
The following functions needed to be completed based on the docstring;
Part a:
def wants_all_toppings(ketchup, mustard, onion):
"""Return whether the customer wants "the works" (all 3 toppings)
"""
return ketchup and mustard and onion <- CODED THIS
Part b:
def wants_plain_hotdog(ketchup, mustard, onion):
"""Return whether the customer wants a plain hot dog with no toppings.
""" return not (ketchup or mustard or onion) <- CODED THIS #return not ketchup and not mustard and not onion <- another option
Part c:
def exactly_one_sauce(ketchup, mustard, onion):
"""Return whether the customer wants either ketchup or mustard, but not both.
"" return (ketchup and not mustard) or (mustard and not ketchup) <- CODED THIS
Check the notebook for the output of the functions given some arguments!
- Exercise 6:
Calling the bool() function on an integer returns False if the integer is 0 and True otherwise. If we call the int() function on a boolean value, we get 0 for False, and 1 for True.
Using this, we can edit the following function based on the docstring:
def exactly_one_topping(ketchup, mustard, onion):
"""Return whether the customer wants exactly one of the three available toppings on their hot dog.
"""
return
Exactly one topping, meaning only one argument can be True at one time.
def exactly_one_topping(ketchup, mustard, onion):
return (int(ketchup)+int(mustard)+int(onion)) == 1
Here, the function will only return True if the sum of the arguments equals 1, in other words, if only one is True.
- Exercise 7:
This exercise was interesting; looking at a simplified version of blackjack, we had to try and mess around with the code to maximise our chances of winning. Check out the notebook for the rules of the game; essentially, who ever exceeds 21, between the player and the dealer, loses.
A good strategy I found was:
def should_hit(player_total, dealer_total, player_aces):
"""Return True if the player should hit (request another card) given the current game
state, or False if the player should stay. player_aces is the number of aces the player has.
""" if player_total < 16 and player_aces == 0:
return True
elif player_total >= 16:
return False
return False
This strategy gave a win rate of 38%-44%. That may seem low, but the game is designed so that the dealer is to win most of the time! There are more strategies on the Kaggle forum for this challenge!
Stay tuned for Day 4!