local variable 'z' referenced before assignment - python-3.x

I've had a look around at older posts on this topic but can't see how to apply the knowledge to my code,
I'm trying to turn two functions into 1 as they are very similar but while trying to execute the function I get a:local variable 'z' referenced before assignmenterror,
and here is the code:
code_a = ['h','e','l','o']
code_b = ['d','t','u','x']
def encrypt(word, a):
if a == 'encrypt':
z = code_a
y = code_b
elif a == 'decrypt':
z = code_b
y = code_a
newword = ''
for char in word:
x = 0
found = False
while found == False:
if z[x] == char:
newword = newword + y[x]
found = True
x += 1
return newword
x = encrypt('hello', 'encrypt')
print(x)
any help would be greatly appreciated thanks in advance
EDIT: After messing around with my code I figured out that the problem was the uncertainty of z and 'y' so I got rid of the elif statement and swapped the values in the if statement and added an else statement to make the default what the original if statement was.

Related

Need to stop the code if conditional works and start again if it fails. Where did I go wrong?

The condition is simple. If sum<=20 then print sum or else loop the starting from the input. However, this is looping even if the input is valid. How should I fix this? My code is in the picture
code in the picture
You need to specify that you wish to update the global variable.
invalid_input = True
def start():
x = int(input("number1: "))
y = int(input("number2: "))
z = int(input("number3: "))
sum = x + y + z
if (sum <= 20):
global invalid_input
invalid_input = False
print(sum)
else:
print("return and give valid input")
while invalid_input:
start()
Alternatively, you could return a boolean from the function.
def start():
x = int(input("number1: "))
y = int(input("number2: "))
z = int(input("number3: "))
sum = x + y + z
if (sum <= 20):
print(sum)
return True
else:
print("return and give valid input")
while True:
if start(): break
Related post: python-function-global-variables

solve n which is an integer above 0 in python

This code works but it is not very efficient is there any help on a faster code in python to find n knowing that n is an integer above 0 and that n has no upper bound, how(x) will return you 1 if x>n, 0 if x = n, and -1 if x
def how(x):
if x > n:
return 1
elif x < n:
return -1
else:
return 0
def find(how):
if how(1) == 1:
return 1
x = 2
while how(x) != 1:
x = x**x
v = x
while how(x) != 0:
if how(x) == 1:
v = x
x = (x+1)//2
else:
x += (v-x+1)//2
return x
Rebecca, I've added some print statements so you can see where goes what wrong. As Patrick Artner said... its a bit confusing which way to go so I've tried to clean-up some things that enable you to continue exploring comparison of two variables against each other (and fake error catching (0).
Lets start and remove the confusing lingo and produce something workable code. With current below script it runs and with value = 1, reference = 1 you get the below print result in a continues loop until YOU stop the script manually:
v1 = n: error
loop1 1
def selector(v1, n):
if v1 > n:
print 'v1 > n', v1, n
return 1
elif v1 < n:
print 'v1 < n', v1, n
return -1
else:
print 'v1 == n: error'
return 0
def find(value, reference):
if selector(value, reference) == 1:
return 1
while selector(value, reference) != 1:
x = value**value
print 'loop1', x
v = x
while selector(value, reference) != 0:
print 'loop2'
if selector(value, reference) == 1:
v = value
x = (value+1)/2
print 'loop2-if', v, x
else:
x += (v-(value+1))/2
print 'loop2-else', x
print ' Almost done...'
return x
if __name__ == '__main__':
n = 1
print find(1, 1)
Happy exploring,....

Python2 increment string in an alphanumeric format

I'm looking for a snippet which does stuff like :
from 'abcd8' string
i want to increment it like 'abcd9' then 'abcda' ... >'abcdz' and next 'abce0', 'abce1' ... 'abcez', 'abcf0' ....
Can't find a way to do it :(
I already tried stuff like using 'aaaa'.encode('hex') then increment it, but not working :(
Thanks for help,
Cheers !
Here is a way of doing it:
# written by 'imerso' to a StackOverflow answer
def increment(os):
s = list(os)
p = len(os)-1
while (p >= 0):
s[p] = chr(ord(s[p]) + 1)
if s[p] > 'z':
s[p] = '0'
p -= 1
continue
if s[p] > '9' and s[p] < 'a':
s[p] = 'a'
return ''.join(s)
s = raw_input("String: " )
for x in range(1, 32):
s = increment(s)
print s

Unable to solve this issue with the code

I am having some issues with this question for which i have tried to make 2 solutions.The first one works partially but the second one does not.Here is the question
Question with which i am having the issue.Has sample input and output
Here are the 2 codes which i have written
number=int(input())
S=input()
w=list(S[:])
w_count=0
other_count=0
v_count=0
vv_count=0
i=0
while(i<(len(w))):
try:
if w[i]=='w':
w_count+=1
elif w[i]=='v' and w[i+1]=='v':
vv_count+=1
i+=1
else:
other_count+=1
except IndexError:
pass
i+=1
max_length=w_count*2+other_count+v_count
min_length=0
min_length=w_count+other_count+vv_count
print(min_length,max_length)
The other Logic has been implemented with the help of a for loop for which 3 test cases are passing
for value in range(len(w)):
try:
if w[value]=='w':
w_count+=1
elif w[value]=='v' and w[value+1]=='v':
vv_count+=1
else:
other_count+=1
except IndexError:
pass
If think you can keep it simple with:
my_string = "avwvb"
max_len = len(my_string.replace("w", "vv"))
min_len = len(my_string.replace("w", "vv").replace("vv", "w"))
print(max_len, min_len)
Or a little faster:
my_string = "avwvb"
max_string = my_string.replace("w", "vv")
min_string = max_string.replace("vv", "w")
max_len = len(max_string)
min_len = len(min_string)
print(max_len, min_len)
You can try this. It's similar to your for loop solution but uses string indexing a bit better.
For the first problem I'm just expanding the string as much as possible changing all ws into 2 vs.
The second is a bit trickier. I first expand the string using the previous method, and then build a new string where any vv combinations can be turned into w. I use 2 indexes, i for the longer string and j for the shorter version of the string, in order to avoid index errors.
def longer(s):
for i in range(0,len(s)):
x = s[i]
if x == 'w':
new_str = s[:i] + 'v' + s[i+1:]
if (i + 1 >= len(s)):
new_str = new_str + 'v'
else:
new_str = new_str[:i] + 'v' + new_str[i:]
s = new_str
return s
def shorter(s):
long_str = longer(s)
short_str = long_str[0]
j = 1
for i in range(1,len(long_str)):
x = long_str[i]
if x == 'v' and short_str[j-1] == 'v':
short_str = short_str[:j-1] + 'w'
j = j -1
else:
short_str = short_str + x
j = j +1
return short_str
print len(longer("avwvb"))
print len(shorter("avwvb"))

Python: TypeError: 'int' object is not iterable

I'm tackling this following question:
Write a function is_fib(n) that returns True if n is a Fibonacci number, and False otherwise.
This is my code:
def is_fib(n):
def fib(x):
if x == 0:
return 0
elif x == 1:
return 1
else:
return fib(x-1) + fib(x-2)
for a in n:
if fib(a) == n:
result = True
break
else:
result = False
return result
Running this give rise to:
TypeError: 'int' object is not iterable.
I have been staring at the code for half an hour. Any help is greatly appreciated.
I think you mean
for a in range(n)
not
for a in n
As jozefg said you are missing range(n)
also notice that you need range(n+2) to cover all cases
def is_fib(n):
def fib(x):
if x == 0:
return 0
elif x == 1:
return 1
else:
return fib(x-1) + fib(x-2)
for a in range(n+2):
if fib(a) == n:
return True
return False
print(is_fib(3))
Firstly thanks to the two guys that helped me.
However, for Yoav's edition, python will run into an error when n is a really big number.
This is my new and improved version.
def is_fib(n):
if n < 0:
return False
else:
fib_0 = 0
fib_1 = 1
if n == fib_0 or n == fib_1:
return True
else:
for a in range(2,n+2):
fib = fib_0 + fib_1
fib_0,fib_1 = fib_1,fib
if fib >= n:
break
return fib == n

Resources