I make a function to input string and return with head and tail with two indexes without space and punctuation. but it's return only "empty string"
def hello(word):
str_cnt = ""
for letter in word:
if letter not in string.whitespace and letter not in string.punctuation:
str_cnt += letter
if len(str_cnt) < 2 :
return "empty string"
else:
return str_cnt[:2] + str_cnt[-2:]
word = input("Input String : ")
result = hello(word)
print("Result: ",result)
I expect when I input "hello world!", and the actual output is "held"
or "Hi!" = "HiHi".
The problem is simply incorrect indentation:
import string
def hello(word):
str_cnt = ""
for letter in word:
if letter not in string.whitespace and letter not in string.punctuation:
str_cnt += letter
if len(str_cnt) < 2:
return "empty string"
return str_cnt[:2] + str_cnt[-2:]
word = input("Input String: ")
result = hello(word)
print("Result: ", result)
Indentation is everything in Python!
> python3 test.py
Input String: hello world!
Result: held
>
However, if the input is long, this is the wrong way to go about the problem. We test a lot of characters we'll never use against the whitespace and punctuation lists. Instead we should grab the first two valid characters from either end of the list and ignore the middle. Something like:
def hello(word):
unwanted = string.whitespace + string.punctuation
str_start = ""
for letter in word:
if letter not in unwanted:
str_start += letter
if len(str_start) == 2:
break
if len(str_start) < 2:
return "empty string"
str_end = ""
for idx in range(len(word) - 1, -1, -1):
if word[idx] not in unwanted:
str_end = word[idx] + str_end
if len(str_end) == 2:
break
return str_start + str_end
EXAMPLE
> python3 test2.py
Input String: telecommunications!
Result: tens
>
The letters 'lecommunicatio' were never tested as they had no effect on the eventual outcome.
You miss-indented the last if block:
import string
def hello(word):
str_cnt = ""
for letter in word:
if letter not in string.whitespace and letter not in string.punctuation:
str_cnt += letter
if len(str_cnt) < 2 :
return "empty string"
else:
return str_cnt[:2] + str_cnt[-2:]
word = input("Input String : ")
result = hello(word)
print("Result: ",result)
Example output:
Input String : Hello World!
Result: Held
Your issue is that you return after the first iteration through the work, no matter what.
Move the return nogic after the logic:
def hello(word):
str_cnt = ""
for letter in word:
if letter not in string.whitespace and letter not in string.punctuation:
str_cnt += letter
if len(str_cnt) < 2 :
return "empty string"
else:
return str_cnt[:2] + str_cnt[-2:]
The problem is indentation as everyone says, after correcting which it works. I would do it more pythonically as:
def hello(word):
w = ''.join([x for x in word if x not in string.whitespace and x not in string.punctuation])
return w[:2] + w[-2:] if len(w) > 1 else 'empty string'
Usage:
>>> hello('hello world!')
held
Related
I have a pig latin translator program (yes, I've searched and reviewed several posts) but cannot figure out one part regarding applying capitalization.
My thinking is once I have the final 'pigged word', if the first letter of the original input was uppercase, do the same for the translated/pigged word using the title() or capitalize() function (like Pig_Latin Captitalization).
I'm sure this overall solution could be improved but I'm really only seeking guidance on the capitalization piece. (Though all constructive criticism is always welcome!)
# If first letter was capitalized, maintain that in 'pigged' word
# Example: "Shark" to "Arkshay"
# Convert any other caps to lower
# Example: "ShaRK" still to "Arkshay"
if not first_one.islower():
pigged_input = pigged_input.title()
return pigged_input
That snippet is contained in the full code:
def pig_latin_translator(user_input):
""" Translator function """
vowels = "aieou"
special_two = ("qu")
first_one = user_input[0]
first_two = user_input[0:2]
pigged_input = ''
# Input begins with vowel: keep input and add "yay"
if first_one in vowels:
pigged_input = user_input.lower()
pigged_input += "yay"
return pigged_input
else:
pigged_input = user_input.lower()
# Input does not begin with vowel: find position of first vowel
for letter in user_input:
if letter in vowels:
index_value = user_input.index(letter)
break
# Special two-letter cases: move both letters to end and add "ay"
# Example: "quarter" to "arterquay"
if first_two in special_two:
pigged_input = user_input[2:] + user_input[:2] + "ay"
return pigged_input
# Regular pig latin: move indexed letter to end and add "ay"
else:
pigged_input = user_input[index_value:] + user_input[:index_value] + "ay"
return pigged_input
# If first letter was capitalized, maintain that in 'pigged' word
# Example: "Shark" to "Arkshay"
# Convert any other caps to lower
# Example: "ShaRK" still to "Arkshay"
if not first_one.islower():
pigged_input = pigged_input.title()
return pigged_input
def error_check_and_print(x):
""" Error checking function
If zero-length or contains non-alpha characters, print error message
Otherwise print result from translator function
"""
if len(x) == 0:
print("Error: Not anything!")
elif not x.isalpha():
print("Error: Not alpha only!")
else:
return print(pig_latin_translator(x))
pigged_Shark = error_check_and_print("Shark")
# returns "arkShay" but want "Arkshay"
You return the word arkShay before captalized ...Please return pigged_input only at function end.
I have modified your code
def pig_latin_translator(user_input):
""" Translator function """
vowels = "aieou"
special_two = ("qu")
first_one = user_input[0]
first_two = user_input[0:2]
pigged_input = ''
# Input begins with vowel: keep input and add "yay"
if first_one in vowels:
pigged_input = user_input.lower()
pigged_input += "yay"
else:
pigged_input = user_input.lower()
# Input does not begin with vowel: find position of first vowel
for letter in user_input:
if letter in vowels:
index_value = user_input.index(letter)
break
# Special two-letter cases: move both letters to end and add "ay"
# Example: "quarter" to "arterquay"
if first_two in special_two:
pigged_input = user_input[2:] + user_input[:2] + "ay"
# return pigged_input
# Regular pig latin: move indexed letter to end and add "ay"
else:
pigged_input = user_input[index_value:] + user_input[:index_value] + "ay"
# return pigged_input
# If first letter was capitalized, maintain that in 'pigged' word
# Example: "Shark" to "Arkshay"
# Convert any other caps to lower
# Example: "ShaRK" still to "Arkshay"
if not first_one.islower():
pigged_input = pigged_input.title()
return pigged_input
def error_check_and_print(x):
""" Error checking function
If zero-length or contains non-alpha characters, print error message
Otherwise print result from translator function
"""
if len(x) == 0:
print("Error: Not anything!")
elif not x.isalpha():
print("Error: Not alpha only!")
else:
return print(pig_latin_translator(x))
pigged_Shark = error_check_and_print("Shark")
I am revisiting a B-Language translation program example in Python from Stanford's notes. This program works where words are transformed such that every vowel cluster is reduplicated with a leading "b".
For example:
translate("quick") => "quibuick"
translate("spaghetti") => "spabaghebettibi"
The code below works perfectly fine, but due to confusion, I was wondering if there's an alternative way to compute the translate(word, separator="b") function which converts a word string by reduplicating each vowel cluster with a leading b. Is it possible to find out a way which exclude the usage of the computation "start = -1"?
def translate(word, separator="b"):
start = -1
translation = ""
for i in range(len(word)):
ch = word[i]
if isEnglishVowel(ch):
if start == -1:
start = i
else:
if start >= 0:
translation += word[start:i] + separator + word[start:i]
start = -1
translation += ch
if start >= 0:
translation += word[start:] + separator + word[start:]
return translation
def isEnglishVowel(ch):
return len(ch) == 1 and "aeiou".find(ch) >= 0
def TestTranslate():
while True:
word = input("Enter a single word [or hit enter to quit]: ");
if word == "": break
translation = translate(word)
print("\"{}\" -> \"{}\"".format(word, translation))
if __name__ == "__main__":
TestTranslate()
Thank you.
I modified the code a bit. It uses vowels instead of start but the internal logic is a little more simplified. Basically grow vowels until you encounter a consonant, then pop vowels into the translation string with the separator in between.
def translate(word, separator="b"):
translation = ""
vowels = ""
for ch in word:
if vowels and not isEnglishVowel(ch):
translation += separator + vowels
vowels = ""
translation += ch
if isEnglishVowel(ch):
vowels += ch
return translation + separator + vowels if vowels else translation
def isEnglishVowel(ch):
return len(ch) == 1 and ch in 'aeiou'
def TestTranslate():
while True:
word = input("Enter a single word [or hit enter to quit]: ")
if word == "": break
translation = translate(word)
print("\"{}\" -> \"{}\"".format(word, translation))
if __name__ == "__main__":
TestTranslate()
This is a program that accepts a string of words and checks if the words are palindromes and if it is one, it prints it. However if a string has a space in it, my program won't count it as a palindrome (Example: nurses run). What should I be adding to make the program exclude the space, when it's accounting for palindromes?
Palindrome: a word, phrase, or sequence that reads the same backwards as forwards, e.g. 'madam' or 'nurses run'
import sys
strings = []
for s in sys.argv[1:]:
strings += [s]
def is_palindrome(word):
if len(word) <= 2 and word[0] == word[-1]:
return True
elif word[0] == word[-1]:
is_palindrome(word[1:-1])
return True
else:
return False
def printpalindromes(strings):
for s in strings:
if is_palindrome(s) == True:
print(s)
printpalindromes(strings)
Try stripping out the whitespaces before doing the palindrome check
>>> x = "nurses run"
>>> x.replace(" ", "")
'nursesrun'
You can use reversed:
def palindrome(word):
if ' ' in word:
word = word.replace(' ', '')
palindrome = reversed(word)
for letter, rev_letter in zip(word, palindrome):
if letter != rev_letter:
return 'Not Palindrome'
return 'Palindrome'
Your code is still incorrect in the elif statement. You've added return True when you should actually be returning the response from your recursive call as previously mentioned.
def is_palindrome(word):
if len(word) <= 2 and word[0] == word[-1]:
return True
elif word[0] == word[-1]:
return is_palindrome(word[1:-1])
else:
return False
Here's a simpler solution of your problem:
import sys
sys.argv = [" nurses ", " run "]
word = "".join([s.strip() for s in sys.argv])
print("{} {} palindrome".format(word, "is" if word == word[::-1] else "is not"))
or you can just create the word out of sys.argv like this:
word = "".join(sys.argv).replace(" ","")
I am using CodeHS for my Computer Science Principles class and one of the problems in the Strings section is really confusing me. We have to remove all of one string from another string.
These are the official instructions:
Write a function called remove_all_from_string that takes two strings, and returns a copy of the first string with all instances of the second string removed. You can assume that the second string is only one letter, like "a".
We are required use:
A function definition with parameters
A while loop
The find method
Slicing and the + operator
A return statement
We are expected to only have to use those 5 things to make it work.
I attempted to write this program but my function doesn't do anything and I am really stumped.
def remove_all_from_string(word, letter):
while letter in word:
x=word.find(letter)
if x==-1:
continue
else:
return x
print word[:x] + word[x+1:]
remove_all_from_string("alabama", "a")
The easiest way to do this would obviously just be
def remove_all_from_string(word, letter):
return word.replace(letter, "")
However, considering the parameters, another way we could do this is like so:
def remove_all_from_string(word, letter):
while letter in word:
x=word.find(letter)
if x == -1:
continue
else:
word = word[:x] + word[x+1:]
return word
You could run this and print it by typing
>>> print(remove_all_from_string("Word Here", "e"))
#returns Word hr
def remove_all_from_string(word, letter):
while letter in word:
x=word.find(letter)
if x == -1:
continue
else:
word = word[:x] + word[x+1:]
return word
print(remove_all_from_string("hello", "l"))
def remove_all_from_string(word, letter):
letters = len(word)
while letters >= 0:
x=word.find(letter)
if x == -1:
letters = letters - 1
continue
else:
# Found a match
word = word[:x] + word[x+1:]
letters = letters - 1
return word
remove_all_from_string("alabama", "a")
I have this so far and it keeps saying that message is not defined and when I define it with find_secret_word it says "find_secret_word" is not defined, what do I do?
This is my code:
`word = "bananas"
letter = "na"
index = word.find(letter)
def remove_all_from_string(word, letter):
while letter in word:
x=word.find(letter)
if x == -1:
continue
else:
word = word[:x] + word[x+1:]
return word
word = word[:index] + word[index+len(letter):]
print(remove_all_from_string("hello", "l"))
def find_secret_word(message):
while True:
return hidden_word
hidden_word = "iCjnyAyT"
for letter in message:
if letter.upper():
hidden_word = hidden_word + letter
print (find_secret_word(message))`
I need a python function that can do the following:
Given an input of 't' and 'tattle', it should return a list like so:
['Tattle','taTtle','tatTle']
Or with 'z' and 'zzzzz':
['Zzzzz','zZzzz','zzZzz','zzzZz','zzzzZ']
I coded the following, but it does not work with the second example because the current function checks to see if the basestr matches what is already in the resulting list, R, and can pick up false positives due to words with multiple basestr's already in the word. Anyone have any advice?
def all_variants(wrapletter,word):
L,R,WLU,basestr=list(word),[],wrapletter.upper(),''
if L.count(wrapletter)==1:
for char in L:
if wrapletter==char:
basestr=basestr+WLU
else:
basestr=basestr+char
R.append(basestr)
return(R)
else:
for i in range(L.count(wrapletter)):
basestr=''
if i==0 and L[0]==wrapletter:
basestr=WLU
for char in range(1,len(L)):
basestr=basestr+L[char]
R.append(basestr)
else:
for char in L:
if wrapletter==char:
if WLU in basestr:
basestr=basestr+char
elif basestr in str(R):
basestr=basestr+char
else:
basestr=basestr+WLU
else:
basestr=basestr+char
R.append(basestr)
R.remove(R[0])
return(R)
It's not elegant, but maybe it's what you need?
target = "daaddaad"
def capitalize(target_letter, word):
return [word[:i] + word[i].upper() + word[i + 1:]
for i in xrange(len(word)) if word[i] == target_letter]
print capitalize("d", target)
Outputs:
['Daaddaad', 'daaDdaad', 'daadDaad', 'daaddaaD']
inp = 't'
word = 'tattle'
inds = (i for i,ele in enumerate(word) if ele == inp)
print([word[:i]+word[i].upper()+word[i+1:] for i in inds])
['Tattle', 'taTtle', 'tatTle']
Try this. I iterate through each letter, shift it to uppercase, and sandwich it with the other parts of the original string.
def all_variants(wrapletter, word):
variants = []
for i, letter in enumerate(word):
if letter == wrapletter:
variants.append(word[:i] + letter.upper() + word[i+1:])
return variants
print all_variants('z', 'zzzzz')
print all_variants('t', 'tattle')
def all_variants(wrapletter, word):
list = []
for i in range(len(word)):
if(word[i]==wrapletter):
start = word[0:i].lower()
str = word[i].upper()
end = word[i+1::].lower()
list.append(start+str+end)
return list
These returned when I ran this function:
>>>all_variants("t", "tattle")
['Tattle', 'taTtle', 'tatTle']
>>>all_variants("z", "zzzzz")
['Zzzzz', 'zZzzz', 'zzZzz', 'zzzZz', 'zzzzZ']