Just 5 days into Python, learning through Code Academy. I have no knowledge of any other language (very little knowledge of Ruby!).
What am I doing wrong with this code?
Q: Write a function, by_three, that calls a second function, cube,
if a number is evenly divisible by 3 and "False" otherwise. You should
then return the result you get from cube. As for cube, that function
should return the cube of the number passed from by_three. (Cubing a
number is the same as raising it to the third power).
So, for example, by_three should take 9, determine it's evenly
divisible by 3, and pass it to cube, who returns 729 (the result of
9**3). If by_three gets 4, however, it should return False and leave
it at that.
Lastly, call by_three on 11, 12, and 13 on three separate lines.
ANS:
def by_three(n):
orig_num = n
if (isinstance(orig_num, int) and orig_num%3 == 0 ):
cube(orig_num)
else:
print "False"
def cube(orig_num):
cube = orig_num**3
print cube
return
by_three(11)
by_three(12)
by_three(13)
When I run the above code, here is what I get. Why do these values appear in this way?
False
1728
False
==> None
False
False
1728
Oops, try again.
I can't say why you're seeing odd results. When I copy your code into the interpreter, I see:
>>> def by_three(n):
... orig_num = n
... if (isinstance(orig_num, int) and orig_num%3 == 0 ):
... cube(orig_num)
... else:
... print "False"
...
>>> def cube(orig_num):
... cube = orig_num**3
... print cube
... return
...
>>> by_three(11)
False
>>> by_three(12)
1728
>>> by_three(13)
False
I think this problem is a lot simpler than you're making it, though. It's hard to tell because the question is rather poorly written, but this would be my answer:
def by_three(n): return False if n % 3 else cube(n)
def cube(n): return n**3
by_three(11)
by_three(12)
by_three(13)
And this is what it looks like in the interpreter:
>>> def by_three(n): return False if n % 3 else cube(n)
...
>>> def cube(n): return n**3
...
>>> by_three(11)
False
>>> by_three(12)
1728
>>> by_three(13)
False
First you need to change the cube function to actually return the cube. And you can even simplify your cube method, by just returning the cube without storing the temporary result: -
def cube(orig_num):
return orig_num**3 # Just return the cube
Then in your by_three function, rather than printing "False", you should return it. Also, return the value returned by cube function: -
def by_three(n):
if (isinstance(n, int) and n % 3 == 0):
return cube(n) # Added return here
else:
return False #Changed print to return.
You can also simplify this method to just a single line return statement. You should use try-except block instead of checking instance with isinstance, if you are passing a value in your function: -
def by_three(n):
try:
return cube(n) if n % 3 == 0 else False
except TypeError, e:
return False
And then, when you invoke the method, print the result obtained: -
print by_three(11)
print by_three(12)
print by_three(13)
In your cube method, you're not actually returning anything. Unlike Ruby, which returns the last statement in the block, you have to explicitly state what you're returning. There's also no need to create defensive copies of the value. Furthermore, you can't reuse the name cube, or that will clobber your method definition.
def cube(orig_num):
return orig_num ** 3
Next, you would have to return the values in your caller method. I'll leave that as an exercise for you - shouldn't be too tricky to figure out from here.
Third, you (sort of) don't need to worry if the number is an int or a float. While there is imprecision with floating point numbers, the values shouldn't be perfectly divisible by 3.
Related
I recently started learning python through Sololearn and got to Recursion. To get better understanding of the code, I simplified it to:
def is_even(x):
return x
def is_odd(x):
return not is_even(x)
print(is_odd(2))
The return not is_even(x) is boolean and will resulted it as False and when it passed to the def is_even(x): it still would return as False.
However, when I change the return x to print(x)
def is_even(x):
print (x)
def is_odd(x):
return not is_even(x)
print(is_odd(2))
The result would be:
2
True
How did this happen? What is going on between the return not is_even(x) and print (x).
Thank you
Maybe this will get you on track:
def returning(x):
return x
def printing(x):
print(x)
returning(2)
# 2
printing(2)
# 2
a = returning(2)
a
# 2
b = printing(2)
2
b
# None
The difference is that return returns a value from a function which can be used to pass to another function / variable. print just prints out the information but does not return any value, this is why b holds no value, but during the assigment b = printing(2) it immediately printed out what was passed to it, when a = returning(2) did not, it assigned the value to variable a.
And None is falsly in python.
None == False
# False
None == True
# False
not None == True
# True
What you are lacking is for is_even to return a bool instead of the argument passed:
def is_even(x):
return x % 2 == 0
def is_odd(x):
return not is_even(x)
is_odd(3)
# True
Your code does not have any recursion!
the function is_even() returns anything you pass to it like an integer,a character or anything else.
the function is_odd() returns a boolean;But notice the equivalent boolean value for non boolean values.
For example values like 1, 'Example', [1,2,3] and ... have True boolean value and values like 0,[], None and ... have False boolean value.
So if you pass something like "test" or 5 to is_odd(), it will return False
So i'm creating a little experimental python program and I'm using a little tidbit of code (shown below) to determine if a number is whole or has decimal places.
def isWhole(x):
if(x%1 == 0):
return "1"
else:
return "2"
My problem is that no matter where I go I can't find a way to just take the returned value and assign it to a variable...
Sorry if I seem like an absolute spurglord noob for asking this question but I never even knew that functions could "return" until about 2 days ago, so yeah...
like this:
def isWhole(x):
if(x%1 == 0):
return "1"
else:
return "2"
my_var = isWhole(4)
The return value will always be 1.
def isWhole(x):
if x % 1 == 0:
return "1"
else:
return "2"
if __name__ == "__main__":
k = isWhole(4)
print(k)
Answering your question, how to assign a variable, just assign it to the output of the function as below:
var = isWhole(4) #Put any number in instead of 4
As long as you have a return in your function, you can assign a variable to the output:
>>> def foo():
... return "bar"
...
>>> var = foo()
>>> var
"bar"
>>>
However if you do not have a return, then it returns None, so beware :)
>>> def bar():
... print "foo"
...
>>> var = bar()
foo
>>> var
None
>>>
As others have explained, you can just assign the result of calling the function to a variable name to save the value. Perhaps equally important though, is the fact that the code shown in your function will always return "1" since the value of x%1 is always going to be 0 regardless of the value of x (assuming its value is non-zero and a type with a modulo operator).
I would suggest that tou instead implement your function to return a True or False value and do it like the following:
def is_whole(x):
return float(x).is_integer()
(See the is_integer documentation for more information.)
You can assign the result of calling this function to a variable as shown below:
result1 = is_whole(21./7.) # assign function return value to a variable
result2 = is_whole(22./7.) # assign function return value to another variable
print(result1) # --> True
print(result2) # --> False
I have some functions doing math stuff which needs to take integer agrmuents.
I know that I can force using int by using condition isinstance(x, int)
or more strict type(x) == int, but IMO it isn't pythonic.
I think my Python code shouldn't reject 2.0 just because it's float.
What's the best way to check if value is logically integer?
By logically integer I mean value of any type, which represents integer.
It should be able to be used in arithmetic operations like int, but I don't have to check it,
because I belive that in Python any set of conditions can get fooled.
For example,
True, -2, 2.0, Decimal(2), Fraction(4, 2) are logically integers,
when '2' and 2.5 are not.
At the moment I use int(x) == x, but I'm not sure if it's the best solution.
I know I can use float(x).is_integer().
I also saw x % 1 == 0.
Normally one would check against the Integral ABC (Abstract Base Class), but floating point values are not normally meant to be treated as integers no matter their value. If you want that, take note of their is_integer property:
(1324.34).is_integer()
#>>> False
(1324.00).is_integer()
#>>> True
and the code is then just:
from numbers import Integral
def is_sort_of_integer(value):
if isinstance(value, Integral):
return True
try:
return value.is_integer()
except AttributeError:
return False
If you also want to deal with Decimals, Fractions and so on, which don't have an is_integer method, the best option would probably be just:
from numbers import Number, Integral
def is_sort_of_integer(value):
if isinstance(value, Integral):
return True
if isinstance(value, Number):
try:
return not value % 1
except TypeError:
return False
return False
The Integral check shouldn't be needed in this case, but it's probably best to keep it.
One way to solve this is by using a metaclass to define your custom implementation of __instancecheck__, then define a concrete class having the metaclass, and use isinstance with your concrete class.
This has the downside of pulling in metaclass machinery, which is often extraneous.
But it has the upside of cleanly encapsulating whatever properties you desire to use for what you mean by "logically integer" for your application.
Here's some code to show this approach:
class Integral(type):
def __instancecheck__(self, other):
try:
cond1 = int(other) == other
cond2 = (other >= 1.0) or (other < 1.0)
# ... plus whatever other properties you want to check
return all([cond1, cond2,])
except:
return False
class IntLike:
__metaclass__ = Integral
print isinstance(-1, IntLike)
print isinstance('1', IntLike)
print isinstance(27.2, IntLike)
print isinstance(27.0, IntLike)
print isinstance(fractions.Decimal(2), IntLike)
print isinstance(fractions.Fraction(4, 2), IntLike)
It prints:
True
False
False
True
True
True
Note that it is important to get rid of the idea that the mathematical concept of being logically integer should apply to your program. Unless you bring in some proof-checking machinery, you won't get that. For example, you mention properties like certain functions being available, and specifically sqrt -- but this won't be available for negative integers unless you implement custom behavior to check for complex results.
It will be application-specific. For example, someone else might pick up this code and modify it so that '1' does register as IntLike, and perhaps for the sake of their application it will be correct.
This is why I like the metaclass approach here. It lets you explicitly denote each condition that you are imposing, and store them in one location. Then using the regular isinstance machinery makes it very clear to code readers what you are trying to do.
Lastly, note that no given conditions will always be perfect. For example, the class below could be used to 'fool' the int(x) == x trick:
class MyInt(object):
def __init__(self, value):
self.value = value
def __int__(self):
return int(self.value)
def __add__(self, other):
return self.value + other
#... define all needed int operators
def __eq__(self, other):
if isinstance(other, float):
raise TypeError('How dare you compare me to a float!')
return self.value == other
# ..etc
Then you get behavior like this:
In [90]: mi = MyInt(3)
In [91]: mi + 4
Out[91]: 7
In [92]: mi == 3
Out[92]: True
In [93]: int(mi) == mi
Out[93]: True
In [94]: mi == 3.0
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-93-827bea4a197f> in <module>()
----> 1 mi == 3.0
<ipython-input-89-66fec92fab7d> in __eq__(self, other)
13 def __eq__(self, other):
14 if isinstance(other, float):
---> 15 raise TypeError('How dare you compare me to a float!')
16 return self.value == other
17
TypeError: How dare you compare me to a float!
and whether or not isinstance(mi, IntLike) returns True will be totally dependent on how you have implemented the comparison operators for MyInt and also whatever extra checks you have made in Integral's __instancecheck__.
There are some cases, which none of int(x) == x, x.isinteger() & x % 1 == 0 can handle the way I would like to.
Example:
>>> big_float = 9999999999999999.1
The big_float is big enough to ignore substracting some small number from it (AFAIK, it's called underflow):
>>> big_float -1 == big_float
True
Then
>>> def fib(n):
... current, prev = 1, 0
... while n > 0:
... current, prev, n = current+prev, current, n-1
... return prev
...
>>> fib(big_float) #unwanted infinite loop
There are some cases, which none of int(x) == x, x.isinteger() & x % 1 == 0 can handle the way I would like to.
>>> int(big_float) == big_float
True
>>> big_float.is_integer()
True
>>> big_float % 1 == 0
True
Solution
We can check if big_float in the same way as int(big_float):
>>> int(big_float) -1 == big_float -1
False
Of course, this method works also for more trivial cases, like this:
>>> x = 2.1
>>> int(x) -1 == x -1
False
Of course, you don't have to substract 1, you can use whatever mathematical operation you need.
Note that this condition may throw exception:
>>> x = '2'
>>> int(x) -1 == x -1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'str' and 'int'
Simple, try to convert it to an integer. If int() works, it is "logically an integer", otherwise it is not.
try:
int(thing)
is_integer = True
except ValueError:
is_integer = False
But, typically, rather than do it like this you would just use int(thing) in the code you needed this for, and just catch the error if it ends up not being an integer and handle that case appropriately.
I'm learning python and I was just wondering if I there was a way to write a code that does something like:
def f(x):
if x>1:
return(x)
else:
# don't return anything
I'm asking about the else part of the code. I need to not return anything if x<=1, returning None isn't acceptable.
There is no such thing as "returning nothing" in Python. Every function returns some value (unless it raises an exception). If no explicit return statement is used, Python treats it as returning None.
So, you need to think about what is most appropriate for your function. Either you should return None (or some other sentinel value) and add appropriate logic to your calling code to detect this, or you should raise an exception (which the calling code can catch, if it wants to).
To literally return 'nothing' use pass, which basically returns the value None if put in a function(Functions must return a value, so why not 'nothing'). You can do this explicitly and return None yourself though.
So either:
if x>1:
return(x)
else:
pass
or
if x>1:
return(x)
else:
return None
will do the trick.
There's nothing like returning nothing but what you are trying to do can be done by using an empty return statement. It returns a None.
You can see an example below:
if 'account' in command:
account()
def account():
talkToMe('We need to verify your identity for this. Please cooperate.')
talkToMe('May I know your account number please?')
acc_number = myCommand()
talkToMe('you said your account number is '+acc_number+'. Is it right?')
confirmation = myCommand()
if confirmation!='yes' or 'correct' or 'yeah':
talkToMe('Let\'s try again!')
account()
else:
talkToMe('please wait!')
return
This will return nothing to calling function but will stop the execution and reach to the calling function.
How about this?
def function(x):
try:
x = x+1
return (x)
except:
return ('')
You can do something like this:
>>> def f(x):
... return x if x>1 else None
...
>>> f(1),f(2)
(None, 2)
It will appear to 'return nothing':
>>> f(1)
>>>
But even the alternative returns None:
>>> def f2(x):
... if x>1: return x
...
>>> f2(1),f2(2)
(None, 2)
Or:
>>> def f2(x):
... if x>1:
... return x
... else:
... pass
...
>>> f2(1),f2(2)
(None, 2)
So they are functionally the same no matter how you write it.
As mentioned above by others, it will always return None in your case. However you can replace it with white space if you don't want to return None type
def test(x):
if x >1:
return(x)
else:
return print('')
To get a blank result from return statement just type return "" . You will just a get a blank line in the end without anything printed on it
def f(x):
if x>1:
return(x)
else:
return ""
You can use lambda function with filter to return a list of values that pass if condition.
Example:
myList = [1,20,5,50,6,7,2,100]
result = list(filter(lambda a: a if a<10 else None, (item for item in myList)))
print(result)
Output:
[1,5,6,7,2]
I may have a tip for you !
Writing print(f(x)) will output None if there is no return value, but if you just call your function without the 'print', and instead write in the function some 'print(s)' you won't have a None value
you can use
return chr(0)
cause 0 in ASCII doesn't have a character hence it leaves it blank
Just to add to all the answers, the only actual way to not return a function is to raise an exception. At least, as long as the program needs to run even after not returning anything.
So your code can be:
def f(x):
if x>1:
return x
raise Exception
(Note that I didn't use an else block to raise the Exception since it would have already returned the value if the condition was satisfied. You could, however, do this in an else block, too)
On test running:
num1 = f(2) # 2
num2 = f(0) # Unbound; and error raised
Now this can be useful if you want to also keep returning None an option for some conditions, and not returning anything for some other conditions:
def f(x):
if x > 0:
return x
elif x == 0:
return None # pass
raise Exception
>>> num1 = f(1) # 1
>>> num2 = f(0) # None
>>> num3 = f(-1) # Unbound; and error raised
If you don't want the program to exit and show an error, you can make it catch the exception outside of the function:
try:
num = f(0)
except:
pass
This way, if at all f(0) raises an exception (which it would) it will be caught be the except block and you can happily continue the program, being rest assured that num is not None, but simply unbound.
An interesting fact:
The only other way to not return anything is probably to simply exit the program, which is what exit() and quit() do. When I check the return type for exit() and quit() in my code editor, it shows me NoReturn, which is different from when it shows None for a regular function :)
In Simple Terms
for i in range(0,10):
if i<5:
None
else:
print("greater")
Output:-
greater
greater
greater
greater
greater
The code outputs nothing for all values less than 5.
This question already has answers here:
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 7 years ago.
In python I don't seem to be understanding the return function. Why use it when I could just print it?
def maximum(x, y):
if x > y:
print(x)
elif x == y:
print('The numbers are equal')
else:
print(y)
maximum(2, 3)
This code gives me 3. But using return it does the same exact thing.
def maximum(x, y):
if x > y:
return x
elif x == y:
return 'The numbers are equal'
else:
return y
print(maximum(2, 3))
So what's the difference between the two? Sorry for the mega noob question!
The Point
return is not a function. It is a control flow construct (like if else constructs). It is what lets you "take data with you between function calls".
Break down
print: gives the value to the user as an output string. print(3) would give a string '3' to the screen for the user to view. The program would lose the value.
return: gives the value to the program. Callers of the function then have the actual data and data type (bool, int, etc...) return 3 would have the value 3 put in place of where the function was called.
Example Time
def ret():
return 3
def pri():
print(3)
4 + ret() # ret() is replaced with the number 3 when the function ret returns
# >>> 7
4 + pri() # pri() prints 3 and implicitly returns None which can't be added
# >>> 3
# >>> TypeError cannot add int and NoneType
What would you do if you need to save printed value? Have a look at good explanation in docs and cf.:
>>> def ret():
return 42
>>> def pri():
print(42)
>>> answer = pri()
42
>>> print(answer) # pri implicitly return None since it doesn't have return statement
None
>>> answer = ret()
>>> answer
42
It also is no different from return statement in any other language.
For more complex calculations, you need to return intermediate values. For instance:
print minimum(3, maximum(4, 6))
You can't have maximum printing its result in that case.
Remember that the interactive command line isn't the only place methods will be called from. Methods can also be called by other methods, and in that case print isn't a usable way to pass data between them
Honestly, it depends on what you need the function to do. If the function specification state that it will print out max term, then what you have is fine. What generally happens for a method like this is that the method should return the actual value which is larger. In the case they are equal, it doesn't matter which value is returned.