Working with data

Day 8: Exercise Solutions

Python Guru with a screen instead of a face, typing on a computer keyboard with a light green background to match the day 8 image.

Here are our solutions for the day 8 exercises in the 30 Days of Python series. Make sure you try the exercises yourself before checking out the solutions!

1) Write a short guessing game program using a while loop. The user should be prompted to guess a number between 1 and 100, and you should tell them whether their guess was too high or too low after each guess. The loop should keeping running until the user guesses the number correctly.

First things first, we need to define out target number. You can generate this randomly using the random module, but here we're just going to hard code some value. Let's say 47 is our target number.

target_number = 47

We have two options when creating our while loop. We can write a loop condition so that the loop stops when the user guesses the number correctly, or we can have an explicitly infinite loop where we break the loop under certain conditions with a break statement.

The first approach would look like this:

target_number = 47

guess = int(input("Enter a number: "))

while guess != target_number:
    print("Wrong!")
    guess = int(input("Enter a number: "))

print("You guessed correctly!")

In this version, we need to define guess outside of the loop, because we need to be able to refer to it in the first line of the loop. We also need to redefine guess at the end of each iteration so that the user can choose a new number for each iteration.

If the user guesses correctly, we break out of the loop, and only then do we hit this "You guessed correctly!" string.

The other approach looks like this:

target_number = 47

while True:
    guess = int(input("Enter a number: "))

    if guess == target_number:
         print("You guessed correctly!")
         break
    else:
        print("Wrong!")

In this version all of the loop flow is controlled by these conditional statements inside the loop. We have an if statement to check if the user got the right number, and we can manually break the loop in those cases.

There's also a third option available to us in Python 3.8 using an assignment expression.

Any of these options are totally valid, so choose whichever you prefer. I'm going to use the first version here.

Now that we have the skeleton of the loop in place, we need to give the user some feedback on their guess. We need to tell them if the number is too high or too low. We can do this with a conditional statement.

target_number = 47

guess = int(input("Enter a number: "))

while guess != target_number:
    if guess > target_number:
        print("Too high!")
    else:
        print("Too low!")

    guess = int(input("Enter a number: "))

print("You guessed correctly!")

And with that, we have a working guessing game.

2) Use a loop and the continue keyword to print out every character in the string "Python", except the "o".

You can use whatever kind of loop you like here, but when trying to do something once for each item in a collection, we should generally use a for loop.

Let's start by creating our test string and writing the broad outlines of the loop:

sample_string = "Python"

for character in sample_string:
    print(character)

At the moment, this is going to print every character, but we need to exclude the "o" from this output.

Checking for "o" is fairly straightforward. We already get the characters one by one, so we can just check if a given character is "o". If it is, we can use the continue keyword to start a new iteration without printing the "o".

sample_string = "Python"

for character in sample_string:
    if character == "o":
        continue

    print(character)

3) Create a program that prints out every prime number between 1 and 100.

For the solution, I'm going to draw upon the implementation found in today's post:

# Get a number to test from the user
dividend = int(input("Please enter a number: "))

# Grab numbers one at a time from the range sequence
for divisor in range(2, dividend):
    # If user's number is divisible by the curent divisor, break the loop
    if dividend % divisor == 0:
        print(f"{dividend} is not prime!")
        break
else:
    # This line only runs if no divisors produced integer results
    print(f"{dividend} is prime!")

We just need to modify this solution so that can check multiple numbers.

The way I'm going to approach this is to create an outer loop which iterates over a range. This range is going to define the numbers we want to test. We can then feed numbers into this inner loop one at a time to see if they're prime.

One important detail is that I'm not going to start by range at 1. I'm going to start it at 2. We'll talk about why in a second.

for dividend in range(2, 101):
    for divisor in range(2, dividend):
        if dividend % divisor == 0:
            print(f"{dividend} is not prime!")
            break
    else:
        print(f"{dividend} is prime!")

Let's imagine we provide 1 as the dividend for this inner loop. This means we're iterating over range(2, 1). What does this sequence contain?

The answer is nothing at all. When we try to iterate over this sequence, Python is going to realise its empty, so we run zero iterations of the inner loop.

In that case, what happens? Well, the else clause still runs, because we didn't encounter a break statement in the inner loop. This means that 1 will be incorrectly reported as a prime number.

To avoid this, we start the sequence at 2, because we know that 1 is not prime.

We've also ensured that 2 will be listed as prime, because range(2, 2) is also an empty sequence. We therefore skip the loop body and go right to the else clause.

Since we only need to print out the prime numbers, we can clean up our solution just a little bit:

for dividend in range(2, 101):
    for divisor in range(2, dividend):
        if dividend % divisor == 0:
            break
    else:
        print(dividend)

Now we just provide output for the prime numbers, and we only print the numbers themselves.

You could also create a list of numbers and print out the list if you wanted to, like this:

primes = []

for dividend in range(2, 101):
    for divisor in range(2, dividend):
        if dividend % divisor == 0:
            break
    else:
        primes.append(dividend)

print(primes)

You could also make this a little nicer by using join. Just don't forget we can only join collections of strings!

primes = []

for dividend in range(2, 101):
    for divisor in range(2, dividend):
        if dividend % divisor == 0:
            break
    else:
        primes.append(str(dividend))

print(", ".join(primes))