how can my code could be written more succinctly? - python

Question: how can my code could be written more succinctly?
Background:
Working on Automate the boring stuff challenges in Python. The program below is meant to:
get the user to enter an integer
check that what was entered was an integer (with try and except)
perform the collatz() function on that sequence
CODE:
def accept_int():
while True:
try:
i = int(input())
break
except ValueError:
print('Please enter an integer value: ')
continue
return i
def collatz(i):
while num > 1:
if i % 2 == 1:
return 3* i + 1
else:
return i // 2
print('Hello, please enter an integer: ')
num = accept_int()
while num > 1:
num = collatz(num)
print(num)

Related

How to stop Python while I key in a value that indicates "break"

in the python code below, the desired output is to find the max and min from all of the key-in values (via input function) and when I key in "done", it stops (meaning that there will be no pop-up anymore), while other non-integer strings will print "Invalid output".
However, even if I key in "done", the pop-up still appears and it never ends, what is the problem of my code?
lar = None
smal = None
while True:
try:
num = int(input("Enter a number:"))
except:
if num == "done":
break
else:
print("Invalid input")
if lar is None:
lar = num
elif lar <= num:
lar = num
if smal is None:
smal = num
elif smal >= num:
smal = num
print("Maximum is", lar)
print("Minimum is", smal)
Its because of your try/except:
...
while True:
try:
num = int(input("Enter a number:")) # issue is here
except:
if num == "done":
break
else:
print("Invalid input")
...
When you cast int() on the result of input() when you've typed "done" in the terminal, this throws a ValueError (see example of the running below):
>>> Enter a number:h
Traceback (most recent call last):
File "main.py", line 5, in <module>
num = int(input("Enter a number:"))
ValueError: invalid literal for int() with base 10: 'h'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "main.py", line 7, in <module>
if num == "done":
NameError: name 'num' is not defined
In this example, the first value ever given to your while loop to try and assign to the variable num is "h", and this errors on int() since "h" is not a base 10 number (which is what int() tries to cast a string as). That ValueError is caught in the except portion of your block, but then the if num == "done" fails because num is never assigned to since the first try failed.
Lets look at another example:
>>> Enter a number:1
>>> Enter a number:h
Invalid input
>>> Enter a number:
Here we didn't receive the error traceback, but why?
Well the fact that we gave a valid base 10 integer as our first input, in this case "1", it was successfully assigned to the variable num and thus the if/else inside the except block executes correctly since num currently holds "1".
To resolve your issue, your loop needs to look like this:
lar = None
smal = None
while True:
# never give variables the same name as keywords
inpt = input('Enter a number (or done): ')
if inpt == 'done':
break
try:
num = int(inpt)
except ValueError as err:
# f-string to display error
print(f'Invalid input: {inpt}')
if not lar:
lar = num
elif lar <= num:
lar = num
if not smal:
smal = num
elif smal >= num:
smal = num
print("Maximum is", lar)
print("Minimum is", smal)
>>> Enter a number (or done): 1
>>> Enter a number (or done): 8
>>> Enter a number (or done): 3
>>> Enter a number (or done): 2
>>> Enter a number (or done): -1
>>> Enter a number (or done): 4
>>> Enter a number (or done): done
Maximum is 8
Minimum is -1
Personally I'd adjust even further using built-ins:
nums = []
while True:
# never give variables the same name as keywords
inpt = input('Enter a number (or done): ')
if inpt == 'done':
break
try:
num = int(inpt)
except ValueError as err:
# f-string to display error
print(f'Invalid input: {inpt}')
nums.append(num)
print("Maximum is", max(nums))
print("Minimum is", min(nums))
When a user inputs "done", it is then trying to be converted into an int. This throws an error and the value of num is not set, so when it is checked if it is equal to "done" it will never be. You should set check the user input before attempting to convert to an int.
lar = None
smal = None
while True:
try:
user_input =input("Enter a number:")
if user_input == "done":
break
num = int(user_input)
except:
print("Invalid input")
if lar is None:
lar = num
elif lar <= num:
lar = num
if smal is None:
smal = num
elif smal >= num:
smal = num
print("Maximum is", lar)
print("Minimum is", smal)
When the exception is raised, the new value that is inputted is never saved to the num variable.
You could add the if-statement before converting the input to an integer.
Here's a quick example:
num = input("Enter a number:")
if num == "done":
break
try:
num = int(num)
except ValueErorr:
print("Invalid input")

Convert roman to integer - Python [duplicate]

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 1 year ago.
I've tried the following Python 3 code that transform from Roman to Integer.
The code is working fine. But there is a problem happened when I input an integer number or string (ex: 1, 2 or any integer number, string) it shows the message "Invalid input! Try again!" and the program ends. I want if the program input is valid it will end but if the input is invalid the input message should continue till its become a valid input.
Here is my code:
class Solution(object):
def roman_to_int(self, s):
"""
:type s: str
:rtype: int
"""
roman = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000,'IV':4,'IX':9,'XL':40,'XC':90,'CD':400,'CM':900}
i = 0
num = 0
while i < len(s):
if i+1<len(s) and s[i:i+2] in roman:
num+=roman[s[i:i+2]]
i+=2
else:
#print(i)
num+=roman[s[i]]
i+=1
return num
ob1 = Solution()
message = str(input("Please enter your roman number: "))
try:
n = ob1.roman_to_int(message)
if n > 3999: raise Exception()
print(n)
except Exception:
print("Invalid input! Try again!")
Try this:
while True:
message = input("Please enter your roman number: ")
try:
n = ob1.roman_to_int(message)
if n > 3999: raise Exception()
print(n)
break
except Exception:
print("Invalid input! Try again!")

how to use a while loop in my python code

Q) Write a function named collatz() that has one parameter named number. If a number is even, then collatz() should print number // 2 and return this value. If a number is odd, then collatz() should print and return 3 * number + 1. Then write a program that lets the user type in an integer and that keeps calling
collatz() on that number until the function returns the value 1.
This is the code I wrote for the above problem but I need a small help on how to use the while loop so when I get a ValueError rather than breaking out of the program I want the program to re-execute the program rather than just displaying the print statement in except.
try:
def collatz(number):
if number % 2 == 0:
print(number // 2)
return number // 2
elif number % 2 == 1:
print(3 * number + 1)
return 3 * number + 1
x = int(input("Enter a number: "))
while x != 1:
x = collatz(x)
except ValueError:
print("Please enter a numerical value")
You could modify the code from the HandlingExceptions - Python Wiki:
def collatz(number):
if number % 2 == 0:
print(number // 2)
return number // 2
elif number % 2 == 1:
print(3 * number + 1)
return 3 * number + 1
has_input_int_number = False
while has_input_int_number == False:
try: # try to convert user input into a int number
x = int(input("Enter a number: "))
has_input_int_number = True # will only reach this line if the user inputted a int
while x != 1:
x = collatz(x)
except ValueError: # if it gives a ValueError
print("Error: Please enter a numerical int value.")
Example Usage:
Enter a number: a
Error: Please enter a numerical int value.
Enter a number: 1.5
Error: Please enter a numerical int value.
Enter a number: 5
16
8
4
2
1
def collatz(number):
if number % 2 == 0:
print(number // 2)
return number // 2
elif number % 2 == 1:
print(3 * number + 1)
return 3 * number + 1
x = int(input("Enter a number: "))
while x != 1:
try:
x = collatz(x)
except ValueError:
print("Please enter a numerical value")
Use while True and break if not statified.
def collatz(x):
x= x//2 if x%2==0 else x*3+1
print(x)
return x
def func(x):
while True:
x = collatz(x)
if x==1:
break
def run():
while True:
try:
x = int(input("Input a positive number: "))
assert x>0
func(x)
break
except Exception as exc:
#print("Exception: {}".format(exc))
pass
if __name__ == "__main__":
run()

Collatz Sequence: Automate the Boring Stuff with Python Chapter 3 Practice Project

This is my working code:
number = int(input())
while number > 1:
if number % 2 == 0:
number = int(number) // 2
print (number)
elif number % 2 == 1:
number = 3 * int(number) + 1
print (number)
Now I'm trying to add the exception that if user input has non-integer value, it should print 'Enter a number'
while True:
try:
number = int(raw_input())
break
except ValueError:
print("Enter a number!")
while number > 1:
....
EDIT: As noted in a comment by Anton, use raw_input in Python 2, and input in Python 3.
I'm a complete beginner so I would appreciate all kinds of tips. Here is how I managed to solve the problem, and for now it seems to work fine:
def collatz(number):
if number%2 == 0:
return number // 2
else:
return 3*number+1
print ('Enter a number:')
try:
number = int(input())
while True:
if collatz(number) != 1:
number= collatz(number)
print(number)
else:
print('Success!')
break
except ValueError:
print('Type an integer, please.')
You could check for ValueError for the except. From docs:
exception ValueError
Raised when a built-in operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception such as IndexError.
try:
number = int(input())
while number > 1:
if number % 2 == 0:
number = int(number) // 2
print (number)
elif number % 2 == 1:
number = 3 * int(number) + 1
print (number)
except ValueError:
print('Enter a number')
You could do this-
while number != 1:
try:
if number % 2 == 0:
number = int(number) // 2
print (number)
elif number % 2 == 1:
number = 3 * int(number) + 1
print (number)
except ValueError:
print('Enter a number')
break
def collatz(number):
if number % 2 == 0:
return number // 2
else:
return 3 * number + 1
while True:
try:
value = int(input("Eneter a number: "))
break
except ValueError:
print("enter a valid integer!")
while value != 1:
print(collatz(value))
value = collatz(value)
def coll(number):
while number !=1:
if number%2==0:
number= number//2
print(number)
else:
number= 3*number+1
print(number)
while True:
try:
number = int(input("Enter the no:"))
break
except ValueError:
print("Enter a number")
print(coll(number))
I did it like this:
# My fuction (MINI-Program)
def collatz(number):
if number % 2 == 0:
return number // 2
else:
return 3 * number + 1
# try & except clause for errors for non integers from the users input
try:
userInput = int(input("Enter a number: "))
# Main loops till we get to the number 1
while True:
number = collatz(userInput)
if number !=1:
userInput = number
print(userInput)
else:
print(1)
break
except ValueError:
print("Numbers only! Restart program")

Python Prime Numbers Loop

When running this code, I keep having an error. I would like to know what is wrong. The code has to be able to read words and integers and repeat the prompt(Please enter an integer >= 2: ') until it is greater or equal to 2. Thanks in advance.
def prime_number():
prime_num = input('Please enter an integer >= 2: ')
while not(prime_num.isdigit() and int(prime_num)<1):
prime_num = input('Please enter an integer >= 2: ')
for i in range(2,int(prime_num)+1):
for x in range(2,i):
if i%x == 0:
break
else:
print (i)
You need to enter the function. This is typically done in python with:
def prime_number():
prime_num = input('Please enter an integer >= 2: ')
while not(prime_num.isdigit() and int(prime_num)<1):
prime_num = input('Please enter an integer >= 2: ')
for i in range(2,int(prime_num)+1):
for x in range(2,i):
if i%x == 0:
break
else:
print (i)
if __name__ == "__main__":
prime_number()
Just some advice in general. I would separate the input logic from the prime number calculation logic.
As mentioned by #rpattiso, you are not invoking the method and
You while condition is buggy
This should work:
def prime_number():
prime_num = input('Please enter an integer >= 2: ')
while not (prime_num.isdigit() and not int(prime_num)<1):
prime_num = input('Please enter an integer >= 2: ')
for i in range(2,int(prime_num)+1):
for x in range(2,i):
if i%x == 0:
break
else:
print (i)
prime_number()

Categories

Resources