Pig latin translator not working properly .Not showing output for vowel 'a'.
example: input: va
the output is an error showing reference error.
working properly for all other vowels except 'a'.
UnboundLocalError: local variable 'list3' referenced before assignment.
import string
def translate(str1):
str2="eaiouy"
list2=[]
punstr=""
for c in str1:
if c in string.punctuation:
punstr=punstr+c
for c in string.punctuation:
str1= str1.replace(c,"")
if str1.isdigit():
return str1+punstr
else:
if (len(str1)==1):
if str1[0] in str2:
return str1+"yay"+punstr
else:
return str1+"ay"+punstr
elif str1[0] in str2:
return str1+"yay"+punstr
else:
for i in str2:
list1=str1.split(i)
if (len(list1[0])<len(list2)):
list3=list1[0]
list2=list1[0]
prestr=str(list3)
stem=str1.split(list3)
reqstem=stem[1]
return reqstem+prestr+"ay"+punstr
while True:
str1=raw_input("\nenter the sentance")
sentlist=str1.split(" ")
for i in range(len(sentlist)):
mystr=sentlist[i]
if i==0:
reqstring=translate(mystr)
print reqstring.capitalize(),
else:
reqstring=translate(mystr)
print reqstring,
list3 is only assigned to when len(list1[0]<len(list2), which means sometimes it isn't set, and that's when prestr=str(list3) will give you trouble.
working now!!!
import string
def translate(str1):
vowel=" eaiouy"
list2=[]
punstr=""
for c in str1:
if c in string.punctuation:
punstr=punstr+c
for c in string.punctuation:
str1= str1.replace(c,"")
if str1.isdigit():
return str1+punstr
else:
if (len(str1)==1):
if str1[0] in vowel:
return str1+"yay"+punstr
else:
return str1+"ay"+punstr
elif str1[0] in vowel:
return str1+"yay"+punstr
else:
for i in str1:
if i in vowel:
list1=str1.split(i)
print list1
break
prestr=str(list1[0])
stem=str1.split(prestr)
reqstem=stem[1]
return reqstem+prestr+"ay"+punstr
while True:
str1=raw_input("\nenter the sentance")
sentlist=str1.split(" ")
for i in range(len(sentlist)):
mystr=sentlist[i]
if i==0:
reqstring=translate(mystr)
print reqstring.capitalize(),
else:
reqstring=translate(mystr)
print reqstring,
Related
I'm very new to python and I'm trying to make a hangman game. I currently have a line of code saying word = (random.choice(open("Level1py.txt").readline())).
I'm getting the error 'str' object does not support item assignment.
Here is the rest of my code (sorry for the mess):
import random
def checkLetter(letter, word, guess_word):
for c in word:
if c == letter:
guess_word[word.index(c)] = c
word[word.index(c)] = '*'
print(guess_word)
word = (random.choice(open("Level1py.txt").readline().split()))
guess_word = ['_' for x in word]
print(guess_word)
while '_' in guess_word:
guess = input('Letter: ')
print(checkLetter(guess, word, guess_word))
Strings are immutable in python. An easy workaround is to use lists, which are mutable:
st = "hello"
ls = list(st)
ls[3] = 'r'
st = ''.join(ls)
print(st)
Outputs
helro
Edit: here's how you would implement it in your own code
import random
def checkLetter(letter, word, guess_word):
for c in word:
if c == letter:
guess_word[word.index(c)] = c
word_list = list(word)
word_list[word.index(c)] = "*"
word = ''.join(word_list)
print(guess_word)
word = 'test'
guess_word = ['_' for x in word]
print(guess_word)
while '_' in guess_word:
guess = input('Letter: ')
print(checkLetter(guess, word, guess_word))
Note that there are still other issues that have nothing to do with this, like printing None and duplicate printing
You can also solve your problem using a dictionary:
word = "my string" #replace this with your random word
guess_word = {i: '_' for i in set(word)} # initially assign _ to all unique letters
guess_word[' '] = ' ' # exclude white space from the game
wrong_attempts = 0
while '_' in guess_word.values():
guess = input('Letter: ')
if guess in guess_word.keys():
guess_word[guess] = guess
else:
wrong_attempts += 1
if wrong_attempts > 11:
break
printable = [guess_word[i] for i in word]
print(' '.join(printable))
if '_' in guess_word.values():
print('you lost')
else:
print('congratulation, you won')
def anti_vowel(text):
p=''
for c in text:
if c=='a' or c=='A':
break
elif c=='e' or c=='E':
break
elif c=='i' or c=='I':
break
elif c=='o' or c=='O':
break
elif c=='u' or c=='U':
break
else:
p=p+c
print(anti_vowel('Hello you'))
You forgot to return p at the end of your function:
def anti_vowel(text):
p=''
for c in text:
if c=='a' or c=='A':
break
elif c=='e' or c=='E':
break
elif c=='i' or c=='I':
break
elif c=='o' or c=='O':
break
elif c=='u' or c=='U':
break
else:
p=p+c
return p
Without that last line all you'll ever print is None, the default return value for functions without an explicit return statement.
Of course, your function will only ever print the first consonants, as break ends the loop as soon as you find any vowels. It'll not reverse the string, ever. For your sample input, the function return 'H', because the next letter in the input is a vowel, and break then ends the loop.
You could easily re-write your function to use str.lower() and a containment test:
def anti_vowel(text):
p = ''
for c in text:
if c.lower() in 'aeiou':
break
p += c
return p
This does the same thing, return the first consonants ('H' for your sample input).
If you wanted to reverse letters, and exclude vowels, don't use break and invert where you place the remaining letters. You could use continue instead, or more simply, just invert the if test and only process a chararter if it is not a vowel:
def anti_vowel(text):
p = ''
for c in text:
if c.lower() not in 'aeiou':
p = c + p
return p
Now consonants are placed before any preceding consonants, reversing the text:
>>> def anti_vowel(text):
... p = ''
... for c in text:
... if c.lower() not in 'aeiou':
... p = c + p
... return p
...
>>> anti_vowel('Hello you')
'y llH'
Here is the standard pig latin code used in codeacademy. It works well but it's shortcoming is that it only works for one word at a time:
pyg = 'ay'
original = raw_input('Enter a word or phrase:')
if len(original) > 0 and original.isalpha():
word = original.lower()
translate = word[1:] + word[0]
if word[0] != "a" and word[0] != "e" and word[0] != "i" and word[0] != "o" and word[0] != "u":
new_word = translate + pyg
print new_word
else:
new_word = word + pyg
print new_word
else:
print 'Input is empty or illegal'
so I wanted to make it so that it could phrases. This is what I came up with:
pyg = 'ay'
count = 0
original_input = raw_input('Enter a word or phrase:')
original = original_input
original_list = []
#converts to a list
while " " in original:
if count > 50:
break
word = original[0:original.index(" ")]
original_list.append(word)
space = original.index(" ")
space += 1
original = original[space:]
count += 1
#this works great until there is a word left and no spaces i.e. the last word
if len(original) > 0:
original_list.append(original)
#this adds the last word
print original_list
def pyglatin(phrase):
#old code doesn't work because phrase is a list
#now I have to translate BACK to a string
for words in phrase:
new_word = str(words)
"""this works for one word, how do I assign a new variable for every word if I don't know the phrase length ahead of time"""
so that brings me to my question: How do I assign a variable for every item when I don't know how many items I'm going to need, and then be able to call that code back (through the old pyglatin translator)?
As Maxime mentioned, lists are useful in this instance, and the string can be converted to a list much easier. To account for phrases, I would rewrite the code as follows:
def trans_word(original):
if len(original) > 0 and original.isalpha():
word = original.lower()
translate = word[1:] + word[0]
if word[0] != "a" and word[0] != "e" and word[0] != "i" and word[0] != "o" and word[0] != "u":
new_word = translate + pyg
return new_word
else:
new_word = word + pyg
return new_word
else:
return "Input is empty or illegal"
def pyglatin(phrase):
if len(phrase) > 0:
return " ".join(trans_word(word) for word in phrase)
else:
return "Input is empty or illegal"
pyg = 'ay'
count = 0
original_input = raw_input('Enter a word or phrase:')
original_list = original_input.split()
print pyglatin(original_list)
Maybe something like this?
def latinize(word):
word = word.lower()
translate = word[1:] + word[0]
return (translate if word[0] in 'aeiou' else word) + 'ay'
original = raw_input('Enter a word or phrase:')
print ' '.join(latinize(word) for word in original.split())
Example input and output:
Enter a word or phrase:Gallia est omnis divisa in partes tres
galliaay steay mnisoay divisaay niay partesay tresay
But shouldn't you actually move all initial consonants to the end, and not only the first?
Edit:
If you want to move all initial consonants to the end, you can use:
def latinize(word):
word = word.lower()
firstvowel = min (word.index (v) if v in word else 42042 for v in 'aeiou')
if firstvowel == 42042: raise Exception ('No vowel in word')
return word [firstvowel:] + word [:firstvowel] + 'ay'
original = raw_input('Enter a word or phrase:')
print ' '.join(latinize (word) for word in original.split () )
Sample input and output:
Enter a word or phrase:star chick mess string
arstay ickchay essmay ingstray
SO i have this assignment to translate multiple words into pig latin. assume that the user will always input lowercase and only letters and spaces.
#----------------global variables
sentence = input("What do you want to translate into piglattin? ")
sentence = list(sentence)
sentence.insert(0, ' ')
length = len(sentence)
sentence.append(' ')
pigLattin = sentence
false = 0
true = 1
consonant = []
a = 0
b = 0
c = 0
d = 0
e = 0
f = 0
j = 0
x = 0
y = 0
#----------------main functions
def testSpace(sentence, i):
if sentence[i] == ' ':
a = true
else:
a = false
return a
def testVowel(sentence, i):
if sentence[i] == 'a' or sentence[i] == 'e' or sentence[i] == 'i' or sentence[i] == 'o' or sentence[i] == 'u' or sentence[i] == 'y':
b = true
else:
b = false
return b
def testStartWord(sentence, i):
x = 0
if sentence[i].isalpha() and sentence[i-1] == ' ':
c = true
x = 1
if x == 1 and sentence[i] != 'a' and sentence[i] != 'e' and sentence[i] != 'i' and sentence[i] != 'o' and sentence[i] != 'u' and sentence[i] != 'y':
c = true
else:
c = false
return c
def testWordEnd(sentence, i):
if sentence[i].isalpha() and sentence[i+1] == ' ':
d = true
else:
d = false
return d
#----------------main loop
for i in range(1,length):
x = 0
space = testSpace(sentence, i)
vowel = testVowel(sentence, i)
word = testStartWord(sentence, i)
end = testWordEnd(sentence, i)
if vowel == false and space == false and word == true:
e = i
consonant.append(sentence[i])
pigLattin.pop(e)
f = f + 1
if end == true:
consonant.append('a')
consonant.append('y')
consLength = len(consonant)
for x in range(consLength):
y = i + j - f
pigLattin.insert(y,consonant[x])
j = j + 1
del consonant[:]
pigLength = len(pigLattin)
for b in range (pigLength):
print(pigLattin[b], end='')
this is what i have so far. it gets kinda messy when trying to remove items. im sort of stuck here and its not working.
OK i got it working now this is an updated version
sentence = input("Please enter a sentence: ")
vowels = ("a", "e", "i", "o", "u", "A", "E", "I", "O", "U")
words = sentence.split()
count = 0
def find_vowel(word):
for i in range(len(word)):
if word[i] in vowels:
return i
return -1
for word in words:
vowel = find_vowel(word)
if(vowel == -1):
print(word, ' ', end='')
elif(vowel == 0):
print(word + "ay", ' ', end='')
else:
print(word[vowel:] + word[:vowel] + "ay", ' ', end='')
Instead of using testSpace eliminate the spaces by using sentence = sentence.split(). This will split all your words into strings in a list. Then iterate through the words in your list.
Instead of using testStartWord, use an if statement:
for word in sentence:
if word[0] in ["a","e","i","o","u"]:
word[:(len(word)-1)] = word[0]
#More Code...
At the end, where you print the output, use print sentence.join()
Here's an alternate version. I use a regular expression to find words in the input string, pass them to a callback function, and substitute them back into the original string. This allows me to preserve numbers, spacing and punctuation:
import re
import sys
# Python 2/3 compatibility shim
inp = input if sys.hexversion >= 0x3000000 else raw_input
VOWELS = set('aeiouyAEIOUY')
YS = set('yY')
def pig_word(word):
"""
Given a word, convert it to Pig Latin
"""
if hasattr(word, 'group'):
# pull the text out of a regex match object
word = word.group()
# find the first vowel and what it is
vowel, where = None, None
for i,ch in enumerate(word):
if ch in VOWELS:
vowel, where = ch, i
break
if vowel is None:
# No vowels found
return word
elif where == 0 and vowel not in YS:
# Starts with a vowel - end in 'way'
# (leading y is treated as a consonant)
return word + 'way'
else:
# Starts with consonants - move to end and follow with 'ay'
# check capitalization
uppercase = word.isupper() and len(word) > 1
titlecase = word[:1].isupper() and not uppercase
# rearrange word
word = word[where:] + word[:where] + 'ay'
# repair capitalization
if uppercase:
word = word.upper()
elif titlecase:
# don't use str.title() because it screws up words with apostrophes
word = word[:1].upper() + word[1:].lower()
return word
def pig_latin(s, reg=re.compile('[a-z\']+', re.IGNORECASE)):
"""
Translate a sentence into Pig Latin
"""
# find each word in the sentence, pass it to pig_word, and insert the result back into the string
return reg.sub(pig_word, s)
def main():
while True:
s = inp('Enter a sentence to translate (or Enter to quit): ')
if s.strip():
print(pig_latin(s))
print('')
else:
break
if __name__=="__main__":
main()
then
Enter a sentence to translate (or Enter to quit):
>>> Hey, this is really COOL! Let's try it 3 or 4 times...
Eyhay, isthay isway eallyray OOLCAY! Et'slay ytray itway 3 orway 4 imestay...
def rotate_word(word,number)
for i in word:
word_num = ord(i)
new_word += chr(word_num + number)
return new_word
Hi guys, the code above is not working. This is a python function. When i run the program i will return an error: "UnboundLocalError: 'new_word' referenced before assignment"
what this means? Can anyone help me?
the output of my function would be:
print rotate_word('abc',5)
output: fgh
You should define new_word before using it. Place this before the for:
new_word = ''
You are also missing an indentation for the return and a colon after the def. Here is a fixed version:
def rotate_word(word, number):
new_word = ''
for i in word:
word_num = ord(i)
new_char = chr(word_num + number)
if new_char > 'z':
new_char = chr(ord(new_char) - 26)
new_word += new_char
return new_word
print rotate_word('abc', 5)
print rotate_word('xyz', 3)
EDIT: I've updated your code so it wraps after 'z'