user = 'Peter'
location = 'Quahog'
friend = 'Stewie'
string = 'my name is %user% and i live in %location%, and my son is %friend%.'
The expected output would be
my name is Peter and i live in Quahog, and my son is Stewie.
The solution is expected to be O(N) time complexity, and there can any number of variables. The % symbols can also be inside words.
CodePudding user response:
I don't know why to do this, since there are functions ready for that, but... here it is, friend
def my_crazy_function(patterns:dict,text:str):
IDENTIFIER = '%'
inside_key = False
current_key = ''
generated_text = ''
for char in text:
if char == IDENTIFIER:
#means end the key
if inside_key:
#makes the replace
generated_text =patterns[current_key]
#flips to False
inside_key = False
#reset current key
current_key= ''
else:
#means start inside key
inside_key = True
#the "%" char is ignored on string
continue
if inside_key:
current_key =char
else:
generated_text =char
return generated_text
patterns ={
'user':'Peter',
'location':'Quahog',
'friend':'Stewie'
}
string = 'my name is %user% and i live in %location%, and my son is %friend%.'
r = my_crazy_function(patterns,string)
print(r)
CodePudding user response:
I see two ways of doing it (without using regex, or python string methods), depending if you can put the variables in a dict or not. If you can, I will do it like this:
variables = {
'user': 'Peter',
'location': 'Quahog',
'friend': 'Stewie'
}
string = 'my name is %user% and i live in %location%, and my son is %friend%.'
res = ''
pattern = None
for char in string:
if char == '%':
if pattern is None:
pattern = ''
else:
res = variables[pattern]
pattern = None
else:
if pattern is None:
res = char
else:
pattern = char
print(res)
The complexity is still O(N), because the string is iterated only once, and python dict get method is O(1).
Otherwise, if you are forced to use undeterminated independent variables, the solution will be like this:
user = 'Peter'
location = 'Quahog'
friend = 'Stewie'
string = 'my name is %user% and i live in %location%, and my son is %friend%.'
res = ''
pattern = None
for char in string:
if char == '%':
if pattern is None:
pattern = ''
else:
res = globals()[pattern]
pattern = None
else:
if pattern is None:
res = char
else:
pattern = char
print(res)
You should change the globals()[pattern]
to locals()[pattern]
if the variables are defined inside the function. In the case you dont know where the variables are defined, you can use eval(pattern)
, but i dont recomend that option, because enables code execution inside %%.
CodePudding user response:
The code below uses eval
to find target variables. However, it should be carefully used because the use of eval
can be problematic in many cases.
The phrase %%
results in EOF error in this code. If you don't want it, check (idx_start 1) == idx_end
.
user = 'Peter'
location = 'Quahog'
friend = 'Stewie'
string = 'my name is %user% and i live in %location%, and my son is %friend%.'
idx_start = None
idx_end = None
string_new = ''
for idx, ch in enumerate(string):
if ch != '%':
if idx_start is None:
string_new = string_new ch
else:
if idx_start is None:
idx_start = idx
else:
idx_end = idx
string_new = eval(string[idx_start 1:idx_end])
idx_start = None
idx_end = None
string_new
> 'my name is Peter and i live in Quahog, and my son is Stewie.'
CodePudding user response:
Do not worry. Gilfoyle is here to help you out.
vocab_dict = {"user" : 'Peter',
"location" : 'Quahog',
"friend" : 'Stewie'}
sentence = 'my name is %user% and i live in %location%, and my son is %friend%.'
def fill_sentence(sentence, vocab_dict):
special_char = "%"
odd_flag = False
word_found = ""
generate_op = ""
for char_i in sentence:
if char_i == special_char and not odd_flag:
odd_flag = True
continue
elif char_i == special_char and odd_flag:
generate_op = vocab_dict[word_found]
odd_flag = False
word_found = ""
continue
elif odd_flag:
word_found = char_i
else:
generate_op = char_i
return generate_op
fill_sentence(sentence, vocab_dict)
Output :
my name is Peter and i live in Quahog, and my son is Stewie.
CodePudding user response:
You can use globals()
or replace all % ... %
with { ... }
and treat this string as a f-string
and use all of the variables.
import re
string = 'my name is %user% and i live in %location%, and my son is %friend%.'
# approach_1
user = 'Peter'
location = 'Quahog'
friend = 'Stewie'
app1 = re.sub(r'%([^%]*)%', lambda x: globals()[x.group(0)[1:-1]], string)
print(app1)
# approach_2
dct = {'user':'Peter', 'location':'Quahog', 'friend':'Stewie'}
rep_chr = re.sub(r'%([^%]*)%', r'{\1}', string)
print(rep_chr)
# my name is {user} and i live in {location}, and my son is {friend}.
print(rep_chr.format(**dct))
print(eval("f'{}'".format(rep_chr)))
Output:
my name is Peter and i live in Quahog, and my son is Stewie.