Replacing a character in a string but it duplicate - python

This is a line of code I create that will replace a '_' with a character from a string
def test():
time = -1
in_time = 0
n = 'c__rd_nate'
new_n = ''
word = 'coordinate'
chr = 'i'
for w in word:
time = time + 1
if w == chr:
for i in n:
if in_time == time:
u = i.replace(i, chr)
new_n = new_n + u
in_time = in_time + 1
else:
in_time = in_time + 1
new_n = new_n + i
if len(word) == in_time:
break
Output:
>>>c__rdinate
But when applying the same rules for the duplicate character 'o' in word
def test():
time = -1
in_time = 0
n = 'c__rd_nate'
new_n = ''
word = 'coordinate'
chr = 'o'
for w in word:
time = time + 1
if w == chr:
for i in n:
if in_time == time:
u = i.replace(i, chr)
new_n = new_n + u
in_time = in_time + 1
else:
in_time = in_time + 1
new_n = new_n + i
if len(word) == in_time:
break
Output:
>>>co_rd_natec__rd_nate
I know what the error is but I'm stuck at creating a solution for this type of problem!
This is some more output in the same situation!
def test():
time = -1
in_time = 0
n = 'd__r'
new_n = ''
word = 'door'
chr = 'o'
for w in word:
time = time + 1
if w == chr:
for i in n:
if in_time == time:
u = i.replace(i, chr)
new_n = new_n + u
in_time = in_time + 1
else:
in_time = in_time + 1
new_n = new_n + i
if len(word) == in_time:
break
print(new_n)
test()
Output:
>>>do_rd__r

Converting the string to a list and then performing item assingment would be much more convenient.
This is a much more simplified way of constructing the code:
def test():
count = 0
n = list('c__rd_nate')
word = 'coordinate'
chr = 'o'
for w in word:
if w == chr:
n[count] = chr
count += 1
print(''.join(n))
output:
coord_nate
Edit:
If you would prefer to still keep the variable new_n then you can do something like this:
def test():
count = 0
n = list('c__rd_nate')
new_n = ''
word = 'coordinate'
chr = 'o'
for w in word:
if w == chr:
n[count] = chr
new_n = new_n + n[count]
count += 1
print(new_n)
output:
coord_nate

I think, you don't have to complicate too much. If you used indexing, problem can be solved with ease. If pattern matches, then concatenate that letter from variable "word" else concatenate from variable "n"
n = 'c__rd_nate'
new_n = ''
word = 'coordinate'
chr = 'o'
for i in range(len(word)):
if word[i] == chr:
new_n += word[i]
else:
new_n += n[i]
print(new_n)
This works for both 'o' and 'i'.
Output for 'o'
coord_nate
Output for 'i'
c__rdinate

def test():
n = 'doorian'
word = 'd__r_an'
ch = 'o'
return ''.join(_l if _l == '_' and word_l == ch else word_l
for word_l, _l in zip(word, n))
Or in cycle
def test():
n = 'doorian'
word = 'd__r_an'
ch = 'o'
res = ''
for word_l, _l in zip(word, n):
if _l == '_' and word_l == ch:
res += _l
else:
res += word_l
return res

Related

Using Python, how to print output string as -> aaa3bb2c1ddddd5 when Input string is aaabbcddddd

Using Python, how to print output string as -> aaa3bb2c1ddddd5 when Input string is aaabbcddddd
I want to concatenate actual character value and number of times a character is repeated in a string
def mycode(myString):
lenstr = len(myString)
print('length of string is '+str(lenstr));
for ele in myString:
count=0
for character in myString:
if character == ele:
count = count+1
totalstr = ele+str(count)
return totalstr
If the string is always sorted and grouped together like that, then you can use a collections.Counter to do it.
from collections import Counter
inp = "aaabbcddddd"
counter = Counter(inp)
out = "".join(k * v + str(v) for k,v in counter.items())
Or in one line:
print(''.join(k * v + str(v) for k,v in Counter(inp).items()))
Output:
aaa3bb2c1ddddd5
Or you can do it manually:
inp = "aaabbcddddd"
last = inp[0]
out = inp[0]
count = 1
for i in inp[1:]:
if i == last:
count += 1
else:
out += str(count)
count = 1
last = i
out += i
out += str(count)
print(out)
Here is a one line solution using a regex replacement with callback:
inp = "aaabbcddddd"
output = re.sub(r'((\w)\2*)', lambda m: m.group(1) + str(len(m.group(1))), inp)
print(output) # aaa3bb2c1ddddd5
Another one-liner:
import itertools
test = 'aaabbcddddd'
out = ''.join(f"{(g := ''.join(ig))}{len(g)}" for _, ig in itertools.groupby(test))
assert out == 'aaa3bb2c1ddddd5'
def char_counter_string(string):
prev_char = None
char_counter = 0
output = ''
for char_index in range(len(string)+1):
if char_index == len(string):
output += str(char_counter)
break
if string[char_index] != prev_char and prev_char is not None:
output += str(char_counter)
char_counter = 0
output += string[char_index]
char_counter += 1
prev_char = string[char_index]
return output
if __name__ == '__main__':
print(char_counter_string('aaabbcddddd'))
you can do like..
Code:
Time Complexity: O(n)
input_string="aaabbcddddd"
res=""
count=1
for i in range(1, len(input_string)):
if input_string[i] == input_string[i-1]:
count += 1
else:
res+=input_string[i-1]*count + str(count)
count = 1
res+=input_string[-1]*count + str(count)
print(res) #aaa3bb2c1ddddd5
Here's another way, ...
Full disclosure: ... as long as the run of characters is 10 or less, it will work. I.e., if there are 11 of anything in row, this won't work (the count will be wrong).
It's just a function wrapping a reduce.
from functools import reduce
def char_rep_count(in_string):
return reduce(
lambda acc, inp:
(acc[:-1]+inp+str(int(acc[-1])+1))
if (inp==acc[-2])
else (acc+inp+"1"),
in_string[1:],
in_string[0]+"1"
)
And here's some sample output:
print(char_rep_count("aaabbcdddd"))
aaa3bb2c1dddd4
I think this fulfils the brief and is also very fast:
s = 'aaabbcddddd'
def mycode(myString):
if myString:
count = 1
rs = [prev := myString[0]]
for c in myString[1:]:
if c != prev:
rs.append(f'{count}')
count = 1
else:
count += 1
rs.append(prev := c)
rs.append(f'{count}')
return ''.join(rs)
return myString

How to replace all "&int-int" with the respective string slices in an input string?

I have a school project question (for Python) that goes like this:
Given a string_input such as "abcd&1-4efg", the function must remove the "&1-4" and insert the string slice from 1 to 4 where the "&1-4" was.
eg. if string_input = "abcd&1-4efg",
"&1-4" is removed.
The remaining characters are indexed as follows: a=0, b=1, c=2, d=3, e=4, f=5, g=6
The new string becomes:
"abcdbcdeefg"
I've managed to write a long chunk of code to do this, but I'm wondering if anyone has any more efficient solutions?
Things to note:
The instructions can include double digits (eg. &10-15)
If the index isn't found, the returned string should print "?" for every missing index
(eg. "abcd&5-10efgh" would return "abcdfgh???efgh")
Intructions can be back-to-back (eg. "&10-15abcdef&1-5&4-5pqrs")
The code I've written is:
def expand(text):
text += "|"
import string
digits_dash = string.digits + "-"
idx_ref_str = ""
replace_list = []
record_val = False
output_to_list = []
instruct = ""
and_idx_mark = 0
#builds replace_list & idx_ref_list
for idx in range(len(text)):
if text[idx] == "&" and record_val==True:
output_to_list.append(instruct)
output_to_list.append(and_idx_mark)
replace_list.append(output_to_list)
output_to_list, instruct, inst_idx, and_idx_mark = [],"",0,0
and_idx_mark = idx
continue
elif text[idx] == "&":
record_val = True
and_idx_mark = idx
continue
#executes if currently in instruction part
if record_val == True:
#adds to instruct
if text[idx] in digits_dash:
instruct += text[idx]
#take info, add to replace list
else:
output_to_list.append(instruct)
output_to_list.append(and_idx_mark)
replace_list.append(output_to_list)
output_to_list, instruct, inst_idx, and_idx_mark, record_val = [],"",0,0,False
#executes otherwise
if record_val == False:
idx_ref_str += text[idx]
idx_ref_str = idx_ref_str[:-1]
text = text[:-1]
#converts str to int indexes in replace list[x][2]
for item in replace_list:
start_idx = ""
end_idx = ""
#find start idx
for char in item[0]:
if char in string.digits:
start_idx += char
elif char == "-":
start_idx = int(start_idx)
break
#find end idx
for char in item[0][::-1]:
if char in string.digits:
end_idx = char + end_idx
elif char == "-":
end_idx = int(end_idx)
break
start_end_list = [start_idx,end_idx]
item+=start_end_list
#split text into parts in list
count = 0
text_block = ""
text_block_list = []
idx_replace = 0
for char in text:
if char == "&":
text_block_list.append(text_block)
text_block = ""
count += len(replace_list[idx_replace][0])
idx_replace +=1
elif count > 0:
count -= 1
else:
text_block += char
text_block_list.append(text_block)
#creates output str
output_str = ""
for idx in range(len(text_block_list)-1):
output_str += text_block_list[idx]
#creates to_add var to add to output_str
start_repl = replace_list[idx][1]
end_repl = replace_list[idx][1] + len(replace_list[idx][0])
find_start = replace_list[idx][2]
find_end = replace_list[idx][3]
if end_idx >= len(idx_ref_str):
gap = end_idx + 1 - len(idx_ref_str)
to_add = idx_ref_str[find_start:] + "?" * gap
else:
to_add = idx_ref_str[find_start:find_end+1]
output_str += to_add
output_str += text_block_list[-1]
return output_str
Here's how I would do it. Always open to criticism.
import re
s = 'abcd&1-4efg'
c = re.compile('&[0-9]+-[0-9]+')
if (m := c.search(s)):
a, b = m.span()
left = s[:a]
right = s[b:]
o = [int(x) for x in m.group(0)[1:].split('-')]
mid = (left+right)[o[0]:o[1]+1]
print(left + mid + right)

Find the total number of occurrence of a string in a cyclic string

I'm currently learning Python and I'm stuck on this specific question.
Image
Here is my current code:
word = input()
text = 0
wordch = 0
positions = 0
repeated = 0
while repeated != 2:
for i in range(0, len(tablet)):
if tablet[i] == word[wordch]:
text += 1
wordch += 1
if text == len(word):
positions += 1
text = 0
wordch = 0
elif repeated == 1 and text == len(word):
positions += 1
text = 0
wordch = 0
break
elif i == len(tablet)-1:
repeated += 1
break
elif tablet[i] != word[wordch]:
text == 0
wordch == 0
print(positions)
I would hope for a code that is really basic using the same concepts but please do answer.
Thank you!
I have tried to solve the problem by using a different approach. As we know that we can only use (len(fav_word)) - 1 letters if we tried to create the substring in a cyclic manner from the end since if we took any more characters, we would have created them from the start itself without the cycle.
So, I just created a new string from the original string by appending the starting (len(fav_word)) - 1 to the original string and then find all occurrences of the fav_string in the new string.
def find_all(a_str, sub):
start = 0
while True:
start = a_str.find(sub, start)
if start == -1: return
yield start
start += 1
x = "cabccabcab"
fav = "abc"
y = x + x[0:len(fav)-1]
print(len(list(find_all(y, fav)))) # Output: 3
x = "ababa"
fav = "aba"
y = x + x[0:len(fav)-1]
print(len(list(find_all(y, fav)))) # Output: 2
x = "aaaaaa"
fav = "aa"
y = x + x[0:len(fav)-1]
print(len(list(find_all(y, fav)))) # Output: 6
x = "abaaba"
fav = "aaba"
y = x + x[0:len(fav)-1]
print(len(list(find_all(y, fav)))) # Output: 2
def find_str(g,find):
lg = len(g)
lf = len(find)
x=0
s=""
for index, i in enumerate(g):
if i == find[0]:
if index+lf <= lg:
s = "".join(g[index:index+lf])
if s == find:
x+=1
else:
rem = "".join(g[index:])
lr = len(rem)
for index,i in enumerate(g):
rem+=i
lr+=1
if lr == lf:
if rem == find:
x+=1
break
return x
print(find_str("abaaba","aaba"))
def split(word):
return [char for char in word]
x = "aaaaaa"
pattern = "aa"
mylist=split(x)
ok=True
occurrences=0
buffer=""
while ok:
char=mylist.pop(0)
buffer+=char
if buffer==pattern:
occurrences+=1
buffer=""
if len(mylist)==0:
ok=False
print(occurrences)
output:3

python caesar chr and ord without newline and just iterate in the alphabet

I have some problem with my caesar code.
1) I don't know how to check if a character is a punctuation and print without sum.
2) print the char on the same line but when it's finished return a newline.
3) Iterate through the alphabet with big number return me a punctuation, how can I do to return just a character?
import sys
import string
def main():
if len(sys.argv) != 2:
print("Usage: caesar.py k")
else:
k = int(sys.argv[1])
if k == 1 or k <= 26:
text = input("plaintext: ");
j = len(text)
for i in range(j):
#check if is a character
if text[i].isalpha:
if text[i].islower():
print(chr(ord(text[i]) + k),end = "")
if text[i].isupper():
print(chr(ord(text[i]) + k),end = "")
elif text[i].punctuation():
print(text[i])
else:
print("You have to introduce a number between 1 and 26")
main()
Try this code:
import string
def encrypt_ceasar(s, shift):
assert abs(shift) < 26, 'shift is between -25 and 25 (inclusive)'
encrypted_s = ''
for char in s:
if char.isalpha():
is_upper = char.isupper()
char = char.lower()
pos_alphabet = ord(char) - ord('a')
new_pos = (pos_alphabet + shift) % 26
encryted_char = chr(ord('a') + new_pos)
if is_upper:
encryted_char = encryted_char.upper()
encrypted_s += encryted_char
else:
encrypted_s += char
return encrypted_s
def decrypt_ceasar(s, shift):
return encrypt_ceasar(s, -shift)
if __name__ == "__main__":
s = 'AbC1$de#zy'
encrypted_s = encrypt_ceasar(s, 3)
print('s:', s)
print('encrypted_s:', encrypted_s)
print('again s:', decrypt_ceasar(encrypted_s, 3))
Output:
s: AbC1$de#zy
encrypted_s: DeF1$gh#cb
again s: AbC1$de#zy

Translating sentences into pig latin

SO i have this assignment to translate multiple words into pig latin. assume that the user will always input lowercase and only letters and spaces.
#----------------global variables
sentence = input("What do you want to translate into piglattin? ")
sentence = list(sentence)
sentence.insert(0, ' ')
length = len(sentence)
sentence.append(' ')
pigLattin = sentence
false = 0
true = 1
consonant = []
a = 0
b = 0
c = 0
d = 0
e = 0
f = 0
j = 0
x = 0
y = 0
#----------------main functions
def testSpace(sentence, i):
if sentence[i] == ' ':
a = true
else:
a = false
return a
def testVowel(sentence, i):
if sentence[i] == 'a' or sentence[i] == 'e' or sentence[i] == 'i' or sentence[i] == 'o' or sentence[i] == 'u' or sentence[i] == 'y':
b = true
else:
b = false
return b
def testStartWord(sentence, i):
x = 0
if sentence[i].isalpha() and sentence[i-1] == ' ':
c = true
x = 1
if x == 1 and sentence[i] != 'a' and sentence[i] != 'e' and sentence[i] != 'i' and sentence[i] != 'o' and sentence[i] != 'u' and sentence[i] != 'y':
c = true
else:
c = false
return c
def testWordEnd(sentence, i):
if sentence[i].isalpha() and sentence[i+1] == ' ':
d = true
else:
d = false
return d
#----------------main loop
for i in range(1,length):
x = 0
space = testSpace(sentence, i)
vowel = testVowel(sentence, i)
word = testStartWord(sentence, i)
end = testWordEnd(sentence, i)
if vowel == false and space == false and word == true:
e = i
consonant.append(sentence[i])
pigLattin.pop(e)
f = f + 1
if end == true:
consonant.append('a')
consonant.append('y')
consLength = len(consonant)
for x in range(consLength):
y = i + j - f
pigLattin.insert(y,consonant[x])
j = j + 1
del consonant[:]
pigLength = len(pigLattin)
for b in range (pigLength):
print(pigLattin[b], end='')
this is what i have so far. it gets kinda messy when trying to remove items. im sort of stuck here and its not working.
OK i got it working now this is an updated version
sentence = input("Please enter a sentence: ")
vowels = ("a", "e", "i", "o", "u", "A", "E", "I", "O", "U")
words = sentence.split()
count = 0
def find_vowel(word):
for i in range(len(word)):
if word[i] in vowels:
return i
return -1
for word in words:
vowel = find_vowel(word)
if(vowel == -1):
print(word, ' ', end='')
elif(vowel == 0):
print(word + "ay", ' ', end='')
else:
print(word[vowel:] + word[:vowel] + "ay", ' ', end='')
Instead of using testSpace eliminate the spaces by using sentence = sentence.split(). This will split all your words into strings in a list. Then iterate through the words in your list.
Instead of using testStartWord, use an if statement:
for word in sentence:
if word[0] in ["a","e","i","o","u"]:
word[:(len(word)-1)] = word[0]
#More Code...
At the end, where you print the output, use print sentence.join()
Here's an alternate version. I use a regular expression to find words in the input string, pass them to a callback function, and substitute them back into the original string. This allows me to preserve numbers, spacing and punctuation:
import re
import sys
# Python 2/3 compatibility shim
inp = input if sys.hexversion >= 0x3000000 else raw_input
VOWELS = set('aeiouyAEIOUY')
YS = set('yY')
def pig_word(word):
"""
Given a word, convert it to Pig Latin
"""
if hasattr(word, 'group'):
# pull the text out of a regex match object
word = word.group()
# find the first vowel and what it is
vowel, where = None, None
for i,ch in enumerate(word):
if ch in VOWELS:
vowel, where = ch, i
break
if vowel is None:
# No vowels found
return word
elif where == 0 and vowel not in YS:
# Starts with a vowel - end in 'way'
# (leading y is treated as a consonant)
return word + 'way'
else:
# Starts with consonants - move to end and follow with 'ay'
# check capitalization
uppercase = word.isupper() and len(word) > 1
titlecase = word[:1].isupper() and not uppercase
# rearrange word
word = word[where:] + word[:where] + 'ay'
# repair capitalization
if uppercase:
word = word.upper()
elif titlecase:
# don't use str.title() because it screws up words with apostrophes
word = word[:1].upper() + word[1:].lower()
return word
def pig_latin(s, reg=re.compile('[a-z\']+', re.IGNORECASE)):
"""
Translate a sentence into Pig Latin
"""
# find each word in the sentence, pass it to pig_word, and insert the result back into the string
return reg.sub(pig_word, s)
def main():
while True:
s = inp('Enter a sentence to translate (or Enter to quit): ')
if s.strip():
print(pig_latin(s))
print('')
else:
break
if __name__=="__main__":
main()
then
Enter a sentence to translate (or Enter to quit):
>>> Hey, this is really COOL! Let's try it 3 or 4 times...
Eyhay, isthay isway eallyray OOLCAY! Et'slay ytray itway 3 orway 4 imestay...

Categories