The code below shows error if a decimal (eg. 49.9) is sent to next variable. Can you please tell me why? Why does int() converts it into an integer?
next=raw_input("> ")
how_much = int(next)
if how_much < 50:
print"Nice, you're not greedy, you win"
exit(0)
else:
dead("You greedy bastard!")
If I dont use int() or float() and just use:
how_much=next
then it moves to "else" even if I give the input as 49.8.
As the other answers have mentioned, the int operation will crash if the string input is not convertible to an int (such as a float or characters). What you can do is use a little helper method to try and interpret the string for you:
def interpret_string(s):
if not isinstance(s, basestring):
return str(s)
if s.isdigit():
return int(s)
try:
return float(s)
except ValueError:
return s
So it will take a string and try to convert it to int, then float, and otherwise return string. This is more just a general example of looking at the convertible types. It would be an error for your value to come back out of that function still being a string, which you would then want to report to the user and ask for new input.
Maybe a variation that returns None if its neither float nor int:
def interpret_string(s):
if not isinstance(s, basestring):
return None
if s.isdigit():
return int(s)
try:
return float(s)
except ValueError:
return None
val=raw_input("> ")
how_much=interpret_string(val)
if how_much is None:
# ask for more input? Error?
int() only works for strings that look like integers; it will fail for strings that look like floats. Use float() instead.
Integers (int for short) are the numbers you count with 0, 1, 2, 3 ... and their negative counterparts ... -3, -2, -1 the ones without the decimal part.
So once you introduce a decimal point, your not really dealing with integers. You're dealing with rational numbers. The Python float or decimal types are what you want to represent or approximate these numbers.
You may be used to a language that automatically does this for you(Php). Python, though, has an explicit preference for forcing code to be explicit instead implicit.
import random
import time
import sys
while True:
x=random.randint(1,100)
print('''Guess my number--it's from 1 to 100.''')
z=0
while True:
z=z+1
xx=int(str(sys.stdin.readline()))
if xx > x:
print("Too High!")
elif xx < x:
print("Too Low!")
elif xx==x:
print("You Win!! You used %s guesses!"%(z))
print()
break
else:
break
in this, I first string the number str(), which converts it into an inoperable number. Then, I int() integerize it, to make it an operable number. I just tested your problem on my IDLE GUI, and it said that 49.8 < 50.
Use float() in place of int() so that your program can handle decimal points. Also, don't use next as it's a built-in Python function, next().
Also you code as posted is missing import sys and the definition for dead
Related
I'm a new to Python and a piece of code doesn't seem to work as desired.
Here is the code:
#Create a function that takes any string as argument and returns the length of that string. Provided it can't take integers.
def length_function(string):
length = len(string)
return length
string_input=input("Enter the string: ")
if type(string_input) == int:
print("Input can not be an integer")
else:
print(length_function(string_input))
Whenever I type an integer in the result, it gives me the the number of digits in that integer. However, I want to display a message that "Input can not be an integer".
Is there any error in my code or is there another way of doing this. Please respond. Thank You!
Any input entered is always string. It cannot be checked for int. It will always fail. You can do something like below.
def length_function(string):
length = len(string)
return length
string_input=input("Enter the string: ")
if string_input.isdigit():
print("Input can not be an integer")
else:
print(length_function(string_input))
Output:
Enter the string: Check
5
Enter the string: 1
Input can not be an integer
I'm not sure why you're wrapping len() in your length_function but that's not necessary. The result of input() will always be a string so your if cannot evalue to true. To turn it into a number use int(). This will fail if the input can't be parsed into an integer, so rather than an if...else you probably want to do sth like
try:
int(string_input)
print("Input cannot be an integer")
except ValueError:
print(length_function(string_input))
Even integers are taken as strings for example instead of 10 it is taking "10".
def RepresentsInt(s):
try:
int(s)
return True
except ValueError:
return False
def length_function(string):
length = len(string)
return length
string_input=input("Enter the string: ")
if RepresentsInt(String_input):
print("Input can not be an integer")
else:
print(length_function(string_input))
5.2 Write a program that repeatedly prompts a user for integer numbers until the user enters 'done'. Once 'done' is entered, print out the largest and smallest of the numbers. If the user enters anything other than a valid number catch it with a try/except and put out an appropriate message and ignore the number. Enter 7, 2, bob, 10, and 4 and match the output below.
largest = None
smallest = None
while True:
try:
num = input("Enter a number: ")
if num == "done" : break
print(num)
if num > largest:
largest=num
if num < smallest:
smallest=num
except:
print("Invalid input")
print("Maximum is", largest)
print("Minimum is", smallest)
desired output: my output:
Invalid input 2 ← Mismatch
Maximum is 10 4
Minimum is 2 5
maximum is 5(it prints the last input)
minimum is None
I'm a total beginner at programming and python so if the error is obvious pls break it down as much as you could..thank you so much.
The program will never reach print("Invalid input") since there is no error that could be thrown above. If you were to cast num to an integer with num = int(num) after you've checked if num == "done", then the program would catch invalid inputs like "bob"
input() returns a string, so you need to cast the input to integer with int() before comparing it as a number. Also remove your unnecessary print(num).
So change:
print(num)
to:
num = int(num)
The problem is that you are using strings, not numbers. 10 is a number, it is stored as numeric data and you can do things like compare size, add, subtract, etc. Specifically it is an integer, a number with no decimal places (computers store numbers in a lot of different ways). '10' is a string, a set of characters. Those characters happen to represent a number, but the computer doesn't know that. As far as it can tell it is just text.
What you can do to convert a string to an integer is simply num = int(num). If the number can be converted to an integer, it will be. If it can't, you will get an error. That is why the instructions tell you to use a try/catch block. It will catch this error.
Your question already explains what you want to do
If the user enters anything other than a valid number catch it with a try/except and put out an appropriate message
The explanation of why is that you need int(num) after you check for done, to try converting a string to an integer, and catch exception that happens for non integer inputs
I suggest you remove the try except, type anything but a number and observe the behavior
So I'm creating a program to show number systems, however I've run into issues at the first hurdle. The program will take a number from the user and then use that number throughout the program in order to explain several computer science concepts.
When explaining my first section, number systems, the program will say what type of number it is. I'm doing this by converting the string into a float number. If the float number only has '.0' after it then it converts it into a integer.
Currently I'm using this code
while CorrectNumber == False:
try:
Number = float(NumberString) - 0
print (Number)
except:
print ("Error! Not a number!")
This is useful as it shows if the user has entered a number or not. However I am unsure how to now check the value after the decimal place to check if I should convert it into a integer or not. Any tips?
If the string is convertable to integer, it should be digits only. It should be noted that this approach, as #cwallenpoole said, does NOT work with negative inputs beacuse of the '-' character. You could do:
if NumberString.isdigit():
Number = int(NumberString)
else:
Number = float(NumberString)
If you already have Number confirmed as a float, you can always use is_integer (works with negatives):
if Number.is_integer():
Number = int(Number)
Not sure I follow the question but here is an idea:
test = ['1.1', '2.1', '3.0', '4', '5', '6.12']
for number in test:
try:
print(int(number))
except ValueError:
print(float(number))
Returns:
1.1
2.1
3.0
4
5
6.12
Here is the method to check,
a = '10'
if a.isdigit():
print "Yes it is Integer"
elif a.replace('.','',1).isdigit() and a.count('.') < 2:
print "Its Float"
else:
print "Its is Neither Integer Nor Float! Something else"
This checks if the fractional-part has any non-zero digits.
def is_int(n):
try:
float_n = float(n)
int_n = int(float_n)
except ValueError:
return False
else:
return float_n == int_n
def is_float(n):
try:
float_n = float(n)
except ValueError:
return False
else:
return True
Testing the functions:
nums = ['12', '12.3', '12.0', '123.002']
for num in nums:
if is_int(num):
print(num, 'can be safely converted to an integer.')
elif is_float(num):
print(num, 'is a float with non-zero digit(s) in the fractional-part.')
It prints:
12 can be safely converted to an integer.
12.3 is a float with non-zero digit(s) in the fractional-part.
12.0 can be safely converted to an integer.
123.002 is a float with non-zero digit(s) in the fractional-part.
Regular expressions are nice for this as they can be custom tailored in case you have some edge-cases. For example:
How do you want to handle padded numbers (numbers with leading zeros). My example here includes this consideration.
Do you need to handle exponents, e.g. 2.3E12 or 2.3e12. This is not handled here.
...in other words, if your implementation doesn't agree with an assumption mine makes, you can change it.
Regular expressions work in all versions of Python (and other languages). They can be compiled for reuse, so should be pretty quick.
# Int is:
# - Only numbers that do NOT start with 0 (protect padded number strings)
# - Exactly 0
re_int = re.compile(r"(^[1-9]+\d*$|^0$)")
# Float is:
# - Only numbers but with exactly 1 dot.
# - The dot must always be followed number numbers
re_float = re.compile(r"(^\d+\.\d+$|^\.\d+$)")
These tests all pass:
def test_re_int(self):
self.assertTrue(re_int.match("1"))
self.assertTrue(re_int.match("1543"))
self.assertTrue(re_int.match("0")) # Exactly 0 is good
self.assertFalse(re_int.match("1.54"))
self.assertFalse(re_int.match("1a4"))
self.assertFalse(re_int.match("14a"))
self.assertFalse(re_int.match("a14"))
self.assertFalse(re_int.match("00")) # Ambiguous
self.assertFalse(re_int.match("0012")) # Protect padding
def test_re_float(self):
self.assertTrue(re_float.match("1.0"))
self.assertTrue(re_float.match("1.456"))
self.assertTrue(re_float.match("567.456"))
self.assertTrue(re_float.match("0.10"))
self.assertTrue(re_float.match(".10"))
self.assertFalse(re_float.match("1.0.0")) # Too many dots
self.assertFalse(re_float.match(".10.0"))
self.assertFalse(re_float.match("..034"))
self.assertFalse(re_float.match("1"))
self.assertFalse(re_float.match("0"))
self.assertFalse(re_float.match("1a4"))
self.assertFalse(re_float.match("14a"))
self.assertFalse(re_float.match("a14"))
self.assertFalse(re_float.match("1.a4"))
self.assertFalse(re_float.match("1.4a"))
self.assertFalse(re_float.match(".a14"))
Please comment if there are any caveats, missing details or regular expression improvements I can make.
Here's my gist that not only checks for positive & negative ints, but also checks for positive & negative floats. It also checks if the string is just a normal non-number.
def int_float_or_string(string):
try:
int(string) # strict and nice
except ValueError:
if is_strictly_float(string): # float() is too permissive, this is better
return "float"
else:
return "string"
else:
return "int"
def is_strictly_float(string):
if string.startswith("-"):
string = string[1:]
return "." in string and string.replace(".", "", 1).isdecimal()
int() is great for checking an integer, but float() has a problem of being too laid back in what it calls a float.
x=input("Enter a value to check it's type: ")
def checknumber(a):
try:
a=float(a)
if int(a)/a==1:
print("This is Integer")
return a
elif a/int(a)>1:
print("This is Float")
return a
except ValueError:
print("This value is String")
return str(a)
x=checknumber(x)```
I rewrite bin Mohammed's answer as follows (number also may be negative):
from numpy import nan, isnan
def is_valid_number(s):
if (s.find('-') <= 0) and s.replace('-', '', 1).isdigit():
if (s.count('-') == 0):
s_type = 'Positive Integer'
else:
s_type = 'Negative Integer'
elif (s.find('-') <= 0) and (s.count('.') < 2) and \
(s.replace('-', '', 1).replace('.', '', 1).isdigit()):
if (s.count('-') == 0):
s_type = 'Positive Float'
else:
s_type = 'Negative Float'
else:
s_type = "Not alphanumeric!"
return('{}\t is {}'.format(s, s_type))
example:
nums = ['12', '-34', '12.3', '-12.0', '123.0-02', '12!','5-6', '3.45.67']
for num in nums:
print(is_valid_number(num))
result:
12 is Positive Integer
-34 is Negative Integer
12.3 is Positive Float
-12.0 is Negative Float
123.0-02 is Not alphanumeric!
12! is Not alphanumeric!
5-6 is Not alphanumeric!
3.45.67 is Not alphanumeric!
minimal code:
from numpy import nan, isnan
def str2num(s):
if (s.find('-') <= 0) and s.replace('-', '', 1).isdigit():
return(int(s))
elif (s.find('-') <= 0) and (s.count('.') < 2) and \
(s.replace('-', '', 1).replace('.', '', 1).isdigit()):
return(float(s))
else:
return(nan)
example:
nums = ['12', '-34', '12.3', '-12.0', '123.0-02', '12!','5-6', '3.45.67']
for num in nums:
x = str2num(num)
if not isnan(x):
print('x =', x) # .... or do something else
result:
x = 12
x = -34
x = 12.3
x = -12.0
This is a piece of code I encountered in the 7th lecture on introduction to computer science on MIT OCW. This small program gets input for base and height then calculate the hypotenuse with Pythagoras theorem.
For some reason, it couldn't recognize entry of float.
The code is as follows:
#! /Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5
import math
#Get base
inputOK = False
while not inputOK:
base = input("Enter base: ")
if type(base) == type(1.0):
inputOK = True
else:
print("Error. Base must be a floating point number.")
#Get Height
inputOK = False
while not inputOK:
height = input("Enter height: ")
if type(height) == type(1.0):
inputOK = True
else:
print("Error. height must be a floating point number.")
hyp = math.sqrt(base*base + height*height)
print("Base: " + str(base) + ", height: " + str(height) + ", hypotenuse:" + str(hyp))
This is one of those cases where it is easier to ask for forgiveness than permission. Instead of trying to look at the object and assert it is a float before you act, try to use it as a float and catch any exceptions.
That is, instead of using ifs use:
try:
base = float(base)
inputOK = True
except ValueError as e:
print("Error. Base must be a floating point number.")
This applies similarly to the height value you're trying to get afterwards.
Regardless, input() returns a string so type(input()) will always return str. It is better to cast it to a float (note: ints are also applicable and will be made to floats) and see if it is acceptable than trying to discern its type with if checks.
Mandatory aside, if you even need to check for types, don't use type(obj_a) == type(obj_b), it is arguably always better to use isinstance(obj_a, type(obj_b)).
The code appears to be written for Python 2, not Python 3, as it requires input() to return something other than a string. In Python 3, input() always returns a string, it never applies eval() to that result like Python 2 would.
It has other issues as well, like using type(base) == type(1.0), completely ignoring the availability of the float object and using is to test for identity, and misses out completely on the far superior isinstance() function.
Just use exception handling instead:
while True:
try:
base = float(input("Enter base: "))
break
except ValueError:
print("Error. Base must be a floating point number.")
Note that there is no need for a inputOK boolean either.
Python beginner here. I'm writing a program that uses an infinite loop and allows the user to enter key terms to access different 'tools' or 'modules'.
Within one of these 'modules', the user can enter a value and convert it to binary. I want to:
Allow the program to recognize if the value is either an int or a
float and then run code that converts the value to binary
Allow the program to recognize if the value entered is a str and the str says 'back', in which the current loop will be exited.
As far as I know this issue is occurring as input() converts whatever is entered to a str automatically (due to: http://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/io.html "First it prints the string you give as a parameter").
How can I make the code below recognize if the input is a str, float, or int and then execute the relevant if statements? Currently, this part of my code can accept 'back' to exit out of the loop but will take any int or float value as a str, making the program prompt the user to enter a decimal value once more.
#decimal to binary
while search == "d2b":
dec2bin = input("\nDecimal Value: ")
if type(dec2bin) == int:
print("Binary Value: " + "{0:b}".format(dec2bin))
elif type (dec2bin) == str:
if dec2bin == "back":
search = 0
elif type (dec2bin) == float:
#code for float to binary goes here
Edit: not the same as this thread (Python: Analyzing input to see if its an integer, float, or string), as a list is used there over input()
E2: cannot seem to use suggested duplicate as a solution to issue. However, a comment in this thread by Francisco has the solution
Use exceptions! The int and float functions throw a ValueError exception when they can't convert the value passed.
while search == "d2b":
dec2bin = input("\nDecimal Value: ")
try:
dec2bin = int(dec2bin)
except ValueError:
pass
else:
print("Binary Value: " + "{0:b}".format(dec2bin))
continue
try:
dec2bin = float(dec2bin)
except ValueError:
pass
else:
#code for float to binary goes here
continue
if dec2bin == "back":
search = 0
The order in which you try the conversions is important, since every value passed to int is valid with float, and every value passed to float is a valid to be passed to str
You can use str.isalpha() and str.isdigit() to achieve this. Hence your code will be as:
while search == "d2b":
dec2bin = input("\nDecimal Value: ")
if dec2bin.lstrip("-").isdigit():
print("Binary Value: " + "{0:b}".format(int(dec2bin))) # OR, simply bin(int(dec2bin))
elif dec2bin.isalpha(): # OR, isalnum() based on the requirement
if dec2bin == "back":
search = 0
else:
try:
_ = float(dec2bin)
except:
pass
else:
#code for float to binary goes here
Here, I am using str.lstrip() to remove - from the start of the string as .isdigit() can not check for negative number string.
Refer Python 3: String Methods for complete list of methods available with str objects.
using ast.literal_eval() you can do a similar operation. here is a sample code of converting input() str to str, float, and int.
import ast
def input_conv(strr):
try:
base = ast.literal_eval(strr)
return base
except:
return strr
>>> b = input()
hi
>>> input_conv(b)
'hi'
>>> type(input_conv(b))
<class 'str'>
>>> b = input()
1
>>> type(input_conv(b))
<class 'int'>
>>> b = input()
1.222
>>> type(input_conv(b))
<class 'float'>