Local variable 'list' referenced before assignment - python

I made a simple script that converts any input text into a "code" and can also translate it back. It only works one word at a time.
I want to make the script adds each new code to a list that is printed every time. For example, the first time you translate something, "HELLO" becomes "lohleci". The second time, I want it not only to show "world" = "ldwropx", but also state below everything translated so far.
I'm new to Python and have looked through forums for people with similar problems. The way I tried doing it (a segment was removed and put into a separate script), I get an error saying "local variable 'list' referenced before assignment." This is the code producing the error:
list = "none"
def list():
word = raw_input("")
if list == "none":
list = word + " "
print list
list()
else:
new_list = list + word + " "
list = new_list
print list
list()
list()

Your code has several problems, all of which are fixable with a bit more knowledge.
Don't use the name list for your own variables or functions. It's the name of a built-in Python function, and if you use that name for your own functions you won't be able to call the built-in function. (At least, not without resorting to advanced tricks which you shouldn't be trying to learn yet.)
You're also re-using the same name (list) for two different things, a variable and a function. Don't do that; give them different, meaningful names which reflect what they are. E.g., wordlist for the variable that contains a list of words, and get_words() for your function.
Instead of using a variable named list where you accumulate a set of strings, but which isn't actually a Python list, why not use a real Python list? They're designed for exactly what you want to do.
You use Python lists like this:
wordlist = []
# To add words at the end of the list:
wordlist.append("hello")
# To print the list in format ["word", "word 2", "word 3"]:
print wordlist
# To put a single space between each item of the list, then print it:
print " ".join(wordlist)
# To put a comma-and-space between each item of the list, then print it:
print ", ".join(wordlist)
Don't worry too much about the join() function, and why the separator (the string that goes between the list items) comes before the join(), just yet. That gets into classes, instances, and methods, which you'll learn later. For now, focus on using lists properly.
Also, if you use lists properly, you'll have no need for that if list == "none" check you're doing, because you can append() to an empty list just as well as to a list with contents. So your code would become:
Example A
wordlist = []
def translate_this(word):
# Define this however you like
return word
def get_words():
word = raw_input("")
translated_word = translate_this(word)
wordlist.append(translated_word)
print " ".join(wordlist)
# Or: print ", ".join(wordlist)
get_words()
get_words()
Now there's one more change I'd suggest making. Instead of calling your function at the end every time, use a while loop. The condition of the while loop can be anything you like; in particular, if you make the condition to be the Python value True, then the loop will never exit and keep on looping forever, like so:
Example B
wordlist = []
def translate_this(word):
# Define this however you like
return word
def get_words():
while True:
word = raw_input("")
translated_word = translate_this(word)
wordlist.append(translated_word)
print " ".join(wordlist)
# Or: print ", ".join(wordlist)
get_words()
Finally, if you want to get out of a loop (any loop, not just an infinite loop) early, you can use the break statement:
Example C
wordlist = []
def translate_this(word):
# Define this however you like
return word
def get_words():
while True:
word = raw_input("")
if word == "quit":
break
translated_word = translate_this(word)
wordlist.append(translated_word)
print " ".join(wordlist)
# Or: print ", ".join(wordlist)
get_words()
That should solve most of your problems so far. If you have any questions about how any of this code works, let me know.

Related

Best alternative to using if statement?

I am trying to break out of a bad habit of using if/else too frequently. I am new to how functions work and the proper way to call them but I am constantly researching the correct way to implement them with my code. The code that I am making is suppose to check for 3 different words and if the word is not in the input then the user will receive a statement that says "rejected" if the word is correct it will say "accepted". The issue that I am facing is getting my program to work correctly. So far I have set up my program to check each index of the word and if it matches the full word it will be marked as accepted. I am trying to figure out the correct way to add a rejected flag and to avoid the error that I recieve after running this program.
def checker():
q0 = input("enter word:")
if (q0[0]) +(q0[1]) == "if":
print ("accepted")
if (q0[0]) + (q0[1]) + (q0[2]) + q0[3] == "else":
print("accepted")
if(q0[0]) + (q0[1]) == "do":
print("accepted")
else:
print("rejected")
checker()
For this program, I am not going to use a dictionary so I can correctly challenge myself and implement this in an automata fashion. How can I implement this code without getting the string index out of range error. I tried to put break after my print statement but it doesn't work.
Thanks in advance to everyone. This is my first post so if I have made any mistakes in my post please let me know!
Here's an extensible one-liner for you:
def check():
q = input().strip()
acceptable = {'if', 'else', 'do'}
print('accepted' if q in acceptable else 'rejected')
The variable acceptable is set; a data structure which is very quick to check if something is inside of it. You can modify this set (or pass it to check as an argument!) to change the range of acceptable words without changing the control flow of the program (as you would in your original if/else implementation that you're laudably trying to move away from).
EDIT: I guess it's not strictly a 'one-liner'...
First, why do you access each character of the input string, then concatenate them again, then compare to a target string("if", "else", "do")?
Second, why do you use if statements repeatedly if matching either one of them will lead to the same result (print("accepted")?
Try this:
def checker():
q0 = input("enter word:")
if q0 in ["if", "else", "do"]:
print("accepted")
else:
print("rejected")
checker()
Now, you just compare a string q0 to another (each element of the list ["if", "else", "do"]). Also, the first hit in the list will make stop comparing anymore and will continue on to print "accepted".
++ Just to let you know why are you seeing "index out of range error", you are accessing each character of q0 without knowing how many there are. So if the user inputs a string like a, there's no q0[1] or q0[2], but you're asking your program to access it. Thus index out of range error.
You can do this with a for loop and one if statement if that is better for you. Simply put all the accepted values into a list and check if each word is in q0.
def checker():
q0 = input('enter word:')
for i in ['if', 'else', 'do']:
result = ('accepted' if i in q0 else 'rejected')
if result == 'accepted':
break
print(result)
you can do it as one liner with lambda function.
checker = lambda q: print("accepted" if q in ["elif", "if", "else"] else "rejected")
checker()
here is a sample
>>> checker = lambda q: print("accepted" if q in ["elif", "if", "else"] else
"rejected")
>>> checker("if")
accepted
>>> checker("fool")
rejected

How to create a censor "translator" via function in python

I'm trying to create a "translator" of sorts, in which if the raw_input has any curses (pre-determined, I list maybe 6 test ones), the function will output a string with the curse as ****.
This is my code below:
def censor(sequence):
curse = ('badword1', 'badword2', 'badword3', 'badword4', 'badword5', 'badword6')
nsequence = sequence.split()
aword = ''
bsequence = []
for x in range(0, len(nsequence)):
if nsequence[x] != curse:
bsequence.append(nsequence[x])
else:
bsequence.append('*' * (len(x)))
latest = ''.join(bsequence)
return bsequence
if __name__ == "__main__":
print(censor(raw_input("Your sentence here: ")))
A simple approach is to simply use Python's native string method: str.replace
def censor(string):
curses = ('badword1', 'badword2', 'badword3', 'badword4', 'badword5', 'badword6')
for curse in curses:
string = string.replace(curse, '*' * len(curse))
return string
To improve efficiency, you could try to compile the list of curses into a regular expression and then do a single replacement operation.
Python Documentation
First, there's no need to iterate over element indices here. Python allows you to iterate over the elements themselves, which is ideal for this case.
Second, you are checking whether each of those words in the given sentence is equal to the entire tuple of potential bad words. You want to check whether each word is in that tuple (a set would be better).
Third, you are mixing up indices and elements when you do len(x) - that assumes that x is the word itself, but it is actually the index, as you use elsewhere.
Fourth, you are joining the sequence within the loop, and on the empty string. You should join it on a space, and only after you've checked each element.
def censor(sequence):
curse = {'badword1', 'badword2', 'badword3', 'badword4', 'badword5', 'badword6'}
nsequence = sequence.split()
bsequence = []
for x in nsequence:
if x not in curse:
bsequence.append(x)
else:
bsequence.append('*' * (len(x)))
return ' '.join(bsequence)

How to check whether a value is in a list

I'm running in to a problem with my code. What needs to happen is:
Program asks what your movie channel name is,
Program asks what the code is that you received,
Program checks whether the code you received matches the movie channel you specified,
Program returns a print statement based on the result. If the code was found, print "Match", otherwise print "not found"
The code I have so far is:
def code_controle():
moviechannel = input("What is the name of your movie channel?")
code = input("What is the code you want to check?")
list = [
["RTL8", "20:30", "Rush", "John", "Smith", "123"],
["Veronica", "15:00", "V for Vendetta", "Jane", "Smith" , "ABC"]
]
Now what I need to do is match the moviechannel with a code.
Basically, if I put in "RTL8" and the code "123" it should look through all the lists starting with RTL8, then check the code I put in, with the code in the list. If this matches each other, print "match".
A simple solution is to iterate over the main list and check if the movie and code both exist in any sublist.
Python allows for checking values in a list using in. It is simply if 'value' in list
Writing a method as the one below could be useful if you want to call it often.
for sublist in list:
if movie in sublist and code in sublist:
return True
return False
Edit:
The above code will return true even if the movie and code values are interchanged. If the code is an unique identifier it should be fine, as no movie title would match it.
Since the list is generated by reading from an .csv file, and we are assured that the movie will always be the first item and the code the sixth, we can use the below code for exactly matching only those values.
for sublist in list:
if (movie == sublist[0]) and (code == sublist[5]):
return True
return False
I would wrap that in a try/except to catch any Index out of range just to be safe.
You could tackle that using python dictionaries, but to continue with your example:
found=0
for x in list: #note, change this, list is a type def
if x[0]==code and x[-1]==channel:
found+=1
print "Match"
if (found==0):
print "No match"
I'm assuming this is what you mean:
for line in list:
if moviechannel in line and code in line:
print('Match')
return
print('not found')
Btw you really should reconsider renaming your list, since that is also a built in function.
try this:
>>> my_list = set([moviechannel] + [code])
>>> for x in list:
... if len(set(x) & my_list) == 2:
... print "Match"
...
Match
This is an other way to do it:
new_list = c_list[0] + c_list[1]
if code in new_list and moviechannel in new_list:
print 'Match'
else:
print 'Not found'
You should not use list as list is a built-in function so I changed it to c_list.

Find a value within a list in that list's definition Python

Say I have the list
main = ["Hello", "World"]
Is it possible, at all, within definition, to refer to first item of list. By that I mean something like this
main = ["Hello", main[0] + " World!"]
so that main[1] would return Hello World!? The current syntax does not work and was wondering why this is and is there a working alternative/fix?
I apologize if this is a stupid question, im still kinda new to python but thank you in advance
You can't because when the [...] list definition is run, the object doesn't yet exist, nor is it assigned to any name yet.
You'll have to use a second line; you can always alter elements once the list is created and bound:
main = ["Hello", "World"]
main[1] = main[0] + main[1]
or append new elements:
main = ["Hello"]
main.append(main[0] + "World")

How to sort a string of email addresses to a list

I want to sort a string that contains email addresses to a list of email addresses.
The code gets stuck and nothing happens.
unsorted = "sge#grg.lt ggrge#yahoo.com"
def sort_thatstring():
s = ""
out = []
for x in unsorted:
s = ""
while x != " ":
s+=str(x)
else:
out.append(s)
sort_thatstring()
print out
I would like to get:
out = ["sge#grg.lt", "ggrge#yahoo.com"]
You can do:
sorted_list = sorted(unsorted.split(), key=lambda x: x.split('#')[1])
print(sorted_list)
#['sge#grg.lt', 'ggrge#yahoo.com']
Your code has two issues:
You reset s every time you loop in the for loop causing you to loose the data you have read.
The while statement also constructs a loop, but you are using it like an if. Try replacing while with if and read up on the difference between conditionals and loop constructors.
Your function also needs to return the out array otherwise it will be destroyed as soon as your function reaches the end.

Categories

Resources