I am trying to make a function that automatically generated a response to a selection of an action in a text adventure game. My problem is that I have to replace every second '_' with ' '. However I have tried everything I have though of and whenever I google the question the only solution I get is to use .replace(). However .replace() replaces every instance of that character. Here is my code, could you please fix this for me and explain how you fixed it.
example_actions = ['[1] Search desk', '[2] Search Cupboard', '[3] Search yard'
def response(avaliable_actions):
for i in avaliable_actions:
print(i, end=' ')
x = avaliable_actions.index(i)
avaliable_actions[x] = avaliable_actions[x][4:]
avaliable_actions = ' '.join(avaliable_actions)
avaliable_actions = avaliable_actions.lower()
avaliable_actions = avaliable_actions.replace(' ', '_')
avaliable_actions = list(avaliable_actions)
count = 0
for i in avaliable_actions:
if count == 2:
count = 0
index = avaliable_actions.index(i)
avaliable_actions[index] = ' '
elif i == '_':
count += 1
avaliable_actions = ' '.join(avaliable_actions)
print('\n\n' + str(avaliable_actions)) #error checking
Here's one approach:
s = 'here_is_an_example_of_a_sentence'
tokens = s.split('_')
result = ' '.join('_'.join(tokens[i:i+2]) for i in range(0,len(tokens),2))
print(result)
The result:
here_is an_example of_a sentence
Did I understand you correct, that you wanna produce something like this?
this_is_a_test -> this is_a test or this_is a_test?
If so, adapt the following for your needs:
s = "this_is_just_a_test"
def replace_every_nth_char(string, char, replace, n):
parts = string.split(char)
result = ""
for i, part in enumerate(parts):
result += part
if i % n == 0:
result += replace
else:
result += char
return ''.join(result)
res = replace_every_nth_char(s, "_", " ", 2)
print(s, "->", res)
# "this_is_just_a_test" -> "this is_just a_test"
Related
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
Not allowed to use "Split(),Reverse(),Join() or regexes" or any other
helping inbuilt python function
input something like this:
" my name is scheven "
output like this:
"ym eman si nevehcs"
you need to consider removing the starting,inbetween,ending spaces aswell in the input
I have tried 2 tries, both failed i will share my try to solve this and maby an idea to improve it
First try:
def reverseString(someString):
#lenOfString = len(someString)-1
emptyList = []
for i in range(len(someString)):
emptyList.append(someString[i])
lenOfString = len(emptyList)-1
counter = 0
while counter < lenOfString:
if emptyList[counter] == " ":
counter+=1
if emptyList[lenOfString] == " ":
lenOfString-=1
else:
swappedChar = emptyList[counter]
emptyList[counter] = emptyList[lenOfString]
emptyList[lenOfString] = swappedChar
counter+=1
lenOfString-=1
str_contactantion = ""
#emptyList = emptyList[::-1]
#count_spaces_after_letter=0
for letter in emptyList:
if letter != " ":
str_contactantion+=letter
#str_contactantion+=" "
str_contactantion+=" "
return str_contactantion
second try:
def reverse(array, i, j):
emptyList = []
if (j == i ):
return ""
for k in range(i,j):
emptyList.append(array[k])
start = 0
end = len(emptyList) -1
if start > end: # ensure i <= j
start, end =end, start
while start < end:
emptyList[start], emptyList[end] = emptyList[end], emptyList[start]
start += 1
end -= 1
strconcat=""
for selement in emptyList:
strconcat+=selement
return strconcat
def reverseStr(someStr):
start=0
end=0
help=0
strconcat = ""
empty_list = []
for i in range(len(someStr)):
if(someStr[i] == " "):
continue
else:
start = i
j = start
while someStr[j] != " ":
j+=1
end = j
#if(reverse(someStr,start,end) != ""):
empty_list.append(reverse(someStr,start,end))
empty_list.append(" ")
for selement in empty_list:
strconcat += selement
i = end + 1
return strconcat
print(reverseStr(" my name is scheven "))
The following works without managing indices:
def reverseString(someString):
result = crnt = ""
for c in someString:
if c != " ":
crnt = c + crnt # build the reversed current token
elif crnt: # you only want to do anything for the first space of many
if result:
result += " " # append a space first
result += crnt # append the current token
crnt = "" # and reset it
if crnt:
result += " " + crnt
return result
reverseString(" my name is scheven ")
# 'ym eman si nevehcs'
Try this:
def reverseString(someString):
result = ""
word = ""
for i in (someString + " "):
if i == " ":
if word:
result = result + (result and " ") + word
word = ""
else:
word = i + word
return result
You can then call it like this:
reverseString(" my name is scheven ")
# Output: 'ym eman si nevehcs'
Try this:
string = " my name is scheven "
def reverseString(someString):
result = ''
curr_word = ''
for i in someString:
if i == ' ':
if curr_word:
if result:
result = f'{result} {curr_word}'
else:
result = f'{result}{curr_word}'
curr_word = ''
else:
curr_word = f'{i}{curr_word}'
return result
print(repr(reverseString(string)))
Output:
'ym eman si nevehcs'
Note: if you're allowed to use list.append method, I'd suggest using a collections.deque as it's more performant than appending to a list. But of course, in the end you'll need to join the list together, and you mentioned that you're not allowed to use str.join, so that certainly poses an issue.
I have a function in which I need to inject a character before every odd index of a string.
def inject(s, i):
sent = str(s)
new = []
for w in sent:
if w == ' ':
new.append(w)
elif (sent.index(w) % 2 == 1):
new.append(str(i) + w)
else:
new.append(w)
return ''.join(new)
The function works for:
inject(1339, 3)
output: '1333339'
and works for
inject('This is a test', 'x')
output: 'Txhixs ixs a txexst'
but won't work for:
inject('Hello World', 'x')
output: 'Hxello World'
I know it has something to do with it breaking on the 'll' but can't figure out how to fix it.
Thanks!
I think you meant to do this:
def inject(s, i):
sent = str(s)
new = []
for idx,w in enumerate(sent):
if w == ' ':
new.append(w)
elif idx % 2 == 1:
new.append(str(i) + w)
else:
new.append(w)
return ''.join(new)
for t in [1339, 'This is a test', 'Hello World']:
print(t, inject(t,'x'))
When using the enumerate() you get the index of each character without having to search for it.
The sent.index(w) call just doesn't do what you want it to even though it might seem like it does when there are no repeated characters in a string.
I want to remove extra spaces in a string using only for/while loops, and if statements; NO split/replace/join.
like this:
mystring = 'Here is some text I wrote '
while ' ' in mystring:
mystring = mystring.replace(' ', ' ')
print(mystring)
output:
Here is some text I wrote
Here's what I tried. Unfortunately, it doesn't quite work.
def cleanupstring(S):
lasti = ""
result = ""
for i in S:
if lasti == " " and i == " ":
i = ""
lasti = i
result += i
print(result)
cleanupstring("Hello my name is joe")
output:
Hello my name is joe
My attempt doesn't remove all the extra spaces.
Change your code to this:
for i in S:
if lasti == " " and i == " ":
i = ""
else:
lasti = i
result += i
print(result)
Check that the current character and the next one are spaces, and if not, add them to a clean string. There really is no need for an and in this case, since we are comparing to the same value
def cleanWhiteSpaces(str):
clean = ""
for i in range(len(str)):
if not str[i]==" "==str[i-1]:
clean += str[i]
return clean
Uses the end of result in place of lasti:
def cleanupstring(S):
result = S[0]
for i in S[1:]:
if not (result[-1] == " " and i == " "):
result += i
print(result)
cleanupstring("Hello my name is joe")
Just try this
t = "Hello my name is joe"
" ".join(t.split())
this will output
"Hello my name is joe"
I'm trying to write a function that will translate the input into so-called "cow Latin." I want to return the values from the if statement but whenever I do I get a syntax error. I can print the value but I want to avoid the function returning None as well.
def cow_latinify_sentence(sentence):
vowels = tuple('aeiou1234567890!##$%^&*()-_=+|\\][}{?/.\',><`~"')
sentence = sentence.lower()
sentence_list = sentence.split()
for i in range(len(sentence_list)):
cow_word = sentence_list[i][:]
if cow_word.startswith(vowels):
print('{0}moo'.format(cow_word), end=' ')
else:
cow_word = sentence_list[i][1:] + sentence_list[i][:1]
print('{0}oo'.format(cow_word), end=' ')
cow_latin = cow_latinify_sentence("the quick red fox")
print(cow_latin)
In short, how can I get the function to return instead of print?
def cow_latinify_sentence(sentence):
vowels = tuple('aeiou1234567890!##$%^&*()-_=+|\\][}{?/.\',><`~"')
sentence = sentence.lower()
sentence_list = sentence.split()
result = ''
for i in range(len(sentence_list)):
cow_word = sentence_list[i][:]
if cow_word.startswith(vowels):
result += ('{0}moo'.format(cow_word) + ' ')
else:
result += '{0}oo'.format(sentence_list[i][1:] + sentence_list[i][:1]) + ' '
return result.strip()
>>> cow_latinify_sentence('hello there i am a fish')
'ellohoo heretoo imoo ammoo amoo ishfoo'
Why not just replace the two instances of
print('{0}moo'.format(cow_word), end=' ')
with
return '{0}moo'.format(cow_word)+' '
You have to get rid of end=; you don't have to replace the newline that would otherwise follow the output of print, but if you want a space at the end of the returned string you still have to append it yourself.
You need to create a list to accumulate your results.
result = []
your two print statements in your function would need changed to result.append(XXXX). Then when you have processed the entire sentence you can
return (result)
or, to re-form it into a sentence:
return " ".join(result) + '.'
def cow_latinify_sentence(sentence):
vowels = tuple('aeiou1234567890!##$%^&*()-_=+|\\][}{?/.\',><`~"')
sentence = sentence.lower()
sentence_list = sentence.split()
result = ''
for i in range(len(sentence_list)):
cow_word = sentence_list[i][:]
if cow_word.startswith(vowels):
result += '{0}moo'.format(cow_word) + ' '
else:
result += '{0}oo'.format(sentence_list[i][1:] + sentence_list[i][:1]) + ' '
return result.strip()