CS303E Homework 5

Instructor: Dr. Bill Young
Due Date: Friday, February 17, 2025 at 11:59pm

Copyright © William D. Young. All rights reserved.

Assignment

In this assignment, you'll write a program in file MinMax.py that accepts an arbitrary number of integer inputs from the user. It prints out the count of numbers entered, the minimum and maximum of the numbers entered. The user will end the input loop by typing in a special 'sentinel' value -9999; we'll just assume that that's not one of the numbers the user wanted to consider. When the user enters -9999 your program should print out a blank line, the count of numbers entered (not including the sentinel), the minimum integer and the maximum integer entered (not including the sentinel). If the user enters -9999 immediately (i.e., before any other numbers are entered), you'll print a slightly different message. See the examples below.

You can assume that the values entered are strings representing integers (positive, negative or zero). You don't have to validate the inputs. Everything is separated by a single space.

Below is some sample output. You should mimic this exactly for the given inputs.

> python MinMax.py

Enter an integer or -9999 to end: -9999

You didn't enter any numbers.

> python MinMax.py

Enter an integer or -9999 to end: 100
Enter an integer or -9999 to end: 87
Enter an integer or -9999 to end: -10000
Enter an integer or -9999 to end: 12
Enter an integer or -9999 to end: 101
Enter an integer or -9999 to end: -9999

You entered 5 numbers.
The maximum is 101
The minimum is -10000 

> python MinMax.py

Enter an integer or -9999 to end: 1234
Enter an integer or -9999 to end: -9999

You entered 1 number.
The maximum is 1234
The minimum is 1234 

> 
This homework is primarily designed to give you some practice using loops, but you'll also need some if statements.

Below are a few additional requirements:

Requirement 1: We haven't yet covered lists in the class, so don't use them. But you don't need them. Think about this problem as follows. Suppose we're talking and I tell you I'm going to rattle off a bunch of numbers and, when I stop, you should tell me the biggest number I mentioned. I start: "9, 15, 130, 2, 14, -7, 18, ...." Notice that you certainly don't need to remember all of those numbers. At each point, you only need to remember the biggest number I've mentioned to that point. If you hear a smaller number, you ignore it. But if you hear a bigger number, then that's the new biggest number so far and you just need to remember that one. That's the kind of thing you need to implement in this assigment.

Requirement 2: You'll need variables to store the minimum and maximum numbers you've seen so far. How should you initialize those? Note that you probably should read a number before you enter the loop; otherwise, it's hard to treat an initial -9999 specially, as you're required to do. But if the first number you read is not -9999, then it's the min and max so far. Do not set min and max to some spurious values like negative infinity and positive infinity, or something weird like that. There's no integer values you could pick for them (except possibly -9999) that couldn't be a value entered by the user. You could probably get away with setting them to -9999, but then you'd have to have ugly special checks; don't do that.

Requirement 3: For this assigment you must have a main function. This will help when you need to exit your program early. For example, in this assignment if you find that the user enters -9999 immediately, you'll print a message and be done. You could always do that with if statements, but it sometimes makes for a more complicated overall structure. A better way is to put your code into a function, main(). To exit main, you execute a return statement. Note you can't do this unless your code is inside a function. Here's what this might look like:

    if num == -9999:
        print("\nYou didn't enter any numbers.\n")
        return
BTW: your function doesn't have to be called main; we'll introduce user-defined functions in the next module. Remember that you'll also need a call to the function, probably at the very bottom of your file.

Requirement 4: Notice that, if only one number is entered, my program prints out "You entered 1 number.", not "You entered 1 numbers.", which wouldn't be very good grammar. This is a simple fix, requiring a simple if statement (or if expression). Make sure that you make this fix.

Turning in the Assignment:

The program should be in a file named MinMax.py. Submit the file via Canvas before the deadline shown at the top of this page. Submit it to the assignment hw5 under the assignments sections by uploading your Python file.

Your file must compile and run before submission. It must also contain a header with the following format:

# Assignment: HW5
# File: MinMax.py
# Student: 
# UT EID:
# Course Name: CS303E
# 
# Date:
# Description of Program: 

As usual, if you submit multiple times to Canvas, it will rename your file name to something like MinMax-1.py, MinMax-2.py, etc. Don't worry about that; we'll grade the latest version.

Programming tips

Program incrementally: Don't try to write this entire program all at once. In the first pass, you might just handle the input---read numbers and print them until you encounter -9999. This will ensure you can handle looping while reading in integers (But be sure you're treating the integers as numbers, and not as strings.) Then figure out to add in finding the minimum number. Then add finding the max---that's easy once you've done min. Finally add the counting. Each step should get easier since you've already confronted harder problems. You'll be done before you know it. Some of you will think: "I don't want to do all those steps; it's easier to just do it all at once." You're wrong!

Using Loops: You usually write a for loop if you know in advance how many times the loop will run and a while loop if you don't. For this problem, you don't know how many times the loop will run (iterations). So you have to figure out the loop test. The trick is to make sure that the loop test makes sense the first time you enter the loop.

For this problem, it seems to make sense to stop when the user input is -9999. But that means you must have received an input before you entered the loop. Inside the loop you'll need another input statement; think about where it should fall, at the start of the loop or at the end.

Sometimes, it makes sense to write a loop test of True when you don't know how many iterations there will be. But then you run the risk of an infinite loop. You have to test inside the loop body to see if you are ready to exit and break if so. If not, you can always continue to another iteration of the loop. Years ago, I worked on a programming language called "Gypsy" in which all loops were like this. The loop statement had no test and the only way to exit a loop was an explicit break statement. That may be why I often write loops that way.

if-elif-else versus consecutive if: Some of you have wondered whether to use an if-elif-else statement or just a series of if statements. Sometimes, they do the same thing but often they don't and one may be significantly more efficient. Suppose you have a Cartesian coordinate system and you want to know what quadrant a particular point (x, y) is in. You could do the following:

if x == 0 or y == 0:
   print("Point is on an axis")
if x > 0 and y > 0:
   print("Point is in Quadrant I")
if x < 0 and y > 0:
   print("Point is in Quadrant II")
if x < 0 and y < 0:
   print("Point is in Quadrant III")
if x > 0 and y < 0:
   print("Point is in Quadrant IV")
This works because the conditions are mutually exclusive, i.e., it's impossible for any two conditions to both be True for any point. The problem is that you have to evaluate every one of the five conditions, even if you find, say, after the first test that the point is on an axis. This is quite inefficient. Instead, you might do the following:
if x == 0 or y == 0:
   print("Point is on an axis")
elif x > 0 and y > 0:
   print("Point is in Quadrant I")
elif y > 0:
   print("Point is in Quadrant II")
elif x < 0:
   print("Point is in Quadrant III")
else:
   print("Point is in Quadrant IV")
Think about why this works; in particular, think about what must be true as you're evaluating any particular condition. This version is much more efficient because you only have to evaluate conditions until you find one that's true. And also notice that you can't just replace the elifs by ifs in this version because then multiple tests could be true simultaneously and you'd get the wrong answer.