I'm trying to solve a problem that can be found in the Book The Coder's Apprentice by Pieter Spronck, in section 13.2.4. This is the code I wrote so far:
english_dutch = {"last":"laatst", "week":"week", "the":"de", "royal":"koninklijk",
"festival":"feast", "hall":"hal", "saw":"zaag", "first":"eerst", "performance":"optreden",
"of":"van", "a":"een", "new":"nieuw", "symphony":"symphonie", "by":"bij",
"one":"een", "world":"wereld", "leading":"leidend", "modern":"modern",
"composer":"componist", "composers:componisten" "two":"twee", "shed":"schuur", "sheds":"schuren"}
text = "Last week The Royal Festival Hall saw the first \
performance of a new symphony by one of the world's leading \
modern composers, Arthur 'Two-Sheds' Jackson."
def clean(t):
t = t.lower()
t = t.split()
new_t = ""
for word in t:
new_word = ""
for letter in word:
if "a" <= letter <= "z":
new_word += letter
if letter == "-":
new_word += " "
else:
continue
new_t += new_word + " "
return new_t
def translate(t):
translation = ""
for word in t.split():
if english_dutch.get(word):
translation += english_dutch[word] + " "
else:
translation += word + " "
return translation
def auto_correct():
news = ""
a = translate(clean(text)).split()
for word in a:
if len(word) > 1:
news += word + " "
print(news)
auto_correct()
It seems to work OK, but when I run it, the words "composers" and "two" are not translated.
You forgot a comma between the word composers and the word two. In addiotion you wrote "composers:componisten" instead of "composers":"componisten". Change your dictionary like so
english_dutch = {"last":"laatst", "week":"week",
"the":"de", "royal":"koninklijk",
"festival":"feast", "hall":"hal",
"saw":"zaag", "first":"eerst",
"performance":"optreden",
"of":"van", "a":"een",
"new":"nieuw", "symphony":"symphonie",
"by":"bij",
"one":"een", "world":"wereld",
"leading":"leidend", "modern":"modern",
"composer":"componist",
"composers":"componisten", "two":"twee", # <- HERE
"shed":"schuur", "sheds":"schuren"}
Why it passed undetected? Check this:
>>> {"composers:componisten" "two":"twee"}
{'composers:componistentwo': 'twee'}
Because the comma was missing and the colon was within the string, python concatenated the strings, creating a useless (but valid) key/value pair.
This behaviour is documented here
Multiple adjacent string literals (delimited by whitespace), possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. Thus, "hello" 'world' is equivalent to "helloworld".
Related
I need to remove all excess white space and leave one space, between my words while only using if and while statements. and then state the amount of characters that have been removed and the new sentence
edit, it must also work for punctuation included within the sentence.
This is what I have come up with however it leaves me with only the first letter of the sentence i choose as both the number, and the final sentence. can anyone Help.
def cleanupstring(S):
lasti = ""
result = ""
for i in S:
if lasti == " " and i == " ":
i = ""
else:
lasti = i
result += i
return result
sentence = input("Enter a string: ")
outputList = cleanupstring(sentence)
print("A total of", outputList[1], "characters have been removed from your string.")
print("The new string is:", outputList[0])
Your code should be something like this:
def cleanupstring(S):
counter = 0
lasti = ""
result = ""
for i in S:
if lasti == " " and i == " ":
i = ""
counter += 1
else:
lasti = i
result += i
return result, counter
sentence = input("Enter a string: ")
outputList = cleanupstring(sentence)
print("A total of", outputList[1], "characters have been removed from your string.")
print("The new string is:", outputList[0])
The counter keeps track of how often you remove a character and your [0] and [1] work now the way you want them to.
This is because outputList is now a tuple, the first value at index 0 is now the result and the second value at index 1 is the counter.
As of now it takes the punctuation out, but I cannot figure out how to make it add a space instead of just taking out the punctuation.
Currently I have:
punctuation = "!\"#$%&()*+,-./:;<=>?#[\\]^_`{|}~"
def remove_punct(theStr):
theStr_sans_punct = ""
for letter in theStr:
if letter not in punctuation:
theStr_sans_punct = theStr_sans_punct + letter
return theStr_sans_punct
It's in a interactive textbook so it will automatically do the tests on their site.
By adding an else to your code:
punctuation = "!\"#$%&()*+,-./:;<=>?#[\\]^_`{|}~"
def remove_punct(theStr):
theStr_sans_punct = ""
for letter in theStr:
if letter not in punctuation:
theStr_sans_punct = theStr_sans_punct + letter
else:
theStr_sans_punct = theStr_sans_punct + " "
return theStr_sans_punct
Is there another to have exception for capitalizing an entire sentence. I've heard of skipList method, but it didn't work for my code. See below:
string = input('Enter a string: ')
i = 0
tempString = ' '.join(s[0].upper() + s[1:] for s in string.split(' '))
result = ""
for word in tempString.split():
if i == 0:
result = result + word + " "
elif (len(word) <= 2):
result = result + word.lower() + " "
elif (word == "And" or word == "The" or word == "Not"):
result = result + word.lower() + " "
else:
result = result + word + " "
i = i + 1
print ("\n")
print (result)
Sure. Write a complete list of words that should not be title-cased ("and", "the", "or", "not", etc), and title-case everything else.
words = s.split(' ')
result = ' '.join([words[0]] + [w.title() for w in words[1:] if w not in skipwords])
of course this will still miss Mr. Not's last name, which should be capitalized, and some stranger things like "McFinnigan" will be wrong, but language is hard. If you want better than that, you'll probably have to look into NTLK.
You could rewrite this like this
skip_words = {w.capitalize(): w for w in 'a in of or to and for the'.split()}
words = string.title().split()
result = ' '.join(skip_words.get(w, w) for w in words).capitalize()
I'm trying to do a Caesar Cipher and I've come pretty close. The problem is my output only prints out a single letter, not the whole line ciphered line. E is the most frequently used letter in English so the idea is to find the distance between E and the most frequently used letter in the input. And then shift everything over by that distance. I'm new at python, so I'm not very good yet. Thanks so much in advance! Here's the code I have so far:
maximum_character = unciphered_text[0]
maximum_count = unciphered_text.count(unciphered_text[0])
for char in unciphered_text:
if char is not " ":
if unciphered_text.count(char) > maximum_count:
maximum_character = char
print("The most frequent character used is: ", maximum_character)
ASCII_maximum = maximum_character.lower()
ASCII_number = ord(ASCII_maximum)
print(ASCII_number)
shift_distance = ord('e')-ASCII_number
print("The shift distance is: ", shift_distance)
def caesar_cipher(unciphered_text, shift_distance):
ciphered_text = ""
for char in unciphered_text:
cipher_process = ord(char)+shift_distance
post_translation = chr(cipher_process)
ciphered_text += post_translation
return ciphered_text
answer = caesar_cipher(unciphered_text, shift_distance)
print(answer)
You misindent return statement in caesar_cipher function.
Move your return statement out from loop:
def caesar_cipher(unciphered_text, shift_distance):
ciphered_text = ""
for char in unciphered_text:
cipher_process = ord(char)+shift_distance
post_translation = chr(cipher_process)
ciphered_text += post_translation
return ciphered_text
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