How do I ask for user input until the user stops?
Question:
The Question
Write a program that reads a list of integers into a list as long as the integers are greater than zero, then outputs the smallest and largest integers in the list.
Ex: If the input is:
10
5
3
21
2
-6 (negative six, the format is weird on stackoverflow)
the output is:
2
21
You can assume that the list of integers will have at least 2 values.
My Code
lst =[]
for i in range(6):
if i > 0:
i = int(input())
lst.append(i)
print (min(lst), max(lst))
The Problem
My code works perfectly well for the example input given where there are 6 inputs. However, for a different number of inputs (such as 4 inputs or 9 inputs), the range(6) is limited and doesn’t produce the output that I want. I just don’t know how I’m supposed to determine the range for asking the input when The Question doesn’t specify the number of intputs it will take in.
Code after Help
lst =[]
while True:
_input= int(input())
if _input < 0:
break
lst.append(_input)
print(min(lst),max(lst))
Answers:
You could you while
operator and break
lst = []
while True:
_input = int(input())
if _input < 0:
break
lst.append(_input)
Or if you use python3.8 it could be even prettier:
lst = []
while _input := int(input()) >= 0:
lst.append(_input)
user_num = int(input())
list_num = []
while user_num > 0:
list_num.append(user_num)
user_num = int(input())
print(min(list_num),'and',max(list_num))
If you want a more flexible program for future expandability, you can implement a generator function for use in list comprehension. An example of what that might look like is this:
# Future imports (needed for certain type hinting functionality)
from __future__ import annotations
# Standard library imports
from re import compile as re_compile
from typing import TYPE_CHECKING
# Type checking (this is False during runtime)
if TYPE_CHECKING:
from re import Pattern
from typing import Generator
def int_input_generator() -> Generator[int, None, None]:
"""Integer generator: Stops generating when given incorrect input"""
numbers_only: Pattern = re_compile(r'^-?[0-9]+$')
user_input: str
int_input: int
while numbers_only.match((user_input := input())) is not None
and (int_input := int(user_input)) > 0:
yield int_input
return
def main() -> None:
"""Main function to run the program"""
input_list: list[int] = [_ for _ in int_input_generator()]
if input_list:
print(f'{min(input_list)}n{max(input_list)}')
return
if __name__ == '__main__':
main()
I went ahead and type hinted the code for better understanding. Also, the int_input_generator
takes care of cases when the input is not a number.
Note: I opted for using regex for numeric validation since functions like str.isnumeric()
, str.isdecimal()
, and str.isdigit()
allow for certain unicode characters that are not the typical ASCII digits.
The Question
Write a program that reads a list of integers into a list as long as the integers are greater than zero, then outputs the smallest and largest integers in the list.
Ex: If the input is:
10
5
3
21
2
-6 (negative six, the format is weird on stackoverflow)
the output is:
2
21
You can assume that the list of integers will have at least 2 values.
My Code
lst =[]
for i in range(6):
if i > 0:
i = int(input())
lst.append(i)
print (min(lst), max(lst))
The Problem
My code works perfectly well for the example input given where there are 6 inputs. However, for a different number of inputs (such as 4 inputs or 9 inputs), the range(6) is limited and doesn’t produce the output that I want. I just don’t know how I’m supposed to determine the range for asking the input when The Question doesn’t specify the number of intputs it will take in.
Code after Help
lst =[]
while True:
_input= int(input())
if _input < 0:
break
lst.append(_input)
print(min(lst),max(lst))
You could you while
operator and break
lst = []
while True:
_input = int(input())
if _input < 0:
break
lst.append(_input)
Or if you use python3.8 it could be even prettier:
lst = []
while _input := int(input()) >= 0:
lst.append(_input)
user_num = int(input())
list_num = []
while user_num > 0:
list_num.append(user_num)
user_num = int(input())
print(min(list_num),'and',max(list_num))
If you want a more flexible program for future expandability, you can implement a generator function for use in list comprehension. An example of what that might look like is this:
# Future imports (needed for certain type hinting functionality)
from __future__ import annotations
# Standard library imports
from re import compile as re_compile
from typing import TYPE_CHECKING
# Type checking (this is False during runtime)
if TYPE_CHECKING:
from re import Pattern
from typing import Generator
def int_input_generator() -> Generator[int, None, None]:
"""Integer generator: Stops generating when given incorrect input"""
numbers_only: Pattern = re_compile(r'^-?[0-9]+$')
user_input: str
int_input: int
while numbers_only.match((user_input := input())) is not None
and (int_input := int(user_input)) > 0:
yield int_input
return
def main() -> None:
"""Main function to run the program"""
input_list: list[int] = [_ for _ in int_input_generator()]
if input_list:
print(f'{min(input_list)}n{max(input_list)}')
return
if __name__ == '__main__':
main()
I went ahead and type hinted the code for better understanding. Also, the int_input_generator
takes care of cases when the input is not a number.
Note: I opted for using regex for numeric validation since functions like str.isnumeric()
, str.isdecimal()
, and str.isdigit()
allow for certain unicode characters that are not the typical ASCII digits.