Upper case characters every other character but ignoring symbols and spaces - python

I'm a novice working on a practice script of which I have 90% figured out but am stumped on one portion. I'm doing the mocking spongebob "challenge" on dmoj which asks you to make every other character of a given string upper case, but demands symbols and spaces to be ignored and only letters to be counted.
I and am able to make every other character upper case or lower case, but I am not sure how to ignore symbols and spaces? I'll drop what I have so far for critique. Thank you for your time.
meme1 = "I don't even know her like that"
meme2 = "You can't just make a new meme from a different Spongebob clip every
couple of months"
meme3 = "I must have listened to that latest Ed Sheeran song 10000 times!"
memeFIN1 = [""] * len(meme1)
memeFIN2 = [""] * len(meme2)
memeFIN3 = [""] * len(meme3)
memeFIN1[1::2] = meme1[1::2].upper()
memeFIN2[1::2] = meme2[1::2].upper()
memeFIN3[1::2] = meme3[1::2].upper()
memeFIN1[::2] = meme1[::2].lower()
memeFIN2[::2] = meme2[::2].lower()
memeFIN3[::2] = meme3[::2].lower()
memeFIN1 = "".join(memeFIN1)
memeFIN2 = "".join(memeFIN2)
memeFIN3 = "".join(memeFIN3)
print(memeFIN1)
print(memeFIN2)
print(memeFIN3)
EDIT:
All of the following solutions in the answers helped me come to my own, but none of them seemed to work entirely on their own. In cheesits solution, changing counter to start at 1 works, but not realizing that (as an utter noob) I did counters differently, essentially doing the same thing. This is the solution that worked for me:
meme1 = "I don't even know her like that"
meme2 = "You can't just make a new meme from a different Spongebob clip every couple of months"
meme3 = "I must have listened to that latest Ed Sheeran song 10000 times!"
def spongebobify(meme):
count = 0
char = []
for ch in meme:
if ch.isalpha() and count % 2 == 1:
char.append(ch.upper())
count += 1
elif ch.isalpha():
char.append(ch.lower())
count += 1
else:
char.append(ch)
return ''.join(char)
m1 = spongebobify(meme1)
m2 = spongebobify(meme2)
m3 = spongebobify(meme3)
print (m1)
print (m2)
print (m3)

If you want something readable, try this:
def spongebobify(phrase):
## Turn every character lowercase
phrase = phrase.lower()
## Keep track of how many letters you've seen
counter = 0
## Create a list to hold characters
chars = []
## Go through the entire string
for ch in phrase:
## If this is a letter, increment
if ch.isalpha():
counter += 1
## If this is a letter and our counter is odd:
if ch.isalpha() and counter % 2:
chars.append(ch.upper())
## Otherwise, just add it as-is
else:
chars.append(ch)
return ''.join(chars)
If you want a one liner (disregarding efficiency):
def spongebobify(phrase):
return ''.join([ch.lower() if ch.isalpha() and len([c for c in phrase[:i] if c.isalpha()]) % 2 else ch for i, ch in enumerate(phrase.upper())])
## Readable version:
#return ''.join([
# ch.lower()
# if ch.isalpha()
# and len([c for c in phrase[:i] if c.isalpha()]) % 2
# else ch
# for i, ch in enumerate(phrase.upper())
#])

you can use a bit to indicate which lower/upper you're currently looking at, toggling the bit whenever an alpha character is found.
def speak_like_spongebob(phrase):
case_bit = 0
res = []
for lower_upper in zip(phrase.lower(), phrase.upper()):
res.append(lower_upper[case_bit])
case_bit ^= lower_upper[0].isalpha()
return ''.join(res)

You need to use a loop, so you can increment a counter only when the character is a letter, and then check whether that counter is odd or even.
def mock_spongebob(input):
letters = 0
result = ""
for c in input:
if c.isalpha():
result += c.lower() if letters % 2 == 0 else c.upper()
letters += 1
else:
result += c
return result

As others have mentioned, you will need to iterate through each character in the strings, determine whether it's a character or a symbol, and act accordingly.
The following program would print every other character in uppercase, not counting non-alphabetic characters:
meme1 = "I don't even know her like that"
meme2 = "You can't just make a new meme from a different Spongebob clip every couple of months"
meme3 = "I must have listened to that latest Ed Sheeran song 10000 times!"
for meme in [meme1, meme2, meme3]:
count = 0
meme_mod = ""
for c in meme:
if not c.isalpha():
meme_mod += c
continue
elif count % 2 == 0:
meme_mod += c.lower()
else:
meme_mod += c.upper()
count += 1
print meme_mod
This program would output:
i DoN't EvEn KnOw HeR lIkE tHaT
yOu CaN't JuSt MaKe A nEw MeMe FrOm A dIfFeReNt SpOnGeBoB cLiP eVeRy CoUpLe Of MoNtHs
i MuSt HaVe LiStEnEd To ThAt LaTeSt Ed ShEeRaN sOnG 10000 tImEs!

Here's an article that shows how to write a SpongeBob Mocking Converter script in Python

Related

Number of words in text you can fully type using this keyboard

There is such a task with Leetcode. Everything works for me when I press RUN, but when I submit, it gives an error:
text = "a b c d e"
brokenLetters = "abcde"
Output : 1
Expected: 0
def canBeTypedWords(self, text, brokenLetters):
for i in brokenLetters:
cnt = 0
text = text.split()
s1 = text[0]
s2 = text[1]
if i in s1 and i in s2:
return 0
else:
cnt += 1
return cnt
Can you please assist what I missed here?
Everything work exclude separate letters condition in a text.
So consider logically what you have to do, then write that algorithmically.
Logically, you have a list of words, a list of broken letters, and you need to return the count of words that have none of those broken letters in them.
"None of those broken letters in them" is the important bit -- if even one broken letter is in the word, it's no good.
def count_words(broken_letters, word_list) -> int:
words = word_list.split() # split on spaces
broken_letters = set(broken_letters) # we'll be doing membership checks
# on this kind of a lot, so changing
# it to a set is more performant
count = 0
for word in words:
for letter in word:
if letter in broken_letters:
# this word doesn't work, so break out of the
# "for letter in word" loop
break
else:
# a for..else block is only entered if execution
# falls off the bottom naturally, so in this case
# the word works!
count += 1
return count
This can, of course, be written much more concisely and (one might argue) idiomatically, but it is less obvious to a novice how this code works. As exercise to the reader: see if you can understand how this code works and how you might modify it if the exercise was, instead, giving you all the letters that work rather than the letters that are broken.
def count_words(broken_letters, word_list) -> int:
words = word_list.split()
broken_letters = set(broken_letters)
return sum((1 for word in words if all(lett not in broken_letters for lett in word)))

Find alphabet neighbour letters in string (2 types: aABClg = ABC, aAbcd = aA)

EDIT: The problem, and the answer lies in using the enumerate function to access the index of iterables, but I'm still working on applying it properly.
I was asked to generate a random word with N length, and to print uppercase alphabet neighbours and lower - upper neighbours. I really don't know how to put this better.
The example is in the title, here is my code so far, and I think it works, I just need to fix the error made by the index search in the ascii_uppercase list variable.
Also, please excuse the messy do - while loop at the beginning.
import string
import random
letters = list(string.ascii_uppercase + string.ascii_lowercase)
enter = int(input('N: '))
def randomised(signs = string.ascii_uppercase + string.ascii_lowercase, X = enter):
return( ''.join(random.choice(signs) for _ in range(X)))
if enter == 1:
print('END')
while enter > 1:
enter = int(input('N: '))
word1 = randomised()
word2 = list(word1)
neighbour = ''
same = ''
for j in word2:
if word2[j] and word2[j+1] in string.ascii_uppercase and letters.index(j) == word2.index(j) and letters.index(j+1) == word2.index(j+1):
same += j
same += j+1
for i in word2:
if word2[i] == i.upper and word2[i+1] == (i+1).upper:
neighbour += i
neighbour += i+1
print('Created: {}, Neighbour uppercase letters: {}, Neighbour same letters: {}' .format(word1,same,neighbour))
expected behaviour:
N: 7
Created: aaBCDdD, Neighbour uppercase letters: BCD, Neighbour same letters: dD
N: 1
N: END
I am not so sure, but i think your problem might stem from the use of "i+1" and "j+1" without limiting the iterations stop before the last one.
The next thing is that you need to put this code in english for people to be able to provide better answers, i am not native english, but the core of my code is in english so it will be understandable worldwide, there are other general improvements that can be done, but those are learn while coding.
I hope your assignment goes great.
Another recommendation you can use "a".islower() to see if the character is lowercase, isupper() to se if it is uppercase, you don't need to import the whole alphabet. There are many builtin functions to deal with common scenarios and those tend to be more efficient than what most people would do without them.
Edit: the error is because you are doing string + number
Here is a simple working code (without formatting of the output). I used a simple pairwise iteration to compare each character with the previous one.
# generation of random word
N = 50
word = ''.join(random.choices(ascii_letters, k=N))
# forcing word for testing
word = 'aaBCDdD'
# test of conditions
cond1 = ''
cond2 = ''
flag1 = False # flag to add last character of stretch
for a,b in zip('_'+word, word+'_'):
if a.isupper() and b.isupper() and ord(a) == ord(b)-1:
cond1 += a
flag1 = True
elif flag1:
flag1 = False
cond1 += a
if a.islower() and b.isupper() and a.lower() == b.lower():
cond2 += a+b
print(cond1, cond2, sep='\n')
# BCD
# dD
NB. In case the conditions are met several times in the word, the identified patterns will just be concatenated
Example on random word of 500 characters:
IJRSOPHILMMNVW
kKdDyY

How to group consecutive letters in a string in Python?

For example: string = aaaacccc, then I need the output to be 4a4c. Is there a way to do this without using any advanced methods, such as libraries or functions?
Also, if someone knows how to do the reverse: turning "4a4c: into aaaacccc, that would be great to know.
This will do the work in one iteration
Keep two temp variable one for current character, another for count of that character and one variable for the result.
Just iterate through the string and keep increasing the count if it matches with the previous one.
If it doesn't then update the result with count and value of character and update the character and count.
At last add the last character and the count to the result. Done!
input_str = "aaaacccc"
if input_str.isalpha():
current_str = input_str[0]
count = 0
final_string = ""
for i in input_str:
if i==current_str:
count+=1
else:
final_string+=str(count)+current_str
current_str = i
count = 1
final_string+=str(count)+current_str
print (final_string)
Another solution and I included even a patchwork reverse operation like you mentioned in your post. Both run in O(n) and are fairly simple to understand. The encode is basically identical one posted by Akanasha, he was just a bit faster in posting his answer while i was writing the decode().
def encode(x):
if not x.isalpha():
raise ValueError()
output = ""
current_l = x[0]
counter = 0
for pos in x:
if current_l != pos:
output += str(counter) + current_l
counter = 1
current_l = pos
else:
counter += 1
return output + str(counter) + current_l
def decode(x):
output = ""
i = 0
while i < len(x):
if x[i].isnumeric():
n = i + 1
while x[n].isnumeric():
n += 1
output += int(x[i:n])*x[n]
i = n
i += 1
return output
test = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasasggggggbbbbdd"
test1 = encode(test)
print(test1)
test2 = decode(test1)
print(test2)
print(test == test2)
yes, you do not need any libraries:
list1 = list("aaaacccc")
letters = []
for i in list1:
if i not in letters:
letters.append(i)
string = ""
for i in letters:
string += str(list1.count(i))
string+=str(i)
print(string)
Basically, it loops through the list, finds the unique letters and then prints the count with the letter itself. Reversing would be the same function, just print the amount.

How can I change a targeted string in a list of strings?

This is where my fill-in-the-blanks game begin. I need help replacing the old sentence with a new sentence when the user answer correctly. I'm still not sure if everything should be done in one function or get a different one. My main function is "def answer_check(answer, sentence, blank_space):". I want to use the other two functionst too (if relevant).The "def replace_the_blank(answer, sentence, blank):" function could need some modifying to respond only when the user correctly guess and to use next string accordingly too... I don't know how to go about it.....
Overall, I need help replacing strings that are from the "blank_space" list in the "driver_Knowledge_test" list, and replace it with the "answer_1" list --- all of which should be in ordert too and when the user correctly guesses... Hope that makes sense.
driver_knowledge_test = ["When you're going to drive it is important to always put on your ___1___, including your passengers.","If there are no lanes marked on the road, you should drive in the ___2___ side of the road.", "It's getting dark and the sun is fading, you should turn on the ___3___. ","Before driving on a freeway, you should make sure you have enough ___4___, oil, water and the correct tyre pressure."]
answer_1 = ['seatbelts', 'left', 'light', 'fuel']
blank_space = ["___1___", "___2___", "___3___", "___4___"]
'''goal: collect user's answer and replace sentence with word when answered correct - other loop to rettry'''
def finding_blank(word, pos):
for ea_blank in word:
if ea_blank in pos: #This equals to teh whole list.
return ea_blank
return None
def replace_the_blank(answer, sentence, blank):
new_list = []
blank_index = 0
answer_index = 0
sentence_index = 0
for ea_element in sentence:
blank_number = finding_blank(sentence[sentence_index], blank)
if blank_number == blank[blank_index]:
blank_number.replace(blank_index, answer[answer_index])
blank_index += 1
answer_index += 1
sentence_index += 1
"Inputs answer list and sentence string"
"Outputs new sentence when answered correctly"
def answer_check(answer, sentence, blank_space):
new_list = []
index = 0
sentence_index = 0
answer_index = 0
blank_index = 0
while index < sentence:
print sentence[sentence_index]
player_answer = raw_input("\nType your answer for " + blank_space[blank_index] + " \n>>>")
if player_answer.lower() == answer[answer_index]:
new_list.append(sentence[sentence_index])
answer_index += 1
sentence_index += 1
index += 1
blank_index += 1
#print replace_the_blank(answer, sentence, blank)
print "CCORRECT! \n"
else:
print "Wrong! Try again. :) \n"
answer_check(answer_1, driver_knowledge_test, blank_space)
You may use string replace method to replace a part of string with another string.
So instead of
print replace_the_blank(answer, sentence, blank)
try
print sentence[sentence_index].replace(blank_space[blank_index], answer[answer_index])

How to avoid Runtime error in this coding challenge?

I am completing this HackerRank coding challenge. Essentially, the challenge asks us to find all the substrings of the input string without mixing up the letters. Then, we count the number of substrings that start with a vowel and count the number of substrings that start with a consonant.
The coding challenge is structured as a game where Stuart's score is the number of consonant starting substrings and Kevin's score is the number of vowel starting substrings. The program outputs the winner, i.e. the one with the most substrings.
For example, I created the following code:
def constwordfinder(word):
word = word.lower()
return_lst = []
for indx in range(1,len(word)+1):
if word[indx-1:indx] not in ['a','e','i','o','u']:
itr = indx
while itr < len(word)+1:
return_lst.append(word[indx-1:itr])
itr +=1
return return_lst
def vowelwordfinder(word):
word = word.lower()
return_lst = []
for indx in range(1,len(word)+1):
if word[indx-1:indx] in ['a','e','i','o','u']:
itr = indx
while itr < len(word)+1:
return_lst.append(word[indx-1:itr])
itr +=1
return return_lst
def game_scorer(const_list, vow_list):
if len(const_list) == len(vow_list):
return 'Draw'
else:
if len(const_list) > len(vow_list):
return 'Stuart ' + str(len(const_list))
else:
return 'Kevin ' + str(len(vow_list))
input_str = input()
print(game_scorer(constwordfinder(input_str), vowelwordfinder(input_str)))
This worked for smaller strings like BANANA, although when HackerRank started inputting strings like the following, I got multiple Runtime errors on the test cases:
NANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANANNANAN
I tried structuring the program to be a bit more concise, although I still got Runtime errors on the longer test cases:
def wordfinder(word):
word = word.lower()
return_lst = []
for indx in range(1,len(word)+1):
itr = indx
while itr < len(word)+1:
return_lst.append(word[indx-1:itr])
itr +=1
return return_lst
def game_scorer2(word_list):
kevin_score = 0
stuart_score = 0
for word in word_list:
if word[0:1] not in ['a','e','i','o','u']:
stuart_score += 1
else:
kevin_score +=1
if stuart_score == kevin_score:
return 'Draw'
else:
if stuart_score > kevin_score:
return 'Stuart ' + str(stuart_score)
else:
return 'Kevin ' + str(kevin_score)
print(game_scorer2(wordfinder(input())))
What else exactly should I be doing to structure my program to avoid Runtime errors like before?
Here's a quick and dirty partial solution based on my hints:
input_str = raw_input()
kevin = 0
for i, c in enumerate(input_str):
if c.lower() in "aeiou":
kevin += len(input_str) - i
print kevin
Basically, iterate over each character, and if it is in the set of vowels, Kevin's score increases by the number of remaining characters in the string.
The remaining work should be rather obvious, I hope!
[stolen from the spoilers section of the site in question]
Because say for each consonant, you can make n substrings beginning with that consanant. So for the BANANA example look at the first B. With that B, you can make: B, BA, BAN, BANA, BANAN, BANANA. That's six substrings starting with that B or length(string) - indexof(character), which means that B adds 6 to the score. So you go through the string, looking for each consonant, and add length(string) - index to the score.
The problem here is your algorithm.You are finding all the Sub strings of the text. It takes exponential time to solve the problem. That's why you got run time errors here. You have to use another good algorithm to solve this problem rather than using sub strings.

Categories

Resources