What is the most pythonic way to answer this iGCSE CompSci question? - python

I'm a teacher, not a student, I promise :)
Exercise: Declare an array. Use manual input to add integers to array. If the user enters -1, stop accepting input and do not add -1 to the array.
Other requirements: this must be as simple as possible, as it is a very early exercise for students who are just starting to program, and must be compatible with iGCSE PseudoCode, which does not allow for breaks/interrupts.
The three versions we are debating at the moment are:
1. Break
elements = []
while True:
user_input = int(input("Please enter a whole number. When you want to stop type -1 "))
if user_input == -1: break
elements.append(user_input)
Argument against: break is not compatible with pseudocode
2. Repeat Input
elements = []
user_input = int(input("Please enter a whole number. When you want to stop type -1 "))
while user_input != -1:
elements.append(user_input)
user_input = int(input("Please enter a whole number. When you want to stop type -1 "))
Argument against: repeating the input line is inelegant, and a source of errors when you take this approach on larger programs.
3. Repeat Condition
elements = []
user_input = 0
while user_input != -1:
user_input = int(input("Please enter a whole number. When you want to stop type -1 "))
if user_input != -1:
elements.append(user_input)
Argument against: repeating the condition is inelegant, and this is the longest of the three options
Are there any more elegant solutions that still preserve simplicity?

My opinion is that using builtin functions is more pythonic:
list(iter(lambda: int(input("Please enter a whole number. When you want to stop type -1 ")), -1))
Explanation of iter(callable, sentinel): Returns an iterator which calls callable until it returns sentinel (In our case -1).
list() is used to cycle through the iterator and save the elements in a list.
You can also use a function instead of a lambda if you want to do some validation:
def input_number():
value = input("Please enter a whole number. When you want to stop type -1 ")
try:
return int(value)
except ValueError:
return -1
x = list(iter(input_number, -1))

Related

Keep asking for numbers and find the average when user enters -1

number = 0
number_list = []
while number != -1:
number = int(input('Enter a number'))
number_list.append(number)
else:
print(sum(number_list)/ len(number_list))
EDIT: Have found a simpler way to get the average of the list but if for example I enter '2' '3' '4' my program calculates the average to be 2 not 3. Unsure of where it's going wrong! Sorry for the confusion
Trying out your code, I did a bit of simplification and also utilized an if statement to break out of the while loop in order to give a timely average. Following is the snippet of code for your evaluation.
number_list = []
def average(mylist):
return sum(mylist)/len(mylist)
while True:
number = int(input('Enter a number: '))
if number == -1:
break
number_list.append(number)
print(average(number_list));
Some points to note.
Instead of associating the else statement with the while loop, I revised the while loop utilizing the Boolean constant "True" and then tested for the value of "-1" in order to break out of the loop.
In the average function, I renamed the list variable to "mylist" so as to not confuse anyone who might analyze the code as list is a word that has significance in Python.
Finally, the return of the average was added to the end of the function. If a return statement is not included in a function, a value of "None" will be returned by a function, which is most likely why you received the error.
Following was a test run from the terminal.
#Dev:~/Python_Programs/Average$ python3 Average.py
Enter a number: 10
Enter a number: 22
Enter a number: 40
Enter a number: -1
24.0
Give that a try and see if it meets the spirit of your project.
converts the resulting list to Type: None
No, it doesn't. You get a ValueError with int() when it cannot parse what is passed.
You can try-except that. And you can just use while True.
Also, your average function doesn't output anything, but if it did, you need to call it with a parameter, not only print the function object...
ex.
from statistics import fmean
def average(data):
return fmean(data)
number_list = []
while True:
x = input('Enter a number')
try:
val = int(x)
if val == -1:
break
number_list.append(val)
except:
break
print(average(number_list))
edit
my program calculates the average to be 2 not 3
Your calculation includes the -1 appended to the list , so you are running 8 / 4 == 2
You don't need to save all the numbers themselves, just save the sum and count.
You should check if the input is a number before trying to convert it to int
total_sum = 0
count = 0
while True:
number = input("Enter a number: ")
if number == '-1':
break
elif not number.isnumeric() and not (number[0] == "-" and number[1:].isnumeric()):
print("Please enter numbers only")
continue
total_sum += int(number)
count += 1
print(total_sum / count)

Finding Sum of Variables in Python

I am working on a program that requires the user to enter a number and will continue to loop until a positive number is given. When a positive number is given, it will alert the user and present them with the sum of the digits of their number. However, I thought I had written my code correctly, but it is giving me an incorrect answer. What have I done wrong and how can I fix this?
user_input = float(int(input("Please Enter Your Number:")))
s = 0
while user_input < 0:
float(int(input("Please Enter Another Number: ")))
if user_input > 0:
s += user_input%10
user_input //= 10
print("You've entered a positive number! The sum of the digits is: ", s)
Four things:
Not sure why you storing the input as float, int should suffice.
If you give a negative input, it will enter the while loop. However, in the while loop, you are not actually assigning the new input to user_input. Fix this by adding user_input =
The while loop guarantees user_input is >= 0, so if user_input > 0: is unnecessary.
Probably the most important, to calculate the sum of digits, you need to repeatedly divide and sum, not just do it once. So, add a while loop.
Final code:
user_input = int(input("Please Enter Your Number: "))
s = 0
while user_input < 0:
user_input = int(input("Please Enter Another Number: "))
while user_input:
s += user_input % 10
user_input //= 10
print("You've entered a positive number! The sum of the digits is: ", s)
The if statement is generally used to decide if something should be done once.
If you want to keep going until user_input becomes zero, you'll need a while.
Also, I'm not entirely certain why you're storing the number as a float, especially when you make that from an int anyway. It may as well just be an int.
Additionally, you're loop to re-enter the value if it was negative doesn't actually assign the new value to the variable.
And you probably also want to outdent the print statement lest it be done on every iteration of the loop you're about to add.
Of course, some may suggest a more Pythonic way of summing the digits of a positive number is a simple:
sum([int(ch) for ch in str(x)])
That works just as well, without having to worry about explicit loops.
Another way to solve this is using assert and a function:
def sum_num():
# try get user input
try:
user_in = input('Enter Number: ')
assert int(user_in) > 0
except AssertionError:
# we got invalid input
sum_num()
else:
s_d = sum([int(i) for i in user_in])
print('You\'ve entered a positive number! The sum of the digits is: ', s_d)
#run the function
sum_num()
So this will asked user input, if it is not greater than zero it will throw assertion error, which we catch and return the user to inputting the number by calling the function again. If all is well, we split the input into character and add them up. as list('12') gives ['1','2']. We convert to int and add them. :)
The awesome thing about this is you can add more too the asset to capture other issue as floats, character as invalid inputs. E.g.
Assuming literal_eval is important( from ast import literal_eval)
assert isinstance(literal_eval(user_in),int) and int(user_in)>0
Check if user_in is integer and it is greater than 0. So you won’t get issues when user inputs floats or characters.

Asking for a sequence of inputs from user python3

I am working on a python exercise asking for
Write Python programs that read a sequence of integer inputs and print
The smallest and largest of the inputs.
My code so far
def smallAndLarge():
num1 = int(input("Enter a number: "))
num2 = int(input("Enter a number: "))
if num1 > num2:
print(num1,"is the largest number, while",num2,"is the smallest number.")
else:
print(num2,"is the largest number, while",num1,"is the smallest number.")
smallAndLarge()
I am using def smallAndlarge(): since my instructor wants us to use a def function for all of our programs in the future.
My question is how do I ask for multiple inputs from a user until they decided they dont want to add anymore inputs. Thanks for your time.
You could let the user flag when they are finished. (live example)
numbers = [];
in_num = None
while (in_num != ""):
in_num = input("Please enter a number (leave blank to finish): ")
try:
numbers.append(int(in_num))
except:
if in_num != "":
print(in_num + " is not a number. Try again.")
# Calculate largest and smallest here.
You can choose any string you want for the "stop", as long as it's not the same as the initial value of in_num.
As an aside, you should add logic to handle bad input (i.e. not an integer) to avoid runtime exceptions.
In this specific example, you'd also probably want to create smallest and largest variables, and calculate their values after each input. Doesn't matter so much for a small calculation, but as you move to bigger projects, you'll want to keep the efficiency of the code in mind.

'int' object is not iterable in python 3

got a error while compiling the code.
I tried to find smallest and largest value from user's input by storing the input in lists. After 'int' object not iterate problem, couldn't proceed further
largest=0
smallest=0
num=[]
while True:
num = int(input("Please enter a number: "))
for i in num:
if i>largest:
largest=i
for j in num:
if j<smallest:
smallest=j
if num==12:
break
print(largest)
print(smallest)
The moment you issue below code line num is no longer a list, instead its an int type of data.
num = int(input("Please enter a number: "))
As you can understand, there is nothing to iterate over in case of a single integer value.
The right solution is to read your input to a separate variable and append to your list.
input_num = int(input("Please enter a number: "))
num.append(input_num)
Further you will have to change value of your exit clause
if num==12:
break
If you desire to stop the loop after 12 inputs, then use len(num) == 12 in the if condition. In case you want to break loop if input number is 12 then change if condition to if input_num == 12
Note: Your algorithm has logical errors as well. You are assigning smallest to 0 . In case user enters all positive integers as input, your result will incorrect.
You are trying to iterate through a number which is wrong, you have overwritten your num list to an integer. Instead of the following:
num = int(input("Please enter a number: "))
You should save the number in some other variable and add to num list like:
x = int(input("Please enter a number: "))
num.append(x)

How to add up a variable?

I was wondering how I would sum up the numbers they input for n even though it's an input and not int. I am trying to average out all the numbers they input.
n=print("Enter as many numbers you want, one at the time, enter stop to quit. ")
a=0
while n!="stop":
n=input("Start now ")
a+=1
In Python 2.x input() evaluates the input as python code, so in one sense it will return something that you can accept as an integer to start with, but may also cause an error if the user entered something invalid. raw_input() will take the input and return it as a string -> evaluate this as an int and add them together.
http://en.wikibooks.org/wiki/Python_Programming/Input_and_Output
You would be better off using a list to store the numbers. The below code is intended for Python v3.x so if you want to use it in Python v2.x, just replace input with raw_input.
print("Enter as many numbers you want, one at the time, enter stop to quit. ")
num = input("Enter number ").lower()
all_nums = list()
while num != "stop":
try:
all_nums.append(int(num))
except:
if num != "stop":
print("Please enter stop to quit")
num = input("Enter number ").lower()
print("Sum of all entered numbers is", sum(all_nums))
print("Avg of all entered numbers is", sum(all_nums)/len(all_nums))
sum & len are built-in methods on lists & do exactly as their name says. The str.lower() method converts a string to lower-case completely.
Here is one possibility. The point of the try-except block is to make this less breakable. The point of if n != "stop" is to not display the error message if the user entered "stop" (which cannot be cast as an int)
n=print("Enter as many numbers you want, one at the time, enter stop to quit. ")
a=0
while n!="stop":
n=input("Enter a number: ")
try:
a+=int(n)
except:
if n != "stop":
print("I can't make that an integer!")
print("Your sum is", a)

Categories