Function is not producing an integer, but instead producing a "none" output - python

The getvalidint function is explained below, as I am calling the function getvalidint and giving it a input so it may produce an integer output. It is not as I print the functions output(see below in the main program) it prints out "none", I am running on python33.
#getValidInt() takes in a minn and maxx, and gets a number from the
# user between those two numbers (inclusive)
#Input: minn and maxx, two integers
#Output: an integer, between minn and maxx inclusive
MIN_VAL = -1000000
MAX_VAL = 1000000
def getValidInt(minn, maxx):
message = "Please enter a number between " + str(minn) + " and " + \
str(maxx) + " (inclusive): "
newInt = int(input(message))
while newInt <= minn & newInt >= maxx:
# while loop exited, return the user's choice
return newInt
def main():
userNum = getValidInt(MIN_VAL, MAX_VAL)
print(userNum)
main()

If the while newInt <= minn & newInt >= maxx: condition is never met, then nothing will be returned. This means that the function will implicitly return None. Also, assuming you're using python 3 (which I induced from your int(input()) idiom).
The deeper issue is that the input code will only run once, regardless of whether or not the value meets the constraint. The typical way of doing this would be something along the lines of:
import sys
def get_int(minimum=-100000, maximum=100000):
user_input = float("inf")
while user_input > maximum or user_input < minimum:
try:
user_input = int(input("Enter a number between {} and {}: ".format(minimum, maximum)))
except ValueError:
sys.stdout.write("Invalid number. ")
return user_input

Related

Why does my Collatz sequence code execute but show error?

This is my code on the Collatz sequence:
def collatz(a):
while (a != 1):
if a%2 == 0:
a = a//2
print (a, " -> ")
a = collatz(a)
elif a%2 != 0:
a = int(3*a + 1)
print (a, " -> ")
a = collatz(a)
x = int(input("Enter a number: "))
collatz(x)
The output I get is perfect for every number I enter, but Jupyter Notebook also shows some kind of error. Am I making some kind of error in recursion? I've linked the output and error shown.
https://ibb.co/C1jCthq
You do a = collatz(a), but since your function has no return statements, this sets a to None. Then in the next iteration of the loop you try to do arithmetic on a. This fails, because you can't do arithmetic on None.
You don't really need recursion here at all. You already have a loop, so you can simply delete those collatz calls.
def collatz(a):
while (a != 1):
if a%2 == 0:
a = a//2
print (a, " -> ")
elif a%2 != 0:
a = int(3*a + 1)
print (a, " -> ")
x = int(input("Enter a number: "))
collatz(x)
... But if you're dead-set on having recursion, you can do that too. Delete the while loop, and call collatz at the end of your function.
def collatz(a):
if a == 1:
return
if a%2 == 0:
a = a//2
elif a%2 != 0:
a = int(3*a + 1)
print (a, " -> ")
collatz(a)
The drawback of this approach is that it will crash with "maximum recursion depth exceeded" if the function recurses more than 999 times. Collatz sequences converge to 1 fairly quickly, so this probably isn't a practical problem for this specific algorithm, but it's something to keep in mind when writing any recursive function.
Both of these approaches have the potentially undesirable behavior of printing "->" after the final number in the sequence. This is a fairly common problem in this style of "print-while-iterating" code. One possible solution is to remove the print calls from the function, instead returning a list of the values of the sequence. Then you can style your output after the fact, using join to intersperse the numbers with arrows.
def collatz(a):
result = [a]
while (a != 1):
if a%2 == 0:
a = a//2
elif a%2 != 0:
a = int(3*a + 1)
result.append(a)
return result
x = int(input("Enter a number: "))
seq = collatz(x)
print(" -> ".join(str(num) for num in seq))

Need help using range for loop

I am making a program that calculates the sum of all even and odd numbers between two number which are user inputted. I'm new to Python and am not sure how to use the range in a loop to make my program work. Here is my code. I know its sloppy and not well put together and not finished but any help works thanks.
n = int(input(" please enter a number"))
m= int(input(" please enter another number"))
count =0
sum =0
for x in range(n,m+1,2):
if x%2==0:
count=count+x
sum = count
print(" the total sum of odd numbers are",sum)
It's important to know if n is greater than m and invert situation if so. Other than that, you need to know if the smallest number is odd or even and begin the two ranges accordingly:
n = int(input("Please enter a number: "))
m = int(input("Please enter another number: "))
# n will always be the smaller one
if n > m:
n, m = m, n
n_is_odd = n % 2 # Gives 1 if n is odd
n_even = n + n_is_odd # Sum 1 if n is odd
n_odd = n + (not n_is_odd) # Sum 1 if n is even
print("the total sum of even numbers is %d" % sum(range(n_even, m+1, 2)) )
print("the total sum of odd numbers is %d" % sum(range(n_odd, m+1, 2)) )
Input validation is a big part of good coding. A good overview can be found here:
Asking the user for input until they give a valid response
To make the validation it reusable I put the validation in a function that only accept integers and (if a minval is provided, makes sure that the input is bigger that the minval.
def while_invalid_ask_input_return_integer(text, minval = None):
"""Aks for input until a number is given that is > minval if minval not None
returns an integer."""
while True:
c = input (text)
try:
c = int(c)
if minval is not None and c < minval:
raise ValueError # its too small, raise an erros so we jump to except:
return c
except ValueError:
if minval is not None:
print("must be a number and greater ", minval)
else:
print("not a number")
I use it to get the first number, and the second number gets the first one as "constraint" so it will be bigger. For summation I just use the range starting once with n once with n+1 till m and a range step of 2. I check what even/oddness n has and print text accordingly:
n = while_invalid_ask_input_return_integer("please enter a number ")
m = while_invalid_ask_input_return_integer("enter number bigger then {}".format(n),n)
print( "Odd sum:" if n % 2 == 1 else "Even sum:", sum(range(n,m+1,2)) )
print( "Even sum:" if n % 2 == 1 else "Odd sum:", sum(range(n+1,m+1,2)) )
Output:
please enter a number k
not a number
please enter a number 55
enter number bigger then 55 2
must be a number and greater 55
enter number bigger then 55 150
Odd sum: 4896
Even sum: 4944
Doku:
sum(iterable)
try: except: error handling
python ternary operator (thats the thing # "Odd sum:" if n % 2 == 1 else "Even sum:" in the print statement)
Here's a function I think fits into the description of what you asked above. It returns None if the user doesn't enter the type of query he or she wants.
So query can either be odd or even and depending on this, it calculates the sum that you want. The function makes use of list comprehension which is super cool too.
def calculate_odd_or_even_sum(query):
start = int(input(" please enter a number"))
end = int(input(" please enter another number"))
count = 0
if query == 'even':
return sum([x for x in range(start, end) if x % 2 == 0])
elif query == 'odd':
return sum([x for x in range(start, end) if x % 2 != 0])
else:
return 0

I want to return the number of top-level elements in a "duo" lists

Trying to do a Boolean test loop where the user needs to enter a number between 10 and 1000 including 10 and 1000, they need to stay in this loop until they enter the correct number once they do then I will finish the else statement.
I tried this:
while (num_years < 10) and (num_years > 1000): # boolean test , note == (= will give you an error!)
print("Your input must be 10 and 1000")
input("Enter number of years to simulate (currently " + str(num_years) + "): ")
else:
print()
AND this:
while (num_years == range(10, 1000)): # boolean test , note == (= will give you an error!)
print("Your input must be 10 and 1000")
input("Enter number of years to simulate (currently " + str(num_years) + "): ")
else:
print()
You could try something like this as it also checks if the user inputs a valid number:
while True:
number = input("Enter number of years to simulate (10-1000): ")
try:
years = int(number)
if years >= 10 and years <= 1000:
break
else:
print("Your input must be between 10 and 1000 inclusive")
except ValueError:
print("That's not an int!")
print("Simulating %d years..." % years)
Example Usage:
Enter number of years to simulate (10-1000): asd
That's not an int!
Enter number of years to simulate (10-1000): 5
Your input must be between 10 and 1000 inclusive
Enter number of years to simulate (10-1000): 245
Simulating 245 years...
Try it here!
You are never changing the value of num_years so the condition will never change. Fixing your boolean logic:
num_years = 0
while (num_years < 10) or (num_years > 1000):
print("Your input must be 10 and 1000")
num_years = int(input("Enter number of years to simulate (currently {}): ".format(num_years)))
else:
print()
However, this assumes someone is entering a number if you need to cover a non-numeric value then use a try: except: pass block:
try:
num_years = int(input("Enter number of years to simulate (currently {}): ".format(num_years)))
except ValueError:
pass
Note: = is assignment not an equality test. Use in to test if a value is in a list or range.
Okay, first of all:
(num_years < 10) and (num_years > 1000)
this is always False since one number cannot be less than 10 and more than 1000 at the same time.
Second of all
num_years == range(10, 1000)
will never work since you have (probably) integer on the left and generator on the right.
However you might try something like that:
possible_years = range(10,101)
num_years = 50
while num_years in possible_years: # or 9 < num_years < 100
print("Your input must be 10 and 1000")
entered_years = input("Enter number of years to simulate (currently " + str(num_years) + "): ")
num_years = int(entered_years) # remeber to check if entered_years is int before this line!
else:
print()
However there is still a catch, you need to check if user entered an integer.
What you need to do is a while loop to check whether the input is valid. If it's not, it will loop again. Also you never assign the input to a variable.
n = None
while n is None or not 10 <= n <= 1000:
if n is not None: # Only happens if it's not the first input
print('Invalid number, please try again')
try:
n = int( input('Enter number of years to simulate (10-1000): ') ) # Convert the
# string to an int
except:
pass
print( 'Simulating {} years...'.format(n) )
It will continue and say simulating once a valid number is input because
not 10 <= n <= 1000
will evaluate to false.
You can try it at this link: https://repl.it/FftK/0
n = None
while n is None or not 10 <= n <= 1000:
if n is not None: # Only happens if it's not the first input
print('Invalid number, please try again')
try:
n = int( input('Enter number of years to simulate (10-1000): ') ) # Convert the
# string to an int
except:
pass
print( 'Simulating {} years...'.format(n) )

print out max and min numbers of the input

I'm asked to write a program which takes in a bunch of numbers and print out the maximum and minimum number of them, below is my code:
maximum = None
minimum = None
while True:
num = raw_input("Enter a number: ")
if num == 'done':
break;
try:
num = int(num)
if num >= maximum:
maximum = num
if num <= minimum:
minimum = num
except:
print "Please Enter A Number!"
continue
print "Max = ",maximum, "Min = ",minimum
The thing is when I run this program the Min always equals to its initial value None, but it will work if I change the second if statement into else. What's wrong with the current one?
If the indentation is correct in the question (and not some copy paste mistake, that is the issue, the minimum = num line needs to be indented towards the right. Also, you need to take care of maximum and minimum being None that would throw error when used in comparison to int in Python 3.x , and would not work correctly for minimum in Python 2.x since no int would be smaller than None.
maximum = None
minimum = None
while True:
num = raw_input("Enter a number: ")
if num == 'done':
break;
try:
num = int(num)
if maximum is None:
maximum = num
minimum = num
if num >= maximum:
maximum = num
if num <= minimum:
minimum = num
except:
print "Please Enter A Number!"
continue
print "Max = ",maximum, "Min = ",minimum
Here is how I would do it:
track = []
while True:
num = raw_input("Enter a number: ")
if num == 'done':
break
try:
num = int(num)
except ValueError:
print "Please Enter A Number!"
continue
track.append(num)
print "Max = ", max(track), "Min = ", min(track)
Well the problem here is with your use of None here as the default value. It happens to work for the maximum because all numbers are greater than None. However, that way the minimum condition will never come true.
There are a few ways to fix this. The obvious and non-pythonic way is to set the minimum to float('inf'). This is kinda obviously infinity. The "better" way would be to change the condition to:
if num <= minimum or minimum==None:
which will automatically set the min on the first pass.
P.S.: I'm guessing you're doing this for algo-practice, because min() and max() functions are built-in.

Continually prompting user for input in Python

Objective: * Write a python program that repeatedly prompts for input of a positive number until the sum of the numbers is greater than 179. Use at least three modules/functions in your solution.
* The largest number entered cannot exceed 42.
* When the sum of the numbers exceeds 179, print the sum of the numbers, the largest number entered and smallest number entered.
I just need some guidance, specifically for the "input_numbers" module. There must be an easier way to do this than to make a variable for each number. The code is not complete. I haven't even started on the two other modules yet. Thanks in advance.
def input_numbers():
while True:
num1 = raw_input("Enter a positive integer no greater than 42 ")
if num1 <= 0:
print "That is not a positive integer. Try again "
elif num1 > 42:
print "The number cannot exceed 42. Try again "
num2 = raw_input("Enter another positive integer ")
if num2 <= 0:
print "That is not a positive integer. Try again "
elif num2 > 42:
print "The number cannot exceed 42. Try again "
num3 = raw_input("Enter another positive integer ")
if num3 <= 0:
print "That is not a positive integer. Try again "
elif num3 > 42:
print "The number cannot exceed 42. Try again "
num4 = raw_input("Enter another positive integer ")
if num4 <= 0:
print "That is not a positive integer. Try again "
elif num4 > 42:
print "The number cannot exceed 42. Try again "
num5 = raw_input("Enter another positive integer ")
if num5 <= 0:
print "That is not a positive integer. Try again "
elif num5 > 42:
print "The number cannot exceed 42. Try again "
elif sum(num1, num2, num3, num4, num5) > 179:
print_numbers()
add_numbers()
def add_numbers():
print_numbers()
def print_numbers():
input_numbers()
You can knock out all three function requirements by encapsulating each step of your program. Rather than having your loop inside of a function, we'll let main control the loop, and we'll control the flow by passing data into and out of function calls.
Let's rework your input_numbers() function a bit.
def get_input_number():
num = int(raw_input("Enter a positive integer no greater than 42 "))
if num <= 0 or num > 42:
print "Invalid input. Try again "
get_input_number()
else:
return num
So, instead of having input_numbers control the loop as well as the input handling and validation, we have it do just what its name implies: It asks for input, validates it, and then, if it's good, it returns the value to the caller, but if it's bad, it writes a message, and calls itself again to the user can enter good input.
The next function we'll set up is straight from your list of requirements. From all of the numbers that the user enters, we need to find the biggest one. From the language alone, we can determine that we're looking through a set of numbers, and thus, this is a good place to break out a list. Assuming we store all of the users input in a list, we can then pass that list to a function and perform operations on it, like so.
def get_greatest_number(input_list):
highest = input_list[0]
for i in input_list:
if i > highest:
highest = i
return highest
We set the first element of the list to a variable highest and then check all other elements in the list against that initial value. If we find one that's bigger, we then reassign the highest variable to the element that was bigger. Once we do this for each element in the list, the number inside of highest will now be, just that, the highest number, and so, we'll return it to the main program.
Similarly, we can do the same for finding the smallest.
def get_smallest_number(input_list):
smallest = input_list[0]
for i in input_list:
if i < smallest:
smallest = i
return smallest
Finally, we get to our main loop. Here we declare an empty list, number_list to store all the numbers in. And we use the sum of that as our loop condition.
if __name__ == '__main__':
number_list = []
while sum(number_list) < 179:
number_list.append(get_input_number())
In the body of the loop, we call our get_input_number() and append its result to the list we made. Once the sum of the numbers in the list exceed 179, the while loop will exit and we can finally show the user the results.
print
print '-------------------------'
print 'total of numbers entered: %d' % sum(number_list)
print 'greatest number entered: %d' % get_greatest_number(number_list)
print 'smallest number entered: %d' % get_smallest_number(number_list)
Here we can the get_greatest_number and get_smallest_number we made, and we give them the list of numbers as an argument. They'll loop though the lists, and then return the appropriate values to the print statements.
Yes, of course there's a better way than making a variable for each number. Store them in a list. Storing them in a list also makes finding their sum and the highest and lowest value easy (there are built-in functions for this).
As a further hint, you'll want to use two loops, one inside the other. The outer loop keeps the user entering numbers until their sum exceeds 179. The inner loop keeps the user entering a single number until it's between 1 and 42 inclusive.
def get_int(prompt=''):
while True:
try:
return int(raw_input(prompt))
except ValueError:
pass
def get_values():
values = []
total = 0
while total <= 179:
val = get_int('Enter a positive integer <= 42: ')
if 0 <= val <= 42:
values.append(val)
total += val
return values
def print_info(values):
print 'Sum is {}'.format(sum(values))
print 'Largest value is {}'.format(max(values))
print 'Smallest value is {}'.format(min(values))
def main():
values = get_values()
print_info(values)
if __name__=="__main__":
main()
You can repeatedly poll the number in a loop, and add the inputs into a list, e.g.
def input_numbers():
user_inputs = [] # a list of all user's inputs
while True:
num = raw_input("Enter a positive integer no greater than 42 ")
try:
num = int(num) # convert input string to integer
if num <= 0:
print "That is not a positive integer. Try again "
elif num > 42:
print "The number cannot exceed 42. Try again "
user_inputs.append(num)
except ValueError: # conversion to integer may fail (e.g. int('string') ?)
print 'Not a Number:', num
if some_condition_regarding(user_inputs):
break # eventually break out of infinite while loop
here some well-known tricks:
def min_and_max(your_num_list)
min=your_num_list[0]
max=your_num_list[0]
for num in your_num_list:
if num < min:
min=num
if max > num
max=num
return min,max
When you're writing a standalone Python program, it’s a good practice to use a main function. it allows you to easily add some unit tests, use your functions or classes from other modules (if you import them), etc.
And as others already said, it is a good idea to create a list and append a new element to it each time the user enters a valid number (until the sum of the numbers axceeds 179). If user entered an incorrect value, then just don’t append anything to the list and skip to the next iteration (so the user will be asked to enter a number again).
So basically it could look like this:
def validate_entered_number(num):
"""
Checks if the number is positive and is less or equal to 42.
Returns True if the number matches these conditions,
otherwise it returns False.
"""
if num < 0:
print "That is not a positive integer."
return False
if num > 42:
print "The number cannot exceed 42."
return False
return True
def main():
entered_numbers = []
while True:
try:
num = int(raw_input("Enter a positive integer less or equal to 42: "))
except ValueError:
print "You should enter a number"
continue
if validate_entered_number(num):
entered_numbers.append(num)
if sum(entered_numbers) > 179:
print "The sum of the numbers is %s" % sum(entered_numbers)
print "The smallest number entered is %s" % min(entered_numbers)
print "The largest number entered is %s" % max(entered_numbers)
return
if __name__ == "__main__":
main()
In fact, I can imagine a situation where you would want to just store the sum of the numbers, the smallest number and the largest number in three variables and update these variables in each iteration (add current number to the sum and compare it to the currently known smallest and larger numbers and update the corresponding variables when necessary), but in this case the longest list you can possibly have is only 180 elements (if all numbers are 1 and the user doesn’t enter 0 or you have modified the program to deny entering 0), which is very small amount of elements for a list in Python. But if you had to deal with really big amounts of numbers, I’d recommend to switch to a solution like this.
Thanks to everyone who answered. I've written the following code and it works nearly perfectly except the last module. If you exit the program after the first run (by pressing 0) it will exit, but if you run it a second time pressing 0 won't make it exit. It'll just go back to the beginning of the program. I don't know why.
Note: The assignment has various requirements that I had to incorporate in my code. Hence the unnecessary modules, global variables, and comments.
maxNum = 42 # declares global variable maxNum
target = 179 # declares global variable target
def user_input(): # prompts user to input a number 42 or less until all add up to 179
x = 0
nums = []
while sum(nums) <= target:
nums.append(int(raw_input("Enter a number: ")))
if int(nums[x]) > int(maxNum):
print "Number cannot exceed 42."
user_input()
else:
x += 1
print_nums(nums,x)
def print_nums(nums,x): # prints the sum of the numbers, the smallest, and the largest
print "Sum of all numbers is", sum(nums)
nums.sort()
x -= 1
print "Largest number entered is", nums[x]
print "Smallest number entered is", nums[0]
decide()
def decide(): # allows user to continue the program or exit
exit = raw_input("<9 to enter a new set of number. 0 to exit.> ")
while True:
if int(exit) == 0:
return
elif int(exit) == 9:
user_input()
user_input()

Categories

Resources