I'm a noobie, learning to code and i stumbled upon an incorrect output while practicing a code in python, please help me with this. I tried my best to find the problem in the code but i could not find it.
Code:
def compare(x,y):
if x>y:
return 1
elif x==y:
return 0
else:
return -1
i=raw_input("enter x\n")
j=raw_input("enter y\n")
print compare(i,j)
Output:
-> python python.py
enter x
10
enter y
5
-1
The output that i had to receive is 1 but the output that i receive is -1. Please help me with the unseen error in my code.
Thank you.
raw_input returns a string always.
so you have to convert the input values into numbers.
i=raw_input("enter x\n")
j=raw_input("enter y\n")
print compare(i,j)
should be
i=int(raw_input("enter x\n"))
j=int(raw_input("enter y\n"))
print compare(i,j)
Your issue is that raw_input() returns a string, not an integer.
Therefore, what your function is actually doing is checking "10" > "5", which is False, therefore it falls through your if block and reaches the else clause.
To fix this, you'll need to cast your input strings to integers by wrapping the values in int().
i.e.
i = int(raw_input("enter x\n")).
Use the inbuilt cmp builtin function.
>>> help(cmp)
Help on built-in function cmp in module __builtin__:
cmp(...)
cmp(x, y) -> integer
Return negative if x<y, zero if x==y, positive if x>y.
So your function will look like this.
>>> def compare(x,y):
... return cmp(x,y)
...
>>>
Then get two variables using raw_input() which returns string, So If you are typing two numbers with a blankspace in the middle, splitting based on blank space will save two numbers in these x and y, and then apply map function which takes two parameters, one int function and the sequence which is nothing but a list created out of split().
>>> x,y = map(int, raw_input().split())
3 2
Now Comparing the x and y, Since x = 3 and y =2, Now since as per the documentation of cmp(), It Return negative if xy.
>>> compare(x,y)
1
>>> compare(y,x)
-1
>>> compare(x-1,y)
0
>>>
Related
I wish to cast a string or a number to an integer only if the casting is "lossless" or, another way to put it, only if the string or number is indeed an integer.
For instance,
3.0 (a float that is indeed an integer) -> 3.
'3.000' (a string that is an integer) -> 3.
3.1 -> exception raised.
'4.2' -> exception raised.
Directly doing int(x) will convert 3.1 to 3.
This is the best I have:
def safe_cast_to_int(x):
int_x = int(x)
if np.issubdtype(type(x), np.floating):
assert int_x == x, \
f"Can't safely cast a non-integer value ({x}) to integer"
return int_x
but I wonder if there is a better or more Pythonic way?
If I understand you correctly, you only want to cast something if it's a whole number.
If that's the case, you could first cast it to a float and then check with float.is_integer() function if it's an integer.
Here are the examples with values of the question.
>>> float('3.0').is_integer()
True
>>> float('3.000').is_integer()
True
>>> float('3.1').is_integer()
False
>>> float('4.2').is_integer()
False
You could convert to float and modulus the data with 1 to check if you want to keep it a float
val = float(src)
val = int(val) if not val%1 else val
Edit: is_integer() is just doing the below for you, but with a bunch of conditions and flags attached before it gets to this line.
o = (floor(x) == x) ? Py_True : Py_False;
If you want things that look like integers, but aren't really integer values, as in (1.03-0.42)*100, then you need to test to see how "near" an integer a value is, and accept anything close. How close you accept as "integer" will depend on your exact use case:
import sys
tests = [
42,
'1.00',
3.2,
(1.03-0.42)*100,
]
for x in tests:
is_close_to_int = abs(int(float(x))-float(x))<0.00000000001
print(f"{x}: {float(x).is_integer()} {is_close_to_int}")
This outputs:
42: True True
1.00: True True
3.2: False False
61.00000000000001: False True
Showing that for many cases float's is_integer helper will do the right thing, but for some edge cases, a person might expect different results.
Recently I encountered someone's code along the lines of:
b = {
'b': "b" or []
}
When I do a print(b) I get {'b': 'b'}. It got me questioning when will b ever be []? Or is it saying b is both "b" and []?
But if that is the case:
a = (1 or 2)
print(a == 1)
print(a == 2)
Why does print(a == 1) results in True but print(a==2) results in False?
This leads me to a final question, is it possible for a variable of type int or float or string to hold multiple values at the same time? ie, a is both 1 and 2 provided that it is not a list or dictionary?
No, you can't assign multiple values to a single variable.
The expression x or y returns y if x is false, or x if not.
A string only evaluates false if it's empty. Your string "b" is not empty, so it will never be false. Thus there's no way for that expression "b" or [] to equal [], it will always be "b".
Not, it is not possible.
What you have done is assign to a the value of the expression (1 or 2); that is, the result of or-ing 1 and 2.
a will never be 2. (1 or 2) will always evaluate to 1 because python evaluates these logical expressions left-to-right.
If the left-most one is not False, empty list, None, etc then it will assign that value to a and stop reading. The interpreter only looks at the second value if the first one is "no good".
is it possible for a variable of type int or float or string to hold multiple values at the same time?
Maybe in Quantum Computing, but certainly not in normal programming.
You're misunderstanding what the posted syntax does. When you assign a value using that expression, it assigns the first "truthy" value it comes across in left-to-right order. Any remaining value candidates after that first truthy one are discarded/ignored.
As it stands, the example you gave is pretty redundant - non-empty strings are "truthy", and since it's a literal "b", the empty list never even gets considered. That code is fundamentally equivalent to:
b = {
'b': "b"
}
With respect to your code snippets, the ored expressions are evaluated when they are assigned:
Since x or y returns x if x evaluates to True, else returns y,
the values of b and a from the examples are:
b = {'b': 'b'}
a = 1
and that is, what the print function returns.
Concerning the final question: It is not possible that a is 1 and 2 at the same time, but you can create a new type, so that a equals 1 and 2 at the same time:
class multiple_values:
def __init__(self, data):
self.data = set(data)
def __eq__(self, value):
return value in self.data
a = multiple_values([1, 2])
A list of 'valid' values is given to initialise a, but a itself is not a list.
a == 1 as well as a == 2 evaluate to True, while e.g. a == 3 evaluates to False.
But please note, that the type definition for multiple_values would need to be expanded in order to be useful for more than just an equality test.
Also, you asked for an int, float or string to have multiple values. a is not an int - it only 'behaves' like one in this limited example.
I wish to find a way to achieve the following: With the likes of 5.0, return 5. With the likes of 5.1, which cannot equal any integer, return Error.
Currently I use int() together with an "if integer != float". However this has problems, for instance I won't be able to tell whether the inequality was caused by the likes of 5.1 or the likes of 1111111111111111.0(and even larger numbers).
Also this is extremely troublesome compared with a potential, simple, one-line command. So is there a command in Python that does this?
Float objects in Python have an is_integer() predicate.
def strict_int(x):
if x.is_integer():
return int(x)
raise ValueError
Note that int objects do not have this method. You'll get an attribute error if you try to call this on an int.
If you wanted some error value instead of an exception, you can use a one-liner like this
int(x) if x.is_integer() else 'Error'
Simply use math as suggested in this answer by #Anthony V like this:
>>> frac, whole = math.modf(5.0)
>>> if frac ==0.0:
... print("this is a whole")
... else:
... print("this is not whole and should return the Error")
This should work easily.
I'm not sure whether there's a more idiomatic way to do this, but intuitively, you can just compare the value of the int and the float and return only when they are equal.
That is
def weird_cast(my_float):
if int(my_float) == my_float:
return int(my_float)
return None # or some error
def return_int(a):
if int(a)==a:
print(int(a)) #you can store the integer value in separate variable #also b = int(a)
#instead of using print you can use return b or int(a)
else:
print('Error') #or you can use return 'Error'
a = 5.0
return_int(a)
Maybe another easier way is to minus with the round down number with itself.
if the remainder is more than 0.0 and less than 1.0, then we can call it a float otherwise integer
def IntegerSanityCheck ( num ):
remainder = abs ( round ( num ) - num )
if ( remainder > 0.0 ) and ( remainder < 1.0 ):
print "Float"
else:
print "Integer"
or you can use math as suggested by user2906838
This question already has an answer here:
"None" keeps showing up when I run my program
(1 answer)
Closed 9 years ago.
Why using print won´t work, and it does work using return?
I want to output the bigger number:
def bigger(x,y):
if x<y:
return y
return x
print bigger(2,7)
It prints out:
7
def bigger(x,y):
if x<y:
print y
print x
print bigger(2,7)
It prints out:
7
None
Why using print won´t work, and it does work using return?
It works. If a function doesn't have a return statement, the function returns a None. In second case you just print it.
Any particular reason you're not using Python's builtin max?
Functions implicitly return None if no explicit return value is specified. So, in your second example, you are printing the result of a function that doesn't return anything. While the function itself is already printing what the result is.
Your first version is the correct and what should be used version.
Here is a demo of what you are seeing in the first case:
>>> def f1(): return 7
...
>>> print f1()
7
Here is a demo of what you are seeing in the second case:
>>> def f2(): pass
...
>>> print f2()
None
And if you are looking to make the first function you have more concise, use this form:
>>> def bigger(x,y):
... return x if x>y else y
...
>>> print bigger(2,7)
7
Or just use the builin max (as stated in the comments) which has the advantage of returning the max of a sequence:
>>> max([1,2,3,4,5,6,7])
7
>>> max('abcdefg')
'g'
Or doing something like the max element of a data element, like the second integer of a tuple:
>>> max([(100,2),(50,7)], key=lambda x: x[1])
(50, 7)
In the first case you return the value from a function and then print it - so you have one output. In the second case you print the value inside the function and then you try to print an output from a function which doesn't return anything - so it prints the value first and then prints an empty return.
When I am executing this code in http://www.pyschools.com/quiz/view_question/s2-q1. It gives error for both the answers... Please help
The questions is:
Write a function to convert temperature from Celsius to Fahrenheit scale.
oC to oF Conversion: Multipy by 9, then divide by 5, then add 32.
Examples
>>> Cel2Fah(28.0)
'82.40'
>>> Cel2Fah(0.00)
'32.00'
My Answer
# Note: Return a string of 2 decimal places.
def Cel2Fah(temp):
x = 9.00
y = 5.00
z = 32.00
a = temp * x
a = a / y
a = a + z
return(a)
At the top it says:
# Note: Return a string of 2 decimal places.
You are not returning a string. You are returning a value of type float.
Since this looks like homework, I'll let you figure out how to fix this (hint: use the string formatting operator).
Return this instead.
return '%.2f' %a
change your return statement to read
return '%.2f' %a
There is nothing wrong syntactically with that code. It should work if you pass a number as parameter. It won't work if you pass anything but a number.
def Cel2Fah(temp):
cel=(round((((temp*9)/5) +32),2))
return '%.2f' %cel
print Cel2Fah(36.9)
print Cel2Fah(29.0)