# Homework 7: While Loops¶

## Objectives¶

• while loops:
• user input with sentinel values
• until reaching a numerical threshold
• iterating over a list
• using the random module
• generating a random integer in a range
• simulating probabilities by using random.random()

Submissions Limited

For this HW, you may submit each exercise up to 20 times. Before you submit to Gradescope, make sure that you:

1. Test your code, either in the shell or in the __main__ block.
2. Run !flake8, and resolve all PEP 8 and docstring issues.

Don't Use for

This homework is about while loops. Be sure not to use for loops in any of the exercises.

Stubs Provided

To save you time on this assignment, we are giving you starter files with all the docstrings already written. Download and unzip HW7-stubs.zip. Don't forget to write your name at the top of each file!

## Exercise 7.1 While Signs¶

Previously, you created a program that determined if numbers were positive or negative. Let's do more things with positive and negative numbers! You will create a function that distributes numbers entered by the user into separate lists of positive and negative numbers. Your program will read numbers from the keyboard until the user inputs a 'q'.

Name your program while_signs.py. Write a function get_positive_negative() that:

1. Repeatedly reads keyboard entries until the user inputs a 'q'. The prompt should be Input? (with a single space after the question mark).
2. Appends each float input into the appropriate list: positive numbers or negative numbers
3. Returns the two lists as a tuple, positives first.

For instance:

>>> %Run while_signs.py
>>> result = get_positive_negative()
Input? 34
Input? 4
Input? -7
Input? 0
Input? q
>>> print(result)
([34.0, 4.0], [-7.0])


## Exercise 7.2 Division Algorithm¶

Computers aren't born knowing how to perform integer division; they must be programmed to do it. One such method is the division algorithm, described below.

Say you want to divide an integer n ≥ 0 by an integer d > 0. To find the quotient and remainder, follow these steps:

1. Initialize the variable q with the value 0.
2. Initialize the variable r with the value n.
3. As long as r ≥ d, repeat the following:
• Subtract d from r.
4. Then q will be the quotient and r will be the remainder.

You can test you've done it right by checking that n = q * d + r.

In a file named division.py, write a function divide that takes two parameters, number and divisor, in that order, that performs the division algorithm to find number ÷ divisor and returns the two values q and r in that order.

Warning

The goal of this exercise is to implement the division algorithm using a while loop. Do NOT use the division, integer division, or modulo operators in your solution.

## Exercise 7.3 Dice Rolling Simulator¶

For board games and tabletop RPGs, players often need to roll different kinds of dice to determine their progression in the game. Let's create a program named dice.py that can help!

For this exercise, you will need to use the random module. At the top of your program, after the docstring, make sure to import the module:

import random


Write a program named dice.py. It must contain a function called roll_dice.

The roll_dice function must take in two arguments:

• num_dice (an integer): The number of dice to roll.
• num_sides (an integer): The number of sides on each die.

If either num_dice or num_sides are 0 or less, the function must return -1.

Otherwise, this function must simulate rolling num_dice dice, each with num_sides sides, and return the total sum of all the rolls. Use a while loop to accomplish this. Each die has possible values ranging from 1 to num_sides (inclusive). For instance, a die with six sides can give you equally possible outcomes of 1, 2, 3, 4, 5, or 6.

You must call the random.randint function to get a random side for each die. See the Python documentation to understand what arguments and return value this function has.

Warning

Do not call other functions from the random module (or call randint more than once per die – if you have three dice, you must call randint exactly three times), otherwise your code may not pass Gradescope!

Testing: In order to test your code, we will set a "seed" value for the random number generator. These numbers are not truly random; instead the seed value dictates the sequence of numbers that gets generated. Thus, setting a seed will guarantee that the sequence is the same every time. You should not set a seed in your code; however, you may download this test file to see how setting a seed works and test your code using it: sample_tests.py

## Exercise 7.4 Wheel of Fortun…ate Events¶

You are tasked to create a program for a game show called "Wheel of Fortunate Events". In the game, players spin a large wheel for cash prizes. The wheel is split up into segments, like slices of a pie. The player keeps spinning the wheel and accumulating cash until they land on Game Over and cash out their total. The segments have different sizes, so the probability of each outcome is different:

Outcome Probability
$1 25%$20 25%
$50 15%$100 12.5%
\$1000 2.5%
Game Over 20%

You must write a program called fortunate.py to simulate this. Your program must have two functions: spin_wheel and play_game.

1. The spin_wheel function has no parameters. The function must first simulate spinning the wheel and then return the number of dollars won (as an int), or 0 if the wheel landed on Game Over. You must simulate spinning the wheel once by calling random.random(), which will return a number in the range [0.0, 1.0). You must then use this value to determine where the wheel landed.

For instance, if you were spinning a wheel with four colors, each with equal probabilities, the code would be (note how the probabilities accumulate with each elif):

result = None
spin = random.random()

if spin < 0.25:
result = "red"
elif spin < 0.5:
result = "blue"
elif spin < 0.75:
result = "green"
else:
result = "yellow"


Note

We are testing your spin_wheel() function by calling it 100,000 times and computing the probability of each outcome. You can write your own test code to call spin_wheel multiple times and keep track of how often each outcome occurs. If you do not use random.random(), your code may fail Gradescope.

2. The play_game function also has no parameters. This function must simulate spinning the wheel and accumulating cash until the wheel lands on Game Over. Your play_game function must call spin_wheel to get the outcome of each spin. You must keep track of the total amount of cash and total number of spins, until the wheel lands on Game Over.

The function must return a tuple consisting of the total cash earned, followed by the total spins (including the one that caused the Game Over).

## Exercise 7.5 Even More Basketball Stats¶

Previously, you created a program for JMU Basketball that printed the scoring for a single player, and in Exercise 5.4 a function that returned all the statistics for a single player. They would now like you to create a function that will print the statistics for a large number of players all at once.

Name your program even_more_stats.py. Write a function called print_stats that does two things:

1. it prints the names and individual statistics for any number of players; and
2. it prints the total number of points, rebounds, and assists for the entire group of players.

The function will take a single parameter, a list that contains all the statistics for the players. A sample list is as follows:

[('Jefferson', 706, 88, 57), ('Hazell', 615, 62, 62), ('Tucker', 551, 137, 17)]


(Statistics from 2020-2021 JMU Women's Basketball Team)

The list consists of tuples, each of which contains a player's name, their total points, total rebounds, and total assists for the season. Your code should print a line for each player (as demonstrated below), and then print the total points, total rebounds, and total assists, calculated for the entire list.

The output should be as follows:

>>> print_stats([('Bird', 500, 100, 50), ('Jordan', 450, 90, 45)])
Bird scored 500 points, grabbed 100 rebounds, and made 50 assists.
Jordan scored 450 points, grabbed 90 rebounds, and made 45 assists.
Total Points:   950
Total Rebounds: 190
Total Assists:  95


Note

Iterating through a list of elements like this would normally be accomplished using a for-loop, not a while-loop. But right now, we're learning about while loops! Thus, your solution must use a while-loop.