Tutorial A6 – Solutions

1 Below you can find the implementation of a “question-answer”-game, in which the player is asked to evaluate boolean statements with comparison operators. For each right answer you get a point. Do not worry, if you do not understand the implementation! We will cover the elements that we do not know yet in the coming exercises. Execute the code cell in a Jupyter notebook to play the game. a) The program prints the Player’s total points after 10 rounds to the screen (at the very end of the code). Add a set of if-else statements to additionally print a message commenting the number of points. Advanced b) Try to read through the implementation and identify the code block within the doComparison function definition where comparisons are choosen via a set of if-else statements. Comment the lines of this block in the code cell.

[1]:
#
# Game: True or False
#
# The computer writes a statement to screen.
# The user rates it as true or false.
# The game has 10 rounds. For every correct answer the user gets a point.
#

import random
# Random number generator (will be treated in a later exercise)

#-----------------------------------------------------------------------

def doComparison(i, a, b):
    """Generate a comparison

    Compares two integers a and b using one of six comparison operators.
    The comparison operator is determined by the index i:

       0: `==`
       1: `!=`
       2: `>=`
       3: `<=`
       4: `>`
       5: `<`

    Args:
       i (int): index linked to a comparison operator
       a (int): first number
       b (int): second number

    Raises:
       AssertionError: Arguments `i`, `a`, and `b` must be of type `int`
       AssertionError: Index `i` must be in range(6)

    Returns:
       True or False
    """

    # Arguments need to be of type `int`
    assert isinstance(i, int)
    assert isinstance(a, int)
    assert isinstance(b, int)

    if i == 0:
        return a == b
    elif i == 1:
        return a != b
    elif i == 2:
        return a >= b
    elif i == 3:
        return a <= b
    elif i == 4:
        return a > b
    elif i == 5:
        return a < b
    else:
        raise AssertionError(
            "Index `i` must be in range(6)"
            )

#-----------------------------------------------------------------------

# List of comparison operators
operators = ["==", "!=", ">=", "<=", ">", "<"]

# Counter for the number of correct answers
points = 0

for run in range(10):
    # Pick two random numbers between 1 and 10
    a = random.randint(1, 10)
    b = random.randint(1, 10)

    # Pick a random number that determines the comparison operator
    i = random.randint(0, 5)

    # Print the comparison to screen
    print(str(a) + " " + operators[i] + " " + str(b))

    # Ask whether the statement is true or false
    user_input = input("True or False: ")

    #****************************************
    # __b)__ This block should be commented #
    #****************************************

    result = doComparison(i, a, b)
    if user_input == "True" and result == True:
        print("Correct!")
        points += 1
    elif user_input == "False" and result == False:
        print("Correct!")
        points += 1
    else:
        print("Wrong!")

    print("")

#**************************************************
# __a)__ Write a code block that rates the result #
# 0-3 points -> Not so good                       #
# 4-6 points -> You'll get there if you practice  #
# 7-9 points -> Well done!                        #
# 10 points -> Boolean master                     #
#**************************************************
print("-" * 80)
print("You have " + str(points) + " out of 10 points.")

3 == 8
True or False:
Wrong!

10 != 8
True or False:
Wrong!

2 == 7
True or False:
Wrong!

1 < 7
True or False:
Wrong!

10 > 6
True or False:
Wrong!

8 == 1
True or False:
Wrong!

5 < 10
True or False:
Wrong!

8 < 2
True or False:
Wrong!

9 != 2
True or False:
Wrong!

5 <= 2
True or False:
Wrong!

--------------------------------------------------------------------------------
You have 0 out of 10 points.
[2]:
help(doComparison)
Help on function doComparison in module __main__:

doComparison(i, a, b)
    Generate a comparison

    Compares two integers a and b using one of six comparison operators.
    The comparison operator is determined by the index i:

       0: `==`
       1: `!=`
       2: `>=`
       3: `<=`
       4: `>`
       5: `<`

    Args:
       i (int): index linked to a comparison operator
       a (int): first number
       b (int): second number

    Raises:
       AssertionError: Arguments `i`, `a`, and `b` must be of type `int`
       AssertionError: Index `i` must be in range(6)

    Returns:
       True or False

2 Below you find the implementation of another game, in which the Player needs to find a secret number. Again don’t worry about the parts of the implementation you may not understand already. Execute the code cell to play the game Advanced b) Try to read through the implementation and identify the code block where comparisons are choosen via a set of if-else statements. Comment the lines of this block in the code cell.

[3]:
#
# Game: guess the number
#
# The program picks a random integer in the interval [0, maxNum].
# The user tries to guess the number by making statements about the
# number.
# The program replies True or False.
# If the user makes maxCount false statements, the computer wins.
# If the user guesses the number correctly before making maxCount false
# statements, the user wins.
#

import random


# Largest number that can be picked
maxNum = 10

# Number of wrong guesses
maxCount = 3

#-----------------------------------------------------------------------

# Pick a random integer between 1 and maxNum
a = random.randint(1, maxNum)

# Boolean that states whether number has been guessed already
guessed_number = False

# Counts the number of wrong guesses
count = 0

# Instruction to the user
print("Make statements of the form: a == 7 or a >= 5.")

while (count < maxCount) and (guessed_number == False):
    # read in the statement
    statement = input("Your statement ")

    try:
        # Extract the comparison operator
        comparator = statement.split()[1]
        # and the number
        number = int(statement.split()[2])
    except (IndexError, ValueError):
        # IndexError: Indexing the list returned by `.split()` fails.
        # ValueError: Conversion to int fails
        print("Input formatted incorrectly.")
        continue

    #****************************************
    # __b)__ This block should be commented #
    #****************************************
    if comparator == "==" and a == number:
        print("True")
        guessed_number = True
    elif comparator == "!=" and a != number:
        print("True")
    elif comparator == ">=" and a >= number:
        print("True")
    elif comparator == "<=" and a <= number:
        print("True")
    elif comparator == "<" and a < number:
        print("True")
    elif comparator == ">" and a > number:
        print("True")
    else:
        print("False")
        count += 1

if count < 3:
        print("")
        print("You won!")
else:
        print("")
        print("You lost!")

print("The number is " + str(a) + ".")
Make statements of the form: a == 7 or a >= 5.
Your statement a == 0
False
Your statement a == 1
False
Your statement a == 2
True

You won!
The number is 2.

3 What is the outcome of theses statements? Why is this?

  • 10 == "10"

[4]:
10 == "10"  # A number is not a string
[4]:
False
  • bool("False")

[5]:
bool("False")
# Existing objects ("False" is a string) evaluate to True
[5]:
True
  • bool(print("x"))

[6]:
bool(print("x"))
# Print displays x and returns None
# None evaluates to False
x
[6]:
False
  • float(1) == int(1)

[7]:
float(1) == int(1)  # Numerically identical
[7]:
True
  • float(1) is int(1)

[8]:
float(1) is int(1)  # A float is not an integer
[8]:
False
  • not(True or False)

[9]:
not(True or False)
# True or False is True
# not True is False
[9]:
False
  • True in {1}

[10]:
True in {1}  # 1 == True
[10]:
True
  • True > False

[11]:
True > False  # True == 1; False == 0
[11]:
True
  • 1 > "a"

[12]:
1 > "a"  # cannot compare apples and oranges
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-169919dd90e0> in <module>
----> 1 1 > "a"  # cannot compare apples and oranges

TypeError: '>' not supported between instances of 'int' and 'str'

4 a) Write an if-else statement that checks if a variable is an integer and adds 1 to it if it is. Print a message if it is not. Show that this works for both cases.

[13]:
i = 1
if isinstance(i, int):
    i += 1
else:
    print("i is not an integer")

print(i)
2
[14]:
i = "1"
if isinstance(i, int):
    i += 1
else:
    print("i is not an integer")

print(i)
i is not an integer
1

Advanced b) Rewrite this as a try-except statement checking if 1 can be added to the variable at all.

[15]:
i = 1
try:
    i += 1
except TypeError:
    print("Can not add 1 to i")
print(i)
2
[16]:
i = "1"
try:
    i += 1
except TypeError:
    print("Can not add 1 to i")
print(i)
Can not add 1 to i
1

Advanced 1 Can you figure out what this code does? How does the value of c effect the outcome.

[17]:
c = None
if not c:
    c = True
elif c:
    c = None
else:
    print("Never thought I could land here ...")
if c:
    c = not c
elif not c:
    c = True

# print(c)

Advanced 2 Here is something you can wrap you head around. Can you understand what’s going on here?

[18]:
a = False
print(a and 2 or 1)
1
[19]:
a = False
print(a and 2)  # Returns first False value
print(False or 1)  # Returns last value
False
1
[20]:
a = True
print(a and 2 or 1)
2
[21]:
a = True
print(a and 2)  # Returns last True value
print(2 or 1)  # Returns first True value
2
2