Python NameError: name 'isAnagram' is not defined - python

I want to print whether a number is an anagram or not from the user input. I get an error saying nameError.
And this is my code for checking an input for an anagram.
n = input("Enter a long number")
factor = 2
factor_anagram = False
while factor < 10:
if isAnagram(n, factor):
print(n, "is an anagram with factor", factor)
factor_anagram = True
factor += 1
if not factor_anagram:
print("No")
Do I need to create a class? I tried creating an isAnagram class as well. But my implementation did not solve the issue.

You are trying to use isAnagram(n, factor) as a built in function like print("xyz"). isAnagram() is not a built in function, so you will have to define it at the top of your code. It can look like this:
def isAnagram(n, factor):
if (whatever comparison needs to be made here):
return True
else:
return False
Now when you call the isAnagram function, either True or False will be returned.

isAnagram does not exist in the default Python library - you have to define it yourself. From the way you're attempting to use it, you want to create a function
def is_anagram(n, factor):
# Your code here
# return True or False
You can then do something like if is_anagram(n, factor):.

Related

Calculating a factorial using loops in Python3

I am currently studying Software Development as a beginner and I have a task in my programming class to calculate and display a factorial using a loop. I've been given the pseudo-code and have to translate it into true code and test it in the REPL to make sure it returns the expected results.
I almost have it but I've run into two issues that I just can't seem to resolve.
1) The function is returning an extra line of "None" after the calculation and
2) The answer is displaying over multiple lines when I want it to display on a single line.
My current code (which does return the correct answer) is as follows:
def calcFactorial(number):
factorial = 1
print(str(number)+"! =", number)
for count in range (1, number):
if number-count > 0:
factorial = factorial*number-count
print("x", str(number-count))
factorial = factorial*number
print("=", factorial)
When I test, using 3 for example, the REPL returns the following:
>>> print(calcFactorial(3))
3! = 3
x 2
x 1
= 12
None
So I have the correct answer but with an extra line of "None" which I would like to remove (I believe it has something to do with the print function?) and I don't know how to format it correctly.
Any help would be much appreciated.
your function calcFactorial(3) prints already, so you shouldn't call it with
print(calcFactorial(3))
just call it with
calcFactorial(3)
without the print function.
you might think about calling the function calc_and_print_factorial() in order to make it clear, that this function does already the printing
Regarding your second question:
Blockquote
2) The answer is displaying over multiple lines when I want it to display on a single line.
You can fix it by using a single print statement:
def calcFactorial(number):
factorial = 1
string = str(number) + "! = " + str(number)
for count in range (1, number):
if number-count > 0:
factorial = factorial*(number-count)
string = string + " x " + str(number-count)
factorial = factorial * number
print(string + " = " + str(factorial))
This will give you:
IN: calcFactorial(3)
OUT: 3! = 3 x 2 x 1 = 6
On a side note: you might want to think of how to implement this recursively. Maybe that comes later in your class but this would be one of the first go-to examples for it.
Adding to the blhsing's answer, you should choose between these built-in ways to print the "returned" value.
First way:
def calcFactorial(number):
... # <- Your function content
return factorial
Then, call your function with a print() to get the explicitly returned value, as you can see in the return factorial line. See this reference for more details:
print(calcFactorial(3))
Second way:
Having the same function definition with its return statement, just call the function with its instance statement:
calcFactorial(8)
By default, python will print the returned value without a print()
Third way:
Just call the function (without the explicit return statement, this will return a "None" (null-like) value by default), using the print() method. Do NOT use print() inside another print().
Your calcFactorial function does not explicitly return a value, so it would return None by default, so print(calcFactorial(3)) would always print None.
You should make the calcFactorial function return factorial as a result at the end:
def calcFactorial(number):
factorial = 1
print(str(number)+"! =", number)
for count in range (1, number):
if number-count > 0:
factorial = factorial*number-count
print("x", str(number-count))
factorial = factorial*number
print("=", factorial)
return factorial
So I have the correct answer but with an extra line of "None" which I would like to remove
You are printing the return value from your function. In this case, you haven't specified a return value with a return statement so the function automatically returns None.
To fix the problem, you should return a value from your function. Note that you don't need to call print() for final answer because the REPL already does this for you.
Note that the REPL will automatically print the return value for you, so you can just type calcFactorial(3) instead of print(calcFactorial(3)).
Additionally, you are not getting the correct answer. You should get 6 instead of 12. It looks like you are trying to count down from number and multiplying each number together. You can get the same result by counting up from 1. This will lead to much simpler code and avoid the error.
If you want to understand why your code isn't doing the correct thing, look closely at factorial = factorial*number-count and think about the order of operations that are used to calculate the result here.

Finding multiples using recursion

Given 1 to 100 numbers, for multiples of 3 it should print "he" ,for multiples of 5 it should print "llo" ,for both multiples of 3 and 5 it should print "hello".
This is what I have:
for i in range (1,100):
if(i%3==0):
print("he")
elif(i%5==0):
print("llo")
elif(i%3==0 and i%5==0):
print("hello")
How would I do this recursively?
How about the code below?
def find_multiples(current, last_num=100):
# Base Case
if current > last_num:
return
result = ""
if current % 3 == 0:
result += "he"
if current % 5 == 0:
result += "llo"
if result:
print(f"{current}: {result}")
find_multiples(current+1, last_num)
find_multiples(1)
Base case is if current reaches last_num or the maximum number you'd like to check.
Here is a general outline for doing simple recursive things in python:
BASE_CASE = 1 #TODO
def f(current_case):
if current_case == BASE_CASE:
return #TODO: program logic here
new_case = current_case - 2 #TODO: program logic here ("decrement" the current_case somehow)
#TODO: even more program logic here
return f(new_case) + 1 #TODO: program logic here
Of course, this doesn't handle all possible recursive programs. However, it fits your case, and many others. You would call f(100), 100 would be current_value, you check to see if you've gotten to the bottom yet, and if so, return the appropriate value up the call stack. If not, you create a new case, which, in your case, is the "decrement" logic normally handled by the "loop" construct. You then do things for the current case, and then call the function again on the new case. This repeated function calling is what makes it "recursive". If you don't have an "if then" at the beginning of the function to handle the base case, and somewhere in the function recall the function on a "smaller" value, you're probably going to have a bad time with recursion.
This recursive function prints multiples of a number! hope it helps
def multi(n,x):
if x == 12:
print(n*x)
else :
print(n*x,end =",")
multi(n,x+1)
print(multi(4,1));

Python: Why does return not actually return anything that I can see

I have the following code:
def is_prime(n):
limit = (n**0.5) + 1
q = 2
p = 1
while p != 0 and q < limit:
p = n % q
q = q + 1
if p == 0 and n != 2:
return 'false'
else:
return 'true'
But when I send in an integer, there is nothing returned. The console simply moves on to a new command line. What's wrong here?
EDIT 1:
The following are screenshots of different scenarios. I would like to make it such that I call the function with a particular number and the function will return 'true' or 'false' depending on the primality of the number sent into the function. I guess I don't really understand the return function very well.
Also, note that when I send in to test 9, it returns true, despite 9 being quite definitely a composite number...should the if/else bits be outside the while loop?
Key to below image:
1: this is the code as it is above and how I call it in the Spyder console
2: adding a print statement outside the function
3: this is a simple factorial function offered by the professor
image here
EDIT 2:
I made a quick change to the structure of the code. I don't really understand why this made it work, but putting the if/else statements outside the while loop made things result in expected true/false outputs
def is_prime(n):
limit = (n**0.5)+1
q=2
p=1
while p!=0 and q<limit:
p = n%q
q = q+1
if p==0 and n!=2:
return 'false'
else:
return 'true'
Also, I call the function in the console using is_prime(int_of_choice)
Thanks for the helpful suggestions
If you want to print something to the console you have to use a print statement. The return keyword means that you can use this value in a piece of code that calls this function. So to print something:
print (x)
For more information about the print statement see: https://en.wikibooks.org/wiki/Python_Programming/Variables_and_Strings
Nothing is wrong, but you have to print out the return of your function.
Like this:
def Test():
if True:
return "Hi"
print(Test())
In this case python will show "Hi" in your console.

Python: base case of a recursive function

Currently I'm experimenting a little bit with recursive functions in Python. I've read some things on the internet about them and I also built some simple functioning recursive functions myself. Although, I'm still not sure how to use the base case.
I know that a well-designed recursive function satisfies the following rules:
There is a base case.
The recursive steps work towards the base case.
The solutions of the subproblems provide a solution for the original problem.
Now I want to come down to the question that I have: Is it allowed to make up a base case from multiple statements?
In other words is the base case of the following self written script, valid?
def checkstring(n, string):
if len(string) == 1:
if string == n:
return 1
else:
return 0
if string[-1:] == n:
return 1 + checkstring(n, string[0:len(string) - 1])
else:
return checkstring(n, string[0:len(string) - 1])
print(checkstring('l', 'hello'))
Yes, of course it is: the only requirement on the base case is that it does not call the function recursively. Apart from that it can do anything it wants.
That is absolutely fine and valid function. Just remember that for any scenario that you can call a recursion function from, there should be a base case reachable by recursion flow.
For example, take a look at the following (stupid) recursive function:
def f(n):
if n == 0:
return True
return f(n - 2)
This function will never reach its base case (n == 0) if it was called for odd number, like 5. You want to avoid scenarios like that and think about all possible base cases the function can get to (in the example above, that would be 0 and 1). So you would do something like
def f(n):
if n == 0:
return True
if n == 1:
return False
if n < 0:
return f(-n)
return f(n - 2)
Now, that is correct function (with several ifs that checks if number is even).
Also note that your function will be quite slow. The reason for it is that Python string slices are slow and work for O(n) where n is length of sliced string. Thus, it is recommended to try non-recursive solution so that you can not re-slice string each time.
Also note that sometimes the function do not have strictly base case. For example, consider following brute-force function that prints all existing combinations of 4 digits:
def brute_force(a, current_digit):
if current_digit == 4:
# This means that we already chosen all 4 digits and
# we can just print the result
print a
else:
# Try to put each digit on the current_digit place and launch
# recursively
for i in range(10):
a[current_digit] = i
brute_force(a, current_digit + 1)
a = [0] * 4
brute_force(a, 0)
Here, because function does not return anything but just considers different options, we do not have a base case.
In simple terms Yes, as long as it does not require the need to call the function recursively to arrive at the base case. Everything else is allowed.

Python-Recursion-New To Programming

I need to Check that every number in numberList is positive and implement the below
function using recursion. I'm stuck. Just learning recursion and I'm completely lost as I am very new to programming. Help!
def isEveryNumberPositiveIn(numberList):
foundCounterexampleYet = False
for number in numberList:
if(number <= 0):
foundCounterexampleYet = True
return not(foundCounterexampleYet)
Your function is not recursive because it never calls itself; a recursive version would look like
def all_positive(lst):
if lst:
return lst[0] > 0 and all_positive(lst[1:])
# ^
# this is the recursive bit -
# the function calls itself
else:
return True
# this keeps the function from looping forever -
# when it runs out of list items, it stops calling itself
This is a bad example to choose for a recursive function because (a) there is a simple non-recursive solution and (b) passing it a large list (ie over 1000 items) will overflow the call stack and crash your program. Instead, try:
def all_positive(lst):
return all(i > 0 for i in lst)
Your indentation is incorrect, but your thinking is correct, though the algorithm is not recursive. You could make it a bit more efficient though, by jumping out of the loop when a negative number is detected:
def isEveryNumberPositiveIn(numberList):
foundCounterexampleYet = False
for number in numberList:
if number <= 0:
foundCounterexampleYet = True
break
return not foundCounterexampleYet
then for example:
a = [1,-2,3,4,45]
print(isEveryNumberPositiveIn(a))
returns False
By the way, those parentheses forif and not are unnecessary.
With this sort of recursive problem, here is how you should think about it:
There should be a "basis case", which answers the question trivially.
There should be a part that does something that brings you closer to a solution.
In this case, the "basis case" will be an empty list. If the list is empty, then return True.
The part that brings you closer to a solution: shorten the list. Once the list get shortened all the way to a zero-length (empty) list, you have reached the basis case.
In pseudocode:
define function all_positive(lst)
# basis case
if lst is zero-length:
return True
if the first item in the list is not positive:
return False
# the actual recursive call
return all_positive(lst[with_first_value_removed]
Try to convert the above pseudocode into Python code and get it working. When you are ready to peek at my answer, it's below.
def all_positive(lst):
"""
Recursive function to find out if all members of lst are positive.
Because it is recursive, it must only be used with short lists.
"""
# basis case
if len(lst) == 0:
return True
if lst[0] <= 0:
return False
# recursive call
return all_positive(lst[1:])
There's several ways you can write this. One way would be to use lst.pop() to remove one element from the list. You could combine that with the if statement and it would be kind of elegant. Then the list would already be shortened and you could just do the recursive call with the list.
if lst.pop() <= 0:
return False
return all_positive(lst)
There is one problem though: this destroys the list! Unless the caller knows that it destroys the list, and the caller makes a copy of the list, this is destructive. It's just plain dangerous. It's safer to do it the way I wrote it above, where you use "list slicing" to make a copy of the list that leaves off the first item.
Usually in a language like Python, we want the safer program, so we make copies of things rather than destructively changing them ("mutating" them, as we say).
Here's one more version of all_positive() that makes a single copy of the list and then destroys that copy as it works. It relies on a helper function; the helper is destructive. We don't expect the user to call the helper function directly so it has a name that starts with an underscore.
def _all_positive_helper(lst):
"""
Recursive function that returns True if all values in a list are positive.
Don't call this directly as it destroys its argument; call all_positive() instead.
"""
if len(lst) == 0:
return True
if lst.pop() <= 0:
return False
return _all_positive_helper(lst)
def all_positive(lst):
"""
Return True if all members of lst are positive; False otherwise.
"""
# use "list slicing" to make a copy of the list
lst_copy = lst[:]
# the copy will be destroyed by the helper but we don't care!
return _all_positive_helper(lst_copy)
It's actually possible in Python to use a default argument to implement the above all in one function.
def all_positive(lst, _lst_copy=None):
"""
Return True if all members of lst are positive; False otherwise.
"""
if _lst_copy is None:
return all_positive(lst, lst[:])
if len(_lst_copy) == 0:
return True
if _lst_copy.pop() <= 0:
return False
return all_positive(lst, _lst_copy)
Recursion doesn't really help you with this. A better use for recursion would be, for example, visiting every node in a binary tree.

Categories

Resources