Convert tuple to concatenating the digits by recursion - python

def untuplify(tpl):
if len(tpl) == 0:
return 0
n = 0
while n <= len(tpl) - 1 :
x += str(tpl[n])
n += 1
return x
Why am I getting this error UnboundLocalError: local variable 'x' referenced before assignment ??
untuplify((1, 2, 3, 4, 5))
Should give me 12345

You are getting that error because in the line x+=str(tpl[n]) your compiler don't know x

First, there is no recursion here, you never call untuplify from within itself.
Second, the error message is because of the line
x += str(tpl[n])
You've never used x before, and now you want to add to it. That doesn't work.
Place a
x = ''
before the loop?
There are vastly easier ways to do this, but I think you're doing this as an exercise and aren't interested in them.
Edit: also, are you sure it makes sense to return the number 0 if the tuple is empty? Isn't the function supposed to return a string?

Because you are not initializing x:
n, x = 0, ''

Related

I defined a function, but i didn't get any value while I call that function

def number(n):
x=[]
for i in range (1,n):
if i%2==0:
x=x+[i]
i=i+1
return(n)
In the above code, no error is showing while running, but no value returned
As already mentioned in the comments section, there are a few things to note:
A function needs to be called (in case it was not done), so in your case you have to call the function by number(10) for example.
Probably you wanted to return x instead of n.
i = i+1 is not needed since range() already returns an iterable, therefore it has to be removed
the code in front of return does not need to be inside parantheses
you must change your code :
def number(n):
x = []
for i in range(1, n):
if i % 2 == 0:
x = x + [i]
i = i + 1
return (x) #---> you must return x not n!
print(number(12))
output:
[2, 4, 6, 8, 10]
difference between return and print in python :
this

Beginner trying to debug an easy program

I'm a student and am just beginning to learn code. Right now I'm working with Python and have a program I think should work, but just returns some errors that I don't understand:
Traceback (most recent call last): File "C:\Program
Files\Notepad++\1913lab3.py", line 23, in print(most(odd,
[]))
File "C:\Program Files\Notepad++\1913lab3.py", line 9, in most N =
S[i] UnboundLocalError: local variable 'i' referenced before
assignment
I don't understand what the first error tells me, but the I think I understand the second one, but I don't understand why I'm getting it. I don't think i is a local variable as I defined it right away in the beginning. Here's the code:
t = 0
f = 0
i = 0
def odd(N):
return N % 2 != 0
def most(P, S):
N = S[i]
if P == True:
t += 1
else:
f += 1
i += 1
if i < len(S):
most(P, S)
else:
if t > f:
return 'True'
else:
return 'False'
print(most(odd, []))
print(most(odd, [0]))
print(most(odd, [1]))
print(most(odd, [1, 2]))
print(most(odd, [1, 2, 3]))
The assignment is to define a recursive function (most()). The function takes one function and one list as its arguments (P and S). I can't use loops or local variables. Here's a quote from the assignment:
"P is a function of one argument that returns either True or False,
and S is a list. The function most calls P on each element of S. It
must return True if P returns True more often than it returns False.
It must return False otherwise."
The 5 print commands are just 5 examples that I need to work for credit, but this program needs to work for all lists. If anyone can help me fix these errors, that'd be great. (Also, any general Python tips would be welcome.)
By default any variable that is modified within a function is assumed to be local to that function. So if you have i += 1, i must be defined within the function first. Or you have to declare i as a global first (global i) so that python knows it is refering to the i you have defined (first) outside the function. But beware with globals, they are often dangerous (as they make it hard to keep track what is going on) and should be avoided if possible.

Project Euler #4 with python. What;s wrong with my code?

I am trying to do project euler problem 4 using python. The problem statement goes like this:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
I wrote down a solution for it:
s=0
x=100
y=100
list=[]
z=x*y
def palindrome():
while z>=1:
s=s*10+z%10
z=z/10
if z==s:
list.append(z)
while x<=999:
while y<=999:
palindrome()
y=y+1
x=x+1
y=100
print list
It ended up giving an error along the lines of 'z referenced beyond assignment'.
I searched for a solution to this error before finally deciding to use the syntax 'global' to bypass this error.
s=0
x=100
y=100
list=[]
z=x*y
def palindrome():
global z
global s
global x
global y
global list
while z>=1:
s=s*10+z%10
z=z/10
if z==s:
list.append(z)
while x<=999:
while y<=999:
palindrome()
y=y+1
x=x+1
y=100
print list
Now it doesn't give an error, but it gives an empty list as output. I tried to debug the code by inserting print statements in between. The loops appear to work fine, as 'x' and 'y' print all the values they are supposed to. However, I get an empty list as an output to the print list command and 'z' does not apparently change values and is stuck at 100000 despite me using while loops to change the values of x and y.
I am at a loss on how to proceed from here.
The error you got was probably:
UnboundLocalError: local variable 'z' referenced before assignment
This means that z was not defined, at least not within the palindrome() function. Your solution of adding the global keyword is technically correct. However, as others have pointed out already, use of globals makes the code hard to follow.
It's not clear to me what palindrome() is supposed to do. Is it supposed to check if a number is a palindrome? Generate palindrome numbers? To fix this problem, you should think about structuring your code. There are many ways to do this, of course, and with time you will find your own style.
My advice, then, is to think about how you would solve this in general. If you don't know the solution, coding won't help you. Sometimes, when solving problems like this one, I write functions without declaring their bodies. You can do this top-down or bottom-up, both work. For example:
def is_palindrome(n):
""" Check if n is a palindrome number. """
pass
def multiples_of_3_digits():
""" Return all numbers that are the product of two 3-digit numbers ."""
pass
def main():
print max(n for n in multiples_of_3_digits() if is_palindrome(n))
This way you can focus on solving the problem, then on the actual coding. Maybe you will add helper functions or realize you can solve the problem in a more efficient way, but it's a start. Good luck!
min=100
max=999
max_palindrome = 0
for a in range(min,max + 1):
for b in range(a + 1, max + 1):
prod = a*b
if prod > max_palindrome and str(prod)==(str(prod)[::-1]):
max_palindrome = prod
print max_palindrome
Here we are only concerned with the maximum palindrome, and so we don’t spend any time storing other palindromes once they are known to be non-maximum. Also, the if statement first checks if the given product is larger than the maximum known palindrome before using the string cast and list slice to check whether or not the number is even a palindrome. This should speed up our code a bit since the greater than comparison will often fail, regardless of whether the product in question is a palindrome. When we run this, we get the following.
906609
Alternate Way:
I would discourage you to use the global variables because of the reasons pointed out by others. I would also like you to refer to Andre's approach as it will teach you to organize yourself. In this approach too I will be using 2 functions is_palindrome(num) [to check if the number is palindrome or not] and find_max_palindrome [to find the largest palindrome]
def is_palindrome(num):
reversed = 0
original = num
if num < 10:
return True
if num % 10 == 0:
return False
while num >= 1:
reversed = (reversed * 10) + (num % 10)
num = num/10
if original == reversed:
return True
else:
return False
def find_max_palindrome():
max_palindrome = 0
a = 999
b = 999
prod = 0
while a > 99:
b = 999
while b >= a:
prod = a*b
if prod > max_palindrome and is_palindrome(prod):
max_palindrome = prod
b = b -1
a = a - 1
return max_palindrome
print find_max_palindrome()

Variation of suffix array in python

I'm relatively new to computer science, and I'm learning how to code in python. I'm trying to figure out how to make a function that takes a list and returns a list of suffixes from the inputted list, in order from shortest length to longest length. For example, entering
[3,4,2,-9,7,6,1]
to the function would return
[[],[1],[6,1],[7,6,1],[-9,7,6,1],[2,-9,7,6,1],[4,2,-9,7,6,1],[3,4,2,-9,7,6,1]]
I've tried several approaches, but so far I'm not having much luck. Here is what I have so far:
def h(m):
newlist = []
x = 0
y = (len[m])-1
while x in range(y):
sublist = []
sublist = sublist + m[x:y]
newlist.append(sublist)
x += 1
return new list
When I try to run the function by entering something like
a = [3,4,2,-9,7,6,1]
h(a)
I get an error:
Traceback (most recent call last):
File "<pyshell#239>", line 1, in <module>
h(a)
File "<pyshell#238>", line 4, in h
y = (len[m])-1
TypeError: 'builtin_function_or_method' object has no attribute '__getitem__'
My objective with this bit of code was simply to create a the list of suffixes without sorting them by length. After I figure out how to create this new list I will add the sorting bit of the code. Keep in mind this is not a homework assignment. Any help would be greatly appreciated!
Possible solution is using list comprehension:
[l[i:] for i in range(len(l), -1, -1)]
This code uses slicing and list comprehension to simply return a list of slices from the end. Using your code, small modification is required - len is a function and not a dictionary, therefore you need to use the call operator () instead of subscript operator [].
y = len(m) - 1
That will not yield correct result though, because you will not get the last suffix and empty suffix. In order to cover these two, you will need to modify y or the loop to cover them
y = len(m) + 1
or better
while x in range(y + 1):
use parenthesis to get the length of the list:
y = len(m) - 1
Your error is in your len:
(len[m]) - 1
len is a function, and you can't index or slice or the what not. Do this instead:
y = len(m) - 1
There's also one other error:
return new list
Should be: (You can't have spaces in variables)
return newlist

recursive method returning original value

So I'm trying to learn python on my own, and am doing coding puzzles. I came across one that pretty much ask for the best position to stand in line to win a contest. The person running the contest gets rid of people standing in odd number positions.
So for example if 1, 2, 3, 4, 5
It would get rid of the odd positions leaving 2, 4
Would get rid of the remaining odd positions leaving 4 as the winner.
When I'm debugging the code seems to be working, but it's returning [1,2,3,4,5] instead of the expected [4]
Here is my code:
def findWinner(contestants):
if (len(contestants) != 1):
remainingContestants = []
for i, contestant in enumerate(contestants, 1):
if (isEven(i)):
remainingContestants.append(contestant)
findWinner(remainingContestants)
return contestants
Am I not seeing a logic error or is there something else that I'm not seeing?
You must return the value from the recurse function to the caller function:
return findWinner(remainingContestants)
else you would return just the original value without any changes.
def findWinner(contestants):
if (len(contestants) != 1):
remainingContestants = []
for i, contestant in enumerate(contestants, 1):
if (isEven(i)):
remainingContestants.append(contestant)
return findWinner(remainingContestants) # here the value must be return
return contestants # without the return above, it will just return this value(original)
How about this:
def findWinner(contestants):
return [contestants[2**int(math.log(len(contestants),2))-1]]
I know its not what the questions really about but I had to =P. I cant just look at all that work for finding the greatest power of 2 less than contestants and not point it out.
or if you don't like the 'artificial' solution and would like to actually perform the process:
def findWinner2(c):
while len(c) > 1:
c = [obj for index, obj in enumerate(c, 1) if index % 2 == 0] #or c = c[1::2] thanks desfido
return c
you shold use
return findWinner(remaingContestants)
otherwise, of course, your list will never be updated and so your func is gonna always return containts
however, see the PEP8 for style guide on python code: http://www.python.org/dev/peps/pep-0008/
the func isEven is probably an overkill...just write
if not num % 2
finally, recursion in python isn't recommended; make something like
def find_winner(alist):
while len(alist) > 1:
to_get_rid = []
for pos, obj in enumerate(alist, 1):
if pos % 2:
to_get_rid.append(obj)
alist = [x for x in alist if not (x in to_get_rid)]
return alist
Is there a reason you're iterating over the list instead of using a slice? Doesn't seem very python-y to not use them to me.
Additionally, you might want to do something sensible in the case of an empty list. You'll currently go into an infinite loop.
I'd write your function as
def findWinner(contestants):
if not contestants:
raise Exception
if len(contestants)==1:
return contestants[0]
return findWinner(contestants[1::2])
(much as #jon_darkstar's point, this is a bit tangential to the question you are explicitly asking, but still a good practice to engage in over what you're doing)
You are missing a return at the line where you call "findWinner"

Categories

Resources