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))`
Related
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()
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
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 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']
I'm on Codecademy, the section called "Practice Makes Perfect", on problem 10/15, the word-censoring one. The problem goes like this:
Write a function called censor that takes two strings, text and word, as input. It should return the text with the word you chose replaced with asterisks.
My idea was to do this:
def censor(text, word):
length_of_word = len(word)
word_now_censored = '*' * length_of_word
wordlist = text.split()
for item in wordlist:
if item == word:
item = word_now_censored
return " ".join(wordlist)
But, so it seems, changing the value of item in the for loop doesn't change the value of the item in the list.
I thought another way could be to use a while loop, going from i = 0 to i < len(wordlist), and then modify wordlist[i] as needed, but I'd just like to understand why my for-loop method doesn't work.
Change it to this:
for index, item in enumerate(wordlist):
if item == word:
wordlist[index] = word_now_censored
You could simply use re.sub to replace all instances of word:
import re
def censor(text, word):
return re.sub(r'\b{}\b'.format(word), '*' * len(word), text)
Your observation is right
changing the value of item in the for loop doesn't change the value of the item in the list.
There are many ways to go about this. Here is one way. Create another variable new_words_list. Append the word from wordlist to new_words_list if it not word. Else append word_now_censored to new_words_list.
Which translates to:
def censor(text, word):
length_of_word = len(word)
word_now_censored = '*' * length_of_word
wordlist = text.split()
new_words_list = []
for item in wordlist:
if item == word:
new_words_list.append(word_now_censored)
else:
new_words_list.append(item)
return " ".join(new_words_list)
def censor(text,word):
text=list(text)
for n in range(0,len(text)):
i=0
while 1==1:
for i in range(0,len(word)):
if text[n+i]==word[i]:
i+=1
else:
break
if i==len(word):
for m in range(0,i):
text[n+m]='*'
else:
break
n+=i
return "".join(text)
print censor("this hack is wack hack", "hack")
Here is another version:
def censor(text, word):
lst = text.split()
while word in lst:
index = lst.index(word)
lst.remove(word)
lst.insert(index,'*' * len(word))
return " ".join(lst)
censor takes two strings, text and word, as input. It returns the text with the word you chose replaced with asterisks.
def censor(text,word):
result = ""
count = 0
no_of_stars = 0
split_list = text.split()
for i in split_list:
count += 1
if(i==word):
result += "*" * len(i)
else:
result +=i
if(count != len(split_list)):
result += " "
return result
Here's my version. Simply build a new word of asterisks the same length as the word, then replace it.
def censor(text, word):
if word in text:
blabber = ""
while True:
blabber += "*"
if len(blabber) == len(word):
break
return text.replace(word, blabber)
def censor(text,word):
res = text.split()
temp = ""
for i,j in enumerate(res):
if j == word:
res[i] = "*" * len(word)
return " ".join(res)
Just solved it and this was my solution:
def censor(text, word):
textList = text.split()
for index, var in enumerate(textList):
if var == word:
textList[index] = "*" * len(word)
return " ".join(textList)
def censor(text,word) :
c=''
for i in text.split() :
if i == word :
i = "*" * len(word)
c += ' ' + i
else :
c += ' ' + i
return c
print censor("this hack is wack hack", "hack")
def censor(text, word):
lista=[]
for i in text.split():
if i==word:
lista+=['*'*len(word)]
else:
lista+=[i]
return ' '.join(lista)
def censor(text, word):
new_text = text.split()
ctext = []
for item in new_text:
if item == word:
item = "*" *len(word)
ctext.append(item)
return " ".join(ctext)
def censor(text, word):
a = word
b = len(a)
for a in text:
text = text.replace(word, "*"*b)
return text
My idea was just:
def censor(text, word):
answer = text.replace(word, "*"*len(word))
return answer
This is might be simple one but I think simple is good. And I didn't have to use any loop, is it good?
If you like my answer, please let me know, I'll be really happy. Thank you
I've made it quite simple and I don't see why no one mentioned this.
def censor(text, word):
return text.replace(word,"*" * len(word))
I'll appreciate it if you will take a look at this one.
def censor(text, word):
if word in text:
return text.replace(word, '*' * len(word))