Robber's language backwards? - python

does anyone know how to translate robber's languge to English in python?
like this one but in reverse?
def translate(s):
consonants = 'bcdfghjklmnpqrstvwxz'
return ''.join(a + 'o' + a if a in consonants else a for a in s)
print(translate("hej"))

Maybe something like:
def translate(s):
consonants = 'bcdfghjklmnpqrstvwxz'
counter = 0
outputcounter = 0
output = s
while counter < len(s):
char = s[counter]
if char in consonants:
output = output[:outputcounter] + char + output[outputcounter + 3:]
counter += 3
outputcounter += 1
else:
counter += 1
outputcounter += 1
return output
Try it out! (I don't know if that's nice code style, but however)

Here is an alternative approach
Since this is an interesting problem, I decided to have a go myself. Here is an efficient way of writing your first function with O(1) set lookup:
def translate_english_robber(s):
consonants = 'bcdfghjklmnpqrstvwxz'
# using a set instead is more efficient
lookup = set(consonants + consonants.upper())
result = ""
for char in s:
if char in lookup:
# anonymous function for converting the case of the letter "o"
convert_case = lambda x: "o" if x.islower() else "O"
# add it to the result
result += char + convert_case(char) + char
else:
result += char
return result
Then for the reverse translation, all you need to do is find a consonant, and append it to the list, then somehow remove the next 2 characters, and continue the next iteration after the last removed character. Otherwise, if the current character is not a constant, add it normally.
For example, If my Robbers language was "hohey", I would first find "h", add it, and remove "o" and "h" after that, then start iterating from "e". In the end, we would have "hey" as the English translation.
Using an iterator would be useful here. You can also read up on iterators here, they are quite useful for problems like this.
Here is my attempt:
def translate_robber_english(s):
consonants = 'bcdfghjklmnpqrstvwxz'
lookup = set(consonants + consonants.upper())
# create the iterator
it = iter(list(s))
result = ""
# loop till we reach the end
while True:
try:
# get the current letter
current = next(it)
# add it regardless
result += current
# if consonant, skip the next to letters
if current in lookup:
next(it)
next(it)
# If this exception occurs, break out of the loop
except StopIteration:
break
return result
And now you can get the reverse translations with both the above functions:
>>> robber = translate_english_robber("black")
>>> print(robber)
boblolacockok
>>> english = translate_robber_english(robber)
>>> print(english)
black

You can try something like this:
def reverse_translate(s):
vowel = ['a', 'e', 'i', 'o', 'u']
final = []
for i in range(len(s)):
if s[i] in vowel:
final.append(s[i])
else:
try:
if s[i] == s[i + 2]:
final.append(s[i:i + 3])
except IndexError:
pass
for j, i in enumerate(final):
if i == 'o':
try:
if final[j] == final[j + 1]:
pass
else:
del final[j]
except IndexError:
del final[j]
return "".join(list(map(lambda x: x[0], final)))
Now test_cases:
Normal test_case:
print(reverse_translate('boblolacockok'))
output:
black
But if text also include 'o' as vowel now :
print(reverse_translate('boblolocockok'))
output:
block

Related

remove consecutive substrings from a string without importing any packages

I want to remove consecutive "a" substrings and replace them with one "a" from a string without importing any packages.
For example, I want to get abbccca from aaabbcccaaaa.
Any suggestions?
Thanks.
This method will remove a determined repeated char from your string:
def remove_dulicated_char(string, char):
new_s = ""
prev = ""
for c in string:
if len(new_s) == 0:
new_s += c
prev = c
if c == prev and c == char:
continue
else:
new_s += c
prev = c
return new_s
print(remove_dulicated_char("aaabbcccaaaa", "a"))
Whats wrong with using a loop?
oldstring = 'aaabbcccaaaa'
# Initialise the first character as the same as the initial string
# as this will always be the same.
newstring = oldstring[0]
# Loop through each character starting at the second character
# check if the preceding character is an a, if it isn't add it to
# the new string. If it is an a then check if the current character
# is an a too. If the current character isn't an a then add it to
# the new string.
for i in range(1, len(oldstring)):
if oldstring[i-1] != 'a':
newstring += oldstring[i]
else:
if oldstring[i] != 'a':
newstring += oldstring[i]
print(newstring)
using python regular expressions this will do it.
If you don't know about regex. They are extremely powerful for
this kind of matching
import re
str = 'aaabbcccaaaa'
print(re.sub('a+', 'a', str))
You can use a function that removes double values of a string occurrence recursively until only one occurrence of the repeating string remains:
val = 'aaabbcccaaaaaaaaaaa'
def remove_doubles(v):
v = v.replace('aa', 'a')
if 'aa' in v:
v = remove_doubles(v)
if 'aa' in v:
v = remove_doubles(v)
else: return v
else: return v
print(remove_doubles(val))
There are many ways to do this. Here's another one:
def remove_duplicates(s, x):
t = [s[0]]
for c in s[1:]:
if c != x or t[-1] != x:
t.append(c)
return ''.join(t)
print(remove_duplicates('aaabbcccaaaa', 'a'))

How to combine all function togetger

I want to make a function that can show first char, last char, count of char, and count of vowels from a string, so I make this
> def text(a):
> result = a[0]
> return result;
> def text (a):
> result = a[-1]
> return result
> def text(a):
> result= text.len(original_str)
> return result
> vowels = {'a','e','i','o','u'}
> text = "a"
> for a in my_string:
> if a in vowels:
> len(a)
> Text("American")
Expected out put
first_char = A
Last_char = n
num_char = 8
num_vowels = 4
how to make the function working at one time when I put the "text"
hope you all can help
You don't want to write a different function each time. Just include all of the things you want to find inside one function.
def Text(a):
first_char = a[0]
last_char = a[-1]
num_char = len(a)
num_vowels = sum([l in "aeiou" for l in a.lower()])
print("first_char:", first_char)
print("last_char:", last_char)
print("num_char:", num_char)
print("num_vowels:", num_vowels)
Text("American")
Output:
first_char: A
last_char: n
num_char: 8
num_vowels: 4
It looks like you're quite new to python, so I've made the following longer than necessary to allow for comments and clarity. The key point is to identify all the things you want your function to return and then make sure you get them, then return everything at once.
def text(a):
first = a[0] #Store first element in string
last = a[-1] #Store last element in string
length = len(a) #Store length of string
nVowel = 0 #Variable to count vowels
vowels = {'a','e','i','o','u'} #Set of vowels
for s in a.lower(): #Loop over all characters in lower case
if s in vowels: #Check if character is a vowel
nVowel += 1 #Add to count if vowel
return (first, last, length, nVowel) #Return results
print(text("American"))
This can be made significantly shorter, but I'll leave that to you as an opportunity to practice and understand what's going on.
You can execute them all in one function, and simply return all the values in a big chunk. The main problem with your original code is that not only does the code not work to well to begin with, but you are constantly overwriting your function. Also your vowels were represented with braces {} instead of square brackets [], which are used in python.
def Text(string):
# Calculate
first = string[0]
last = string[-1]
length = len(string)
vowels = sum([string.lower().count(v) for v in ["a", "e", "i", "o", "u"]])
# Return
return first, last, length, vowels
first_char, last_char, num_char, num_vowels = Text("American") # Or for any other string

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 to remove Triplicate Letters in Python

So I'm a little confused as far as putting this small code together. My teacher gave me this info:
Iterate over the string and remove any triplicated letters (e.g.
"byeee mmmy friiiennd" becomes "bye my friennd"). You may assume any
immediate following same letters are a triplicate.
I've mostly only seen examples for duplicates, so how do I remove triplicates? My code doesn't return anything when I run it.
def removeTriplicateLetters(i):
result = ''
for i in result:
if i not in result:
result.append(i)
return result
def main():
print(removeTriplicateLetters('byeee mmmy friiiennd'))
main()
I have generalized the scenario with "n". In your case, you can pass n=3 as below
def remove_n_plicates(input_string, n):
i=0
final_string = ''
if not input_string:
return final_string
while(True):
final_string += input_string[i]
if input_string[i:i+n] == input_string[i]*n:
i += n
else:
i += 1
if i >= len(input_string):
break
return final_string
input_string = "byeee mmmy friiiennd"
output_string = remove_n_plicates(input_string, 3)
print(output_string)
# bye my friennd
You can use this for any "n" value now (where n > 0 and n < length of input string)
Your code returns an empty string because that's exactly what you coded:
result = ''
for i in result:
...
return result
Since result is an empty string, you don't enter the loop at all.
If you did enter the loop you couldn't return anything:
for i in result:
if i not in result:
The if makes no sense: to get to that statement, i must be in result
Instead, do as #newbie showed you. Iterate through the string, looking at a 3-character slice. If the slice is equal to 3 copies of the first character, then you've identified a triplet.
if input_string[i:i+n] == input_string[i]*n:
Without going in to writing the code to resolve the problem.
When you iterate over the string, add that iteration to a new string.
If the next iteration is the same as the previous iteration then do not add that to the new string.
This will catch both the triple and the double characters in your problem.
Tweaked a previous answer to remove a few lines that were not needed.
def remove_n_plicates(input_string, n):
i=0
result = ''
while(True):
result += input_string[i]
if input_string[i:i+n] == input_string[i]*n:
i += n
else:
i += 1
if i >= len(input_string):
break
return result
input_string = "byeee mmmy friiiennd"
output_string = remove_n_plicates(input_string, 3)
print(output_string)
# bye my friennd
Here's a fun way using itertools.groupby:
def removeTriplicateLetters(s):
return ''.join(k*(l//3+l%3) for k,l in ((k,len(list(g))) for k, g in groupby(s)))
>>> removeTriplicateLetters('byeee mmmy friiiennd')
'bye my friennd'
just modifying #newbie solution and using stack data structure as solution
def remove_n_plicates(input_string, n):
if input_string =='' or n<1:
return None
w = ''
c = 0
if input_string!='':
tmp =[]
for i in range(len(input_string)):
if c==n:
w+=str(tmp[-1])
tmp=[]
c =0
if tmp==[]:
tmp.append(input_string[i])
c = 1
else:
if input_string[i]==tmp[-1]:
tmp.append(input_string[i])
c+=1
elif input_string[i]!=tmp[-1]:
w+=str(''.join(tmp))
tmp=[input_string[i]]
c = 1
w+=''.join(tmp)
return w
input_string = "byeee mmmy friiiennd nnnn"
output_string = remove_n_plicates(input_string, 3)
print(output_string)
output
bye my friennd nn
so this is a bit dirty but it's short and works
def removeTriplicateLetters(i):
result,string = i[:2],i[2:]
for k in string:
if result[-1]==k and result[-2]==k:
result=result[:-1]
else:
result+=k
return result
print(removeTriplicateLetters('byeee mmmy friiiennd'))
bye my friennd
You have already got a working solution. But here, I come with another way to achieve your goal.
def removeTriplicateLetters(sentence):
"""
:param sentence: The sentence to transform.
:param words: The words in the sentence.
:param new_words: The list of the final words of the new sentence.
"""
words = sentence.split(" ") # split the sentence into words
new_words = []
for word in words: # loop through words of the sentence
new_word = []
for char in word: # loop through characters in a word
position = word.index(char)
if word.count(char) >= 3:
new_word = [i for i in word if i != char]
new_word.insert(position, char)
new_words.append(''.join(new_word))
return ' '.join(new_words)
def main():
print(removeTriplicateLetters('byeee mmmy friiiennd'))
main()
Output: bye my friennd

Optimize beginner python script about substring replacement

I'm tutoring a friend in python, not great at it myself. The assignment is to write a script that reverses some made up alien language in which they repeat every vowel-sequence after adding the letter "p". Some examples:
tomato -> topomapatopo groovy->groopoovy and beautiful -> beaupeautipifupul
The goal is to reverse this. From groopoovy -> groovy.
As it is a dutch assignment, there is an exception: "ij" is seen as a vowel. So blijpij -> blij (which complicates things a lot, I find)
My solution seems quite bulky to me and I am interested in a better, more elegant solution. As this is an introduction course to programming, basics are key, unfortunately.
word = input()
vowels = ('a', 'e', 'i', 'o', 'u')
position = 0
solution = ""
while position < len(word):
if word[position] == 'p': # obviously, search for the letter 'p'
add = 1 # keep track of the sub string size
group = ""
while True: # loop to get consecutive vowels
if word[position + add] in vowels:
group += word[position + add]
if word[position + add] == 'i' and word[position + add + 1] == 'j': # recognize the "ij"
group += 'j'
add += 1
add += 1
else:
break
if position+add == len(word): # stay within the bounds of the string
break
add -= 1
if word[position - add:position].lower() == group.lower() and group != "":
position += add
else:
solution += 'p'
else:
solution += word[position]
position += 1
print(solution)
How about this, for an introductory Python class.
There are several example words at the top; just change the comments #.
Instead of checking for "p" on every step, I check for the beginning of a vowel sequence. This sequence will always be terminated by "p". That's the only case where you don't want to append the character to the solution; instead you want to skip to the end of the vowel sequence.
The fact that "ij" is a vowel doesn't create a special case, since "i" begins a vowel sequence.
word = "poopoo-poopoo"
# word = "poopooh"
# word = "hijipijinks"
# word = "apapepe"
# word = "copovfepefepe"
vowels = ('a', 'e', 'i', 'o', 'u')
position = 0
solution = ""
vowel_count = 0 # consecutive vowels
while position < len(word):
c = word[position]
if vowel_count > 0:
if c == 'p':
position += vowel_count + 1
vowel_count = 0
continue
vowel_count += 1
else:
if c in vowels:
vowel_count = 1
solution += c
position += len(c)
print(solution)
import re
input_text = "tomato"
encoded = re.sub('([aeiou]+)','\\1p\\1',input_text)
print(encoded)
decoded = re.sub('([aeiou]+)p\\1','\\1',encoded)
print(decoded)
should do just that

Categories

Resources