I was studying Python on this website www.codacademy.com and I'm stuck on exercise PygLatin in part 4 of 12.
"Write an if statement that checks to see if the string is not empty.
If the string is not empty, print the user's word.
Otherwise (else), print "empty" if the string is empty.
Make sure you thoroughly test your code. You'll want to make sure you run it multiple times and test both an empty string and a string with characters. When you are confident that your code works, continue on to the next exercise."
I have to print the user's input word if he does so, if not, print "empty".
original = raw_input("Welcome to the English to Pig Latin translator! Type in the word you wish to use.")
if len(original) > 0:
return raw_input
else:
return "empty"
print original
But it's not working, I need help.
What am I doing wrong? The error claims it's on line 2 (if len(original) > 0:) but I haven't figured out what's wrong.
Wrong indentation is the main problem. Also, you have return statements but don't have a function. Plus, you can simplify the check if original is empty:
original = raw_input("Welcome to the English to Pig Latin translator! Type in the word you wish to use.")
if original:
print original
else:
print "empty"
or, in one line:
print original if original else "empty"
or:
print original or "empty"
You have two main problems: indentation and return without a function.
If you want to use a function, you could define a function that receive a string parameter, checks if it's empty, and then returns the corresponding string.
For example:
def checkstring(string):
if len(string) > 0:
return string
else:
return "empty"
original = "Welcome to the English to Pig Latin translator! Type in the word you wish to use."
print checkstring(original)
You can't indent arbitrarily in Python. The four lines beginning with the if statement are indented one level further than the first statement: that's not allowed. You can only indent after a statement that introduces a new block, as you have done after if and else. Bring those four lines back a level so that they start at the left-hand side.
I got the code from "Quine"but I edited more so you can actually put the input. Works better if you ask me for the purpose of this exercise:
print "Welcome to the English to Pig Latin translator!"
def checkstring(original):
if len(original) > 0:
return original
else:
return "empty"
original = raw_input("What is your name?")
print checkstring(original)
print 'Welcome to the Pig Latin Translator!'
# Start coding here!
raw_input ("What is your name")
variable_name = raw_input ()
original = raw_input()
if len (original) > 0:
print "the user's word"
else:
print "empty"
Related
To do:
Convert python to ythonpay (i.e. pick up a first letter, put it in the end and add 'ay' and make sure the user has not entered in the word numbers or alphanumeric word )
def check(word):
if word.isalnum() or word.isdigit():
print ("Enter valid word!")
else:
print ("Thank You for Entering a valid word!")
first_letter = word[0]
new_word = word.strip(word[0])
PygLatin = new_word+first_letter+"ay"
print (PygLatin)
word= input("enter a word:").lower()
result = check(word)
result I got:
1>> enter a word -> python
2>> Enter valid word!
There are two fundamental issues with your code (and one stylistic issue).
Usually you want functions to return something. For example your intention is to take a word, move the first letter to the end of the word, and add "ay" ... in other words to render it in "Pig Latin."
But you're print-ing the results rather than return-ing them. You might think that using print returns a value (in the sense that it "returned" something to your screen or terminal). But that's not what "return" means in computer programming. The Python return statement is how your function returns a result to the rest of the program following any particular invocation of (or "call into") your function.
Here's the simplest function that would work:
def pigify(word):
return word[1:]+word[0].lower()+'ay'
... that will take a "slice" of the word from a one character offset into the string all the way to the end of the string. That's what [1:] means ... it describes a range of characters, how far to the start of the range and then how far to go to get up to (but not including) the end. Then it adds the first character (which is "zero characters" from the beginning of the string), converts that to lower case (which is harmless for all characters, and only affects capital letters) and then it adds the literal string "ay" ... and it takes all of that and returns it.
pig_latin = pigify("Python")
print(pig_latin)
# ---> prints "ythonpay"
The other issue with your code is that you're calling string methods in a confused way. word.alnum() will return True only if all the characters are alphanumeric and word.isdigit() will return True only if all of the characters are numeric. That's the same as just calling word.isdigit() since digits are a proper subset of the alphanumeric character set. In other words the only strings that will pass your code will be those which contain no letters (or other characters); clearly not what you intended.
You probably would prefer to check that the string consists entirely of alphabetic characters:
def pigify(word):
if word.isalpha():
return word[1:]+word[0].lower()+'ay'
# or else? ....
This leaves you with the question of what you should do with an invalid argument (value passed to your function's "word" parameter by the caller).
You could print an error message. But that's considered poor programming practice. You could return some special value such as Python's None value; but then code that calls your function must either check the results every time, or results can cause some other error far removed from where your function was called (where this non-string value was returned).
You can also raise an exception:
def pigify(word):
if word.isalpha():
return word[1:]+word[0].lower()+'ay'
raise ValueError("Invalid input for pigify()")
... note that I don't need to explicitly spell out else in this case; the control flow only reaches that statement if I didn't return a value, only when it's an error. Any other time the control flow returns to the calling code (the part of the program that called my pigify() function).
Another thing I could do is decide that pigify() simply returns anything that doesn't look like a "word" exactly as it was passed:
def pigify(word):
if word.isalpha():
return word[1:]+word[0].lower()+'ay'
else:
return word
... here I could just return word without the else: as it did before with the raise statement. But I personally think that looks wrong; so I've explicitly spelled out the else: clause purely for stylistic reasons.
Mostly you want your program to be composed of functions (or objects with methods) that work with (manipulate) the data, and then a smaller body of code (possibly functions or object and their methods) which then "render" the results of those manipulations. Any time you're writing a function which manipulations or transforms data and writes those results to the screen or into a web page, or out to a file or database, you should pause and reconsider your design. The transformative/manipulations and computations might be re-useable while the code which writes results is typically quite specific. So interleaving one with the other is usually a bad decision.
The str.isdigit() and str.isalnum() methods only return true if all of the characters match the criteria. Your test is written so that you want to detect whether any of the characters match the criteria:
>>> word = 'abc123'
>>> word.isdigit()
False
>>> any(map(str.isdigit, word))
True
So you can amend the code to start with something like this:
def check(word):
if not word.isalnum() or any(map(str.isdigit, word)):
print ("Enter valid word!")
else:
print ("Thank You for Entering a valid word!")
...
FWIW, str.isalpha() would be easier to use because digits are already excluded.
In your code, you have problem with isalnum() which returns true if string contains only alphabets, only numbers or contains both alphabets and numbers so you can try to match if string only contains alphabets and execute your code as follow:
def check(word):
if word.isalpha(): # process only if word contains only alphabets
print("Thank You for Entering a valid word : {}!".format(word))
print(word[1:] + word[0] + "ay") # slicing is better choice in your case
else:
print("Enter valid word!!!")
word = input("enter a word:")
result = check(word.lower())
I have a list containing synonyms for the word 'Good' (this list here is shortened)
good_synonym = ['Good','good','Well','well']
And the program asks how the user is feeling
print = 'Hello, ' + name + ', How are you?'
status = raw_input('')
But sometimes, the user may respond to the question with "I am good" (or similar)
If the answer contains a word in the good synonym list, I want the program to reply
if status contains a word in good_synonym:
print ('That is good')
else:
print ('That is not so good')
note that the first line is not real python language
But I don't know which phrase to use to do the action.
Instead of a list with mixed-case words, use set objects; sets make membership testing and intersection testing much easier. Store lowercase text only, and simply lowercase the input string:
good_synonym = {'good', 'well'}
# good_synonym = set(['good', 'well']) # Python 2.6
Now test if the input string, lowercased and split on whitespace, is a disjoint set with set.isdisjoint(). If it is not a disjoint set, there is overlap between the two sets and that means at least 'good' or 'well' is present:
if not good_synonym.isdisjoint(status.lower().split()):
print ('That is good')
else:
print ('That is not so good')
Testing if a set is disjoint is efficient; it only has to test words up to the first one that is in the good_synonym set to return False quickly. You could calculate the intersection instead, but that would always test all words in the status to build a new set object.
Other solutions you may have seen, use the any() function; given a generator expression it too can be efficient as it would return True early if any of the outputs is true:
if any(word in good_synonym for word in status.lower().split()):
This, however, does all the looping and testing in Python code, while set.isdisjoint() is implemented entirely in C code.
There are many ways you could try to do this. Since you are a beginner, let's just go for something that will work - efficiency should NOT be your first consideration.
status = status.split() # breaks response into words
if any(s in good_synonyms for s in status):
print('That is good')
Of course it won't stop your program from acting as though "not good" is a reply deserving a happy answer, but this is a programming site.
Simple!
We can iterate over the good_synonyms list and check if any of them are present in the input string.
if any(synonym in status for synonym in good_synonyms):
print('That is good')
else:
print('That is not so good')
PS: To save memory, you could perhaps store the synonyms only in lower-case, as ['good', 'well'], and when you check if these are in the 'status' variable, you could just apply the .lower() on it, which just converts the entire string into lower-case, as:
good_synonyms = ['good', 'well']
if any(synonym in status.lower() for synonym in good_synonyms):
print('That is good')
Hope this helps!
Note: holdenweb's answer works too, but applying the split function on status isn't really required as you can check whether a word is present in a string(provided the words in the string are separated by a space) or not using the 'in' keyword as described above.
A short and simple solution would be to use regular expressions for pattern matching like this:
import re
line = "it is good"
good_synonyms = ["good","well"]
line = line.lower()
if any(re.search(synonym,line) for synonym in good_synonyms):
print "That is good"
else:
print "nope"
The search function of re looks for a match of pattern anywhere in the string and returns a boolean which then can be used in an if statement with any
This is a NLP question, the following code is a simple version of detecting synonym:
def is_contains_synonym(sentence, synonym):
token = sentence.split(' ')
return len(filter(lambda x: x in synonym, token)) > 0
if is_contains_synonym(status, good_synonym):
print ('That is good')
else:
print ('That is not so good')
im trying to code a kind of language translator from any language to a kind of gibberish language, wheres every consonant will be replaced with the same consonant plus an o and then the consonant again.
b = bob
d = dod
f = fof
so the text "Hi my name is x"
will become "Hohi momy nonamome isos xox"
The problem i have is the converting part.
any tips on how i can proceed?
Oh and btw I am using python 3
What i got this far.
#Welcom text
print ("Gibberish translator!")
#get stentence
original = raw_input("Give a sentence: ")
#Check so that it is a correct sentence
if len(original) > 0:
print ("")
else:
print ("give a real sentence..: ")
#convert
gibberish = ""
for i in original:
if i == "b,c,d,f,g,h,j,k,l,m,n,p,q,r,s,t,v,w,x,z":
i = i + "0" + i
gibberish.append(i)
elif i == "a,o,u,e,i,y":
gibberish.append(i)
#print out the gibberish
print (gibberish)
Yeah! i think i got it to work quite well..
# -*- coding: cp1252 -*-
#Repeat
while True :
#Welcom text
print ("Gibberish translator!")
#get stentence
original = raw_input("Give a sentence: ")
#Check so that it is a correct sentence
if len(original) > 0:
print ("")
else:
print ("Give a real sentence..: ")
#convert
gibberish = ""
for i in original:
if i in "bcdfghjklmnpqrstvwxzBCDFGHJKLMNPQRSTVWXZ":
i = i + "o" + i
gibberish = gibberish + i
elif i in "aoueiyåäö AOUEIYÅÄÖ":
gibberish = gibberish + i
#print out the gibberish
print (gibberish)
print ("\n")
Im open for suggestions to make it "better"
The problem is you're comparing a character i to a string "b,c,d,f,g,h,j,k,l,m,n,p,q,r,s,t,v,w,x,z". The two will never be equal.
What you want to do instead is use the in operator.
if i in 'bcdfghjklmnpqrstvwxz':
Also, strings don't have an .append() method, only lists do.
You can create a string from a list of strings by doing ''.join(my_list)
If and in statements don't work like that. This is actually a very common mistake, so no worries. When you get to the if i == "b,c,d,f,g,h,j,k,l,m,n,p,q,r,s,t,v,w,x,z": python reads that as "if i is all of this string (the string that contains all the consonants). Now unless you enter that string exactly somewhere in your sentence, python is going to think "nope no string like that" and skip it. You have the same problem with your vowel statements.
For the fastest fix:
if i in "bcdfghjklmnpqrstvwxz": #note the removal of commas, don't want them getting "o'd"
#rest of your code for consonants
else: #having an else is often very good practice, or else you may not get a result.
#what to do if its not a consonant
The function checks if it is a lower case vowel (might want to add stuff for upper case letters), then if it isn't, it checks if it is a letter period. string is very useful when working with strings. You should look at the docs.
And finally, you need to change append to just use + with strings.
I'm writing a program that checks if a word or sentence given by user input is a palindrome or not. This is the program so far:
def reverse(text):
a = text[::-1]
if a == text:
print "Yes, it's a palindrome."
else:
print "No, it's not a palindrome."
string = str(raw_input("Enter word here:")).lower()
reverse(string)
However, this code doesn't work for sentences. So I tried to do it like this:
import string
def reverse(text):
a = text[::-1]
if a == text:
print "Yes, it's a palindrome."
else:
print "No, it's not a palindrome."
notstring = str(raw_input("Enter word here:")).lower()
liststring = list(notstring)
forbiddencharacters = string.punctuation + string.whitespace
listcharacters = list(forbiddencharacters)
newlist = liststring - listcharacters
finalstring = "".join(newlist)
reverse(finalstring)
My goal is to put the punctuation and whitespace into a list and then subtracting those characters to the input of the user so that the program can tell if it's a palindrome even if the string has punctuation and/or whitespace. However, I don't know how I can subtract the elements in a list to the elements in another list. The way I did it, by creating another list that equals the user input minus the characters doesn't work (I tried it in my Xubuntu terminal emulator). Apart from that, when I run the program this error appears:
Traceback (most recent call last):
File "reverse.py", line 12, in <module>
forbiddencharacters = string.punctuation + string.whitespace
AttributeError: 'str' object has no attribute 'punctuation'
Ok so I have changed the variable name and I don't get that mistake above. Now I still don't know how to subtract the elements of the lists.
Since I'm a beginner programmer this might seem stupid to you. If that's the case, I'm sorry in advance. If anyone can solve one or both of the two problems I have, I'd be extremely grateful. Thanks in advance for your help. Sorry for bad english and long post :)
You should add some filtering along the way since palindromes have various syntax tricks (spaces, commas, etc.).
palindrome = "Rail at a liar"
def is_palindrome(text):
text = text.lower() #Avoid case issues
text = ''.join(ch for ch in text if ch.isalnum()) #Strips down everything but alphanumeric characters
return text == text[::-1]
if is_palindrome(palindrome):
print "Yes, it's a palindrome."
else:
print "No, it's not a palindrome."
You are on the right track, but you have used the identifier string for two different purposes.
Since you assigned to this variable name with the line:
string = str(raw_input("Enter word here:")).lower()
You can now no longer access the attributes string.punctuation and string.whitespace from the import string, because the name string is no longer bound to the module but to the user input instead.
A somewhat different approach to testing if a string is a palindrome
def palindrome(s):
s = s.lower()
ln=len(s)
for n in xrange(ln/2):
if s[n] != s[(ln-n)-1]:
return False
return True
print palindrome('Able was I ere I saw Elba')
FYI -- you'll need to tweak this to strip punctuation and white space if you like (left an an exercise to OP)
You can do that by splitting the phrase and storing it in a list. I am going to use your function (but there are more better pythonic ways to do that).
def reverse(textList1):
textList2 = textList1[::-1] #or we can use reversed(textList1)
if textList2 == text:
print "Yes, it's a palindrome."
else:
print "No, it's not a palindrome."
test1= "I am am I"
You should split the phrase and store it in a list:
test1List= test1.split(' ')
reverse(test1List)
Checking for palindrome is simple,
This works for both words and sentences.
import string
def ispalindrome(input_str):
input_str = list(input_str)
forbidden = list(string.punctuation + string.whitespace)
for forbidden_char in forbidden: # Remove all forbidden characters
while forbidden_char in input_str:
input_str.remove(forbidden_char)
return input_str == list(reversed(input_str)) # Checks if it is a palindrome
input_str = raw_input().lower() # Avoid case issues
print ispalindrome(input_str) # Get input
I was banging my head against my desk on this one, because I'm an idiot, and I've finally gotten it to work. This is a simplified, dumb version of my actual code (which is why the function's purpose seems so inane) but I'm curious whether there is (or rather, am sure there must be) a more efficient way of doing the following:
def get_char():
character = raw_input("Enter the character you would like to use.\n >")
if character.isalpha:
proceed = raw_input("The value entered is " + character + "\nWould you like to proceed?(Y/N)\n>")
while True:
if proceed in "N,n":
raw_input("Press enter to try again with another value.")
character = get_char()
break
else:
break
return character
#print character
character = get_char()
print character
What I want to end up with is a way of checking that the user's input is what they intended. Until I set character = get_char() in the while loop, I was getting problematic output (i.e. incorrect final values for character); having fixed that, I've noticed that if I include the print statement at the end of the get_char() definition, it prints out the number of times a "no" choice has been made +1. While the end result is still fine, I'm curious whether the fact that it seems to be holding iterations in a queue, as indicated by the multiple prints upon inclusion of the print statement, means that there's a better way of doing this. Thanks in advance for any help!
UPDATE:
Just in case anyone else needs help with this same issue, based on the suggestion by millerdev, I've adjusted the code to the following, which works just the same except without the self-call which was generating unnecessary character queuing:
def get_char():
while True:
character = raw_input("Enter the character you would like to use\n >")
if character.isalpha:
proceed = raw_input("The value entered is " + character + "\nWould you like to proceed? (Y/N)\n>")
if proceed in ("N", "n"):
raw_input("Press enter to try again with another value.")
else:
break
#print character
return character
character = get_char()
Because of character = get_char(), your loop only runs once, because it will recurse deeper if it fails instead of iterating again. This probably isn't what you want, because it's slower and runs the risk of overflowing the stack. The cleanest way to do this would probably be (you could replace my messages with yours easily):
def get_char(is_valid = lambda c: True):
while True:
c = raw_input('enter a character > ')
if is_valid(c):
keep = raw_input('do you want to use {0}? (Y/N)> '.format(c)).lower()
if 'n' in keep:
continue # go back to While True line
return c
print('{0} is not a valid character'.format(c))
Session:
>>> get_char()
enter a character > a
do you want to use a? (Y/N)> n
enter a character > c
do you want to use c? (Y/N)> no
enter a character > x
do you want to use x? (Y/N)> y
'x'
At least, this is the cleanest in my opinion. Your implementation has a few other problems, like proceed in "N,n", which would also count comma as an n, and if the character isn't isalpha, you still return it.
Is this what you're aiming for?
def get_char():
while True:
character = raw_input("Enter the character you would like to use.\n >")
if character.isalpha: # this is always true; add parens if that's what you want, otherwise remove it
proceed = raw_input("The value entered is " + character + "\nWould you like to proceed? (Y/n)\n>")
if proceed.lower() == "n":
raw_input("Press enter to try again with another value.")
character = get_char()
return character
character = get_char()
print character