Python conditional code not working properly - python

I've just started to learn python and can't get this code to work properly.
def percentage():
while True:
try:
x = int(input('First number:'))
y = int(input('Second number:'))
fraction = x/y
percentage = fraction * 100
final = "%d" % percentage
return final
except ZeroDivisionError:
pass
except ValueError:
pass
if percentage() <= 1:
print('E')
elif percentage() >= 99:
print('F')
else:
print(percentage(), "%")
The 'F' is printed only when I input x = 999 and y = 1000. Any other values just prompt the user again and again.
The code should output 'E' when the percentage function returns <= 1, 'F' when it returns >= 99 and the actual percentage number when any other value is returned.

I am getting a type error as final is a string which you then try to compare with an integer. The issue that you are asking about, however, is due to 3 calls of percentage(). Instead call it once and assign the return value a variable then run your tests against the variable:
def percentage():
while True:
try:
x = int(input('First number:'))
y = int(input('Second number:'))
return 100 * x / y
except ZeroDivisionError:
print('x')
pass
except ValueError:
print('y')
pass
p = percentage()
if p <= 1:
print('E')
elif p >= 99:
print('F')
else:
print(p, "%")

I would restructure your program so that your percentage function returns the percentage as a float instead of a string, and deal with the string formatting in your print statements.
We should also set some variable equal to the output of your function using something like p = percentage(), and then use p in your conditionals so that we don't unintentionally run percentage() multiple times from within your conditionals.
def percentage():
while True:
try:
x = int(input('First number:'))
y = int(input('Second number:'))
fraction = x/y
percentage = fraction * 100
# final = "%d" % percentage
return percentage
except ZeroDivisionError:
pass
except ValueError:
pass
p = percentage()
if p < 1:
print('E')
elif p >= 99:
print('F')
else:
print(f"{p:.2f}%")
Example program run:
First number:2
Second number:3
66.67%

Related

Loop and check if integer

I have an exercise:
Write code that asks the user for integers, stops loop when 0 is given.
Lastly, adds all the numbers given and prints them.
So far I manage this:
a = None
b = 0
while a != 0:
a = int(input("Enter a number: "))
b = b + a
print("The total sum of the numbers are {}".format(b))
However, the code needs to check the input and give a message incase it is not an integer.
Found that out while searching online but for the life of me I cannot combine the two tasks.
while True:
inp = input("Input integer: ")
try:
num = int(inp)
except ValueError:
print('was not an integer')
continue
else:
total_sum = total_sum + num
print(total_sum)
break
I suspect you need an if somewhere but cannot work it out.
Based on your attempt, you can merge these two tasks like:
a = None
b = 0
while a != 0:
a = input("Enter a number: ")
try:
a = int(a)
except ValueError:
print('was not an integer')
continue
else:
b = b + a
print("The total sum of the numbers are {}".format(b))
If you want to use an If-Statement, you don't need the else: If the number is not 0 it will just start again until it's 0 sometime.
total_sum = 0
while True:
inp = input("Input integer: ")
try:
num = int(inp)
except ValueError:
print('was not an integer')
continue
total_sum = total_sum + num
if num == 0:
print(total_sum)
break
Since input's return is a string one can use isnumeric no see if the given value is a number or not.
If so, one can convert the string to float and check if the given float is integer using, is_integer.
a = None
b = 0
while a != 0:
a = input("Enter a number: ")
if a.isnumeric():
a = float(a)
if a.is_integer():
b += a
else:
print("Number is not an integer")
else:
print("Given value is not a number")
print("The total sum of the numbers are {}".format(b))

AttributeError: 'str' object has no attribute 'list'

We have to find out the average of a list of numbers entered through keyboard
n=0
a=''
while n>=0:
a=input("Enter number: ")
n+=1
if int(a)==0:
break
print(sum(int(a.list()))/int(n))
You are not saving the numbers entered. Try :
n = []
while True:
a=input("Enter number: ")
try: #Checks if entered data is an int
a = int(a)
except:
print('Entered data not an int')
continue
if a == 0:
break
n.append(a)
print(sum(n)/len(n))
Where the list n saves the entered digits as a number
You need to have an actual list where you append the entered values:
lst = []
while True:
a = int(input("Enter number: "))
if a == 0:
break
else:
lst.append(a)
print(sum(lst) / len(lst))
This approach still has not (yet) any error management (a user enters float numbers or any nonsense or zero at the first run, etc.). You'd need to implement this as well.
a needs to be list of objects to use sum, in your case its not. That is why a.list doens't work. In your case you need to take inputs as int (Can be done like: a = int(input("Enter a number")); ) and then take the integer user inputs and append to a list (lets say its name is "ListName")(listName.append(a)), Then you can do this to calculate the average:
average = sum(listName) / len(listName);
def calc_avg():
count = 0
sum = 0
while True:
try:
new = int(input("Enter a number: "))
if new < 0:
print(f'average: {sum/count}')
return
sum += new
count += 1
print(f'sum: {sum}, numbers given: {count}')
except ValueError:
print("That was not a number")
calc_avg()
You can loop, listen to input and update both s (sum) and c (count) variables:
s, c = 0, 0
while c >= 0:
a = int(input("Enter number: "))
if a == 0:
break
else:
s += a
c += 1
avg = s/c
print(avg)

Collatz Sequence. (Python 3)

I've started the book "Automate The Boring Stuff" by Al Sweigart.
At the end of Chapter 3, the author suggests creating a Collatz Sequence in Python as a practice exercise. (the practice exercise suggests I use a the print function and return statement)
When I use a print() function in my code, it works great and I get all the evaluated values I want to see on the screen:
print("This is The Collatz Sequence")
user = int(input("Enter a number: "))
def collatz(n):
print(n)
while n != 1:
if n % 2 == 0:
n = n // 2
print(n)
else:
n = n * 3 + 1
print(n)
collatz(user)
Question:
How come when I want to use the return statement, the while loop only runs once?
For example, passing the integer 3 into my function with the return statement only gives me the return value of 3 and 10:
print("This is The Collatz Sequence")
user = int(input("Enter a number: "))
def collatz(n):
print(n)
while n != 1:
if n % 2 == 0:
n = n // 2
return n
else:
n = n * 3 + 1
return n
result = collatz(user)
print(result)
return exits the function and, therefore terminates your while loop.
Perhaps you meant to use yield instead:
print("This is The Collatz Sequence")
user = int(input("Enter a number: "))
def collatz(n):
print(n)
while n != 1:
if n % 2 == 0:
n = n // 2
yield(n)
else:
n = n * 3 + 1
yield(n)
print(list(collatz(user)))
Output:
This is The Collatz Sequence
Enter a number: 3
3
[10, 5, 16, 8, 4, 2, 1]
Yield is logically similar to a return but the function is not terminated until a defined return or the end of the function is reached. When the yield statement is executed, the generator function is suspended and the value of the yield expression is returned to the caller. Once the caller finishes (and assumably uses the value that was sent) execution returns to the generator function right after the yield statement.
In your code you don't re-feed the new value back into your equation. Try separating your while loop from the collatz module. I have an example of this below:
def collatz(number):
if number % 2 == 0:
return number // 2
elif number % 2 == 1:
return 3 * number + 1
chosenInt = int(input('Enter an integer greater than 1: '))
print(chosenInt)
while chosenInt != 1:
chosenInt = collatz(chosenInt)
print(chosenInt)
def collatz(number):
if (number%2 == 0):
return print(number//2);
else:
return (print(number*3+1));
inputNumber = input("Enter a number greater than 1:");
result = collatz(int(inputNumber));
while result != 1:
result = collatz(result);
I am getting a typeError with it! Don't know why?

get raw input that is between a set of numbers with some checks

I am trying to get the user input 2 numbers which are split into a list of 2 integers, but unfortunately I can't seem to get them to turn into integers, but I am also unsure of my checks and if it is going to terminate properly and return what I need.
def getlohiint():
lohilist = []
lohi = raw_input("Enter min and max number of points to use(e.g., 2 1000): ")
lohilist = lohi.split()
for x in lohilist:
int(x)
if lohilist[0]<=2 and lohilist[1]<=1000 and lohilist[0]<lohilist[1]:
break
else:
prompt = "%d is not in the range of 2 to 1000; "
prompt1 = "must be at least 2"
prompt2 = "must be no higher than 1000"
if lohilist[0]<2:
print prompt + prompt1
elif lohilist[1]>1000:
print prompt + prompt2
else:
print prompt + prompt1 + prompt2
lohi
high = lohilist[1]
low = lohilist[0]
return(low, high)
You never assign the result of int(x) to anything. It's easiest achieved with a list comprehension:
lohilist = [int(x) for x in lohi.split()]
Note that you can assign to multiple targets at once:
low, high = [int(x) for x in lohi.split()]
would convert everything in lohi to integers and assign to the two variables in one go.
You may want to test for exceptions too here:
def getlohiint():
while True:
lohi = raw_input("Enter min and max number of points to use(e.g., 2 1000): ")
try:
low, high = [int(x) for x in lohi.split()]
except ValueError:
# either not integers or not exactly 2 numbers entered.
print "You must enter exactly 2 numbers here"
continue
if low <= 2 and high <= 1000 and low < high:
# valid input, return
return low, high
if low > 2:
print 'The minimum must be 2 or lower'
if high > 1000:
print 'The maximum must be 1000 or lower'
if low >= high:
print 'The maximum must be greater than the minimum'
int(x) returns an integer value, it does not modify the value of x.
You probably want something like:
def getlohiint():
lohilist = []
lohi = raw_input("Enter min and max number of points to use(e.g., 2 1000): ")
lohilist = lohi.split()
lohilist = [int(x) for x in lohilist]
I would abstract this out a bit: make a function that parses a list of integers from input, then another function which takes a list of integers and tests that they fit your criteria:
import sys
# version compatibility shim
if sys.hexversion < 0x3000000:
# Python 2.x
inp = raw_input
else:
# Python 3.x
inp = input
def get_ints(prompt, delimiter=None):
while True:
try:
return [int(i) for i in inp(prompt).split(delimiter)]
except ValueError:
pass
def get_lo_hi_ints(prompt, min_=None, max_=None):
while True:
try:
lo, hi = get_ints(prompt)
if lo >= hi:
print("First value must be < second value")
elif (min_ is not None and lo < min_):
print("Low value must be >= {}".format(min_))
elif (max_ is not None and hi > max_):
print("High value must be <= {}".format(max_))
else:
return lo, hi
except ValueError:
print("Please enter 2 values!")
then you can use it like
min_points, max_points = get_lo_hi_ints("Enter min and max number of points to use(e.g., 2 1000): ", 2, 1000)

If statement for number in a range

I cannot tweak this for it to only respond to a value between 1 and 100. I know its somthing simple, but cannot find anything through searching that works.
while True:
Mynumber = raw_input('Enter number of random points')
if Mynumber == '0 < 100':
print 'number choosen'
Mynumber = int(Mynumber)
break
if 1 <= my_number <= 100:
Or, since you are grabbing from raw_input and have to convert to int from unknown string first:
try:
my_number = int(raw_number)
except ValueError:
print "%s not an integer value." % raw_number
else:
if 1 <= raw_number <= 100:
Though on further analysis, it looks like you are trying to do:
base_prompt = 'Enter number of random points'
user_input = raw_input(base_prompt)
while True:
try:
input_number = int(user_input)
except ValueError:
user_input = raw_input('%s not an interger\n%s' % (user_input, base_prompt))
else:
if 1 <= input_number <= 100:
break
else:
user_input = raw_input('%d out of range (1 to 100)\n%s' % (input_number, base_prompt))
If you're on Python 3.x, the following also works:
if int(my_number) in range(1, 101):
# ...
The caveat is that the end point of a range is exclusive, so it probably reads less intuitively than chained operators.

Categories