Recursive function to remove vowels - python

I'm trying to write a recursive program that returns a string of letters from a word that are non vowels. My code right now print's out all of the non vowels of "University" but never ends . Any ideas?
def removeVowels9(aString):
if len(aString) == 0:
return newString
else:
newString = aString[1:len(aString) + 1]
firstLetter = aString[0]
#print(firstLetter)
if firstLetter in "aeiouAEIOU":
return removeVowels9(newString)
else:
newString = newString + firstLetter
print(newString)
return removeVowels9(newString)

Clearly you are never hitting the base case, because you would get a NameError (newString hasn't been defined).
Why? Let's look at your third case:
else: # starts with consonant
newString = newString + firstLetter # add first letter to the end?
return removeVowels9(newString) # repeat
once you've removed all of the vowels, this just keeps on looping the consonants, as you should have seen from your outputs:
>>> removeVowels9("University")
iversityn
ersitynv
sitynvr
itynvrs
ynvrst # all vowels gone
nvrsty
vrstyn
rstynv
stynvr
tynvrs
ynvrst # just keeps looping
...
Here is the minimal fix:
>>> def removeVowels9(aString):
if len(aString) == 0:
return aString # aString, not newString
else:
newString = aString[1:len(aString) + 1]
firstLetter = aString[0]
#print(firstLetter)
if firstLetter in "aeiouAEIOU":
return removeVowels9(newString)
else:
return firstLetter + removeVowels9(newString) # add first letter back at start, after processing rest
>>> removeVowels9("University")
'nvrsty'
But this could be much neater:
def remove_vowels(s):
"""Recursively remove vowels from the input."""
if not s: # empty string
return s
elif s[0] in "aeiouAEIOU": # first character is vowel
return remove_vowels(s[1:]) # skip first character and process rest
return s[0] + remove_vowels(s[1:]) # return first character and process rest
Which does:
>>> remove_vowels("University")
'nvrsty'
Note compatibility with the style guide for variable names etc..

Related

Maintaining first-letter capitalization in Python pig latin translator

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")

How do I fix this code about index string?

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

Accounting spaces in palindrome program

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(" ","")

CodeHS Python, remove all from string

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))`

implement my own strip method in Python

I am trying to implement my own strip method in Python, so without using the built-in method, I'd like my function to strip out all the whitespace from the left and the right.
Here, what I am trying to do is create a list, remove all the blank character before the first non-space character, then do it reverse way, finally return the list to a string. But with what I wrote, it doesn't even remove one whitespace.
I know what I am trying to do might not even work, so I would also like to see the best way to do this. I am really new to programming, so I would take any piece of advise that makes my program better. Thanks!
# main function
inputString = input("Enter here: ")
print(my_strip(inputString))
def my_strip(inputString):
newString = []
for ch in inputString:
newString.append(ch)
print(newString)
i = 0
while i < len(newString):
if i == " ":
del newString[i]
elif i != " ":
return newString
i += 1
print(newString)
Instead of doing a bunch of string operations, let's just get the beginning and ending indices of the non-whitespace portion and return a string slice.
def strip_2(s):
start = 0
end = -1
while s[start].isspace():
start += 1
while s[end].isspace():
end -= 1
end += 1
return s[start:end or None]
How about using regular expression?
import re
def my_strip(s):
return re.sub(r'\s+$', '', re.sub(r'^\s+', '', s))
>>> my_strip(' a c d ')
'a c d'
What you seem to be doing is an ltrim for spaces, since you return from the function when you get a non-space character.
Some changes are needed:
# main function
inputString = input("Enter here: ")
print(my_strip(inputString))
def my_strip(inputString):
newString = []
for ch in inputString:
newString.append(ch)
print(newString)
i = 0
while i < len(newString):
if i == " ": # <== this should be newString[i] == " "
del newString[i]
elif i != " ": # <== this should be newString[i] == " "
return newString
i += 1 # <== this is not needed as the char is deleted, so the next char has the same index
print(newString)
So the updated code will be:
# main function
inputString = input("Enter here: ")
print(my_strip(inputString))
def my_strip(inputString):
newString = []
for ch in inputString:
newString.append(ch)
print(newString)
i = 0
while i < len(newString):
if newString[i] == " ":
del newString[i]
elif newString[i] != " ":
return newString
print(newString)
Good luck with the rest of the exercise (implementation of rtrim).

Categories

Resources