Python reverse each word in a sentence without inbuilt function python while preserve order - python

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.

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 function does not display desired string

Hey so I am doing a project that is supposed to be a word search calculator. The word search is a 10x10 list of characters turned into rows of characters. I did a .find function for my check forward, however it is not working correctly. I will provide my get puzzle function, my check forward and what the output should be (ignore the format of the puzzle for output).
def input_puzzle():
print("Puzzle:\n")
puzzle_input = input()
puzzle_list = []
for i in range(10):
row = ""
for j in range(10):
row += puzzle_input[i*10 + j]
puzzle_list.append(row)
return puzzle_list
def check_forward(puzzle_list, word, direction):
for row in range(len(puzzle_list)):
row_string = puzzle_list[row]
finder = row_string.find(word)
if finder > 0:
print(word + ":" + direction + "row:" + row, "column:", finder) # finder is the indeci in row #+ means right after and comma means space
return True
else:
print(word + ": word not found")
return False
"""
Puzzle:
WAQHGTTWEE
CBMIVQQELS
APXWKWIIIL
LDELFXPIPV
PONDTMVAMN
OEDSOYQGOB
LGQCKGMMCT
YCSLOAPUZM
XVDMGSXCYZ
UUIUNIXFNU
UNIX: (FORWARD) row: 9 column: 3
"""
The following code works
def input_puzzle():
print("Puzzle:\n")
puzzle_input = input()
puzzle_input = puzzle_input.strip()
puzzle_list = []
for i in range(10):
row = ""
for j in range(10):
row += puzzle_input[i*11 + j]
puzzle_list.append(row)
return puzzle_list
def check_forward(puzzle_list, word, direction):
for row in range(len(puzzle_list)):
row_string = puzzle_list[row]
finder = row_string.find(word)
if finder > 0:
print("{}: ({}) row: {} column: {}".format(word, direction, str(row), str(finder)))
return True
else:
continue
print(word + ": word not found")
print(check_forward(input_puzzle(), 'UNIX', 'FORWARD'))
# UNIX: (FORWARD) row: 9 column: 3

Rosalind Consensus and Profile Problem code doesn't work

This is the problem: http://rosalind.info/problems/cons/
def file_read(fname):
with open(fname, "r") as myfile:
global data
data = myfile.readlines()
print(data)
i = 0
while i < len(data):
data[i] = data[i].replace("\n", "")
if ">" in data[i]:
data.remove(data[i])
else:
i += 1
file_read('rosalind_cons.txt')
res = ["".join(el) for el in zip(*data)]
print(res)
a_str = ""
c_str = ""
g_str = ""
t_str = ""
for x in range(0, len(res)):
a_str += (str(res[x].count("A"))) + " "
for x in range(0, len(res)):
c_str += (str(res[x].count("C"))) + " "
for x in range(0, len(res)):
g_str += (str(res[x].count("G"))) + " "
for x in range(0, len(res)):
t_str += (str(res[x].count("T"))) + " "
a_str_nospace = a_str.replace(" ", "")
c_str_nospace = c_str.replace(" ", "")
g_str_nospace = g_str.replace(" ", "")
t_str_nospace = t_str.replace(" ", "")
consensus_string = ""
for x in range(0, len(a_str_nospace)):
if max(a_str_nospace[x], c_str_nospace[x], g_str_nospace[x], t_str_nospace[x]) in a_str_nospace[x]:
consensus_string += "A"
elif max(a_str_nospace[x], c_str_nospace[x], g_str_nospace[x], t_str_nospace[x]) in c_str_nospace[x]:
consensus_string += "C"
elif max(a_str_nospace[x], c_str_nospace[x], g_str_nospace[x], t_str_nospace[x]) in g_str_nospace[x]:
consensus_string += "G"
elif max(a_str_nospace[x], c_str_nospace[x], g_str_nospace[x], t_str_nospace[x]) in t_str_nospace[x]:
consensus_string += "T"
print(consensus_string)
print("A: " + a_str)
print("C: " + c_str)
print("G: " + g_str)
print("T: " + t_str)
What's wrong with my code?
For the sample output it works but for the larger datasets it doesn't.
I don't know what is wrong, I think it's the file reading part that's not correct (maybe?)
EDIT: There are some print functions in there but I don't copy them in the answer box so they don't matter in the result
nice to see a fellow Rosalind user. I discovered that page when I studied Bioinformatics and just stumbled upon it again last month.
To answer your question:
You're creating a string of numbers, so that works fine if the numbers are all below 10.
Try building a list of integers first and only convert them to a string in the final step.

List prints square brackets in python 2.7

import sys
import string
import re
keywords = []
task = "*"
while task not in "ed":
task = raw_input("Encrypt or Decrypt: \nType ‘e’ to Encrypt\nType ‘d’ to Decrypt\n").lower()
keyword = "*"
keyphrase = "*"
while not(re.match('[a-z ]+$',keyword)):
keyword = raw_input("enter your first keyword:-").lower()
while not(re.match('[a-z ]+$',keyphrase)):
keyphrase = raw_input("enter a key phrase:-").lower()
loop = 0
repeated_keyword = ""
if len(keyword) < len(keyphrase):
while len(repeated_keyword) < len(keyphrase):
repeated_keyword = repeated_keyword + keyword[loop]
loop += 1
if loop >= len(keyword):
loop = 0
elif len(keyword) == len(keyphrase):
repeated_keyword = keyword
last_charecter_in_keyword = keyword[-1]
elif len(keyword) > len(keyphrase):
repeated_keyword = keyword
last_charecter_in_keyword = keyword[-1]
while len(repeated_keyword) > len(keyphrase):
repeated_keyword = repeated_keyword[:-1]
repeated_keyword_letter_positions = []
keyphrase_letter_positions = []
for character in repeated_keyword:
position_of_char_in_repeated_keyword = (string.ascii_lowercase + " ").find(character) +1
repeated_keyword_letter_positions.append(position_of_char_in_repeated_keyword)
for character in keyphrase:
position_of_char_in_keyphrase = (string.ascii_lowercase + " ").find(character)
keyphrase_letter_positions.append(position_of_char_in_keyphrase)
if task == "e":
final_positions_of_letters = [a + b for a, b in zip(keyphrase_letter_positions,repeated_keyword_letter_positions)]
elif task == "d":
final_positions_of_letters = [a - b for a, b in zip(keyphrase_letter_positions,repeated_keyword_letter_positions)]
new_letter = ""
final_cipher = []
loop = 0
alphabet = string.ascii_lowercase + " " + string.ascii_lowercase + " "
while loop < len(final_positions_of_letters):
new_letter =alphabet[final_positions_of_letters[loop]]
final_cipher = str(final_cipher) + str(new_letter)
loop += 1
print final_cipher
This is a encryption/ decryption programme in python 2.7. However at the end of the programme when the final_cipher list is printed to the shell a pair of [] brackets are printed prior to the contents of the list
You have some options here:
• Loop through the array, and print each element on the same row without delimiter.
• Use 'join' to join all the parts of the array in a single string. You can find more information about the join statement here.
Personally I do think 'join' is the best option here.
I guess you are trying to output a string. And you are making a mistake by setting the initial declaration to an empty list.
For fixing this just use :
final_cipher = "" instead of final_cipher = []
This should get you the output in string format.
Seeing:
final_cipher = []
loop = 0
alphabet = string.ascii_lowercase + " " + string.ascii_lowercase + " "
while loop < len(final_positions_of_letters):
new_letter =alphabet[final_positions_of_letters[loop]]
final_cipher = str(final_cipher) + str(new_letter)
loop += 1
print final_cipher
I see that you are working with final_cipher like a string, then you should initialize like:
final_cipher = ""
And:
final_cipher = str(final_cipher) + str(new_letter)
Should be:
final_cipher = final_cipher + str(new_letter)
Or better:
final_cipher += str(new_letter)
final_cipher is a list, so yes, printing it will print it as a string, i.e. the result of calling str(final_cipher).
If you want to just print the elements seperated by a comma, you can use .join:
print ", ".join(final_cipher)
You create final_cipher as a list but then change your mind and do string concatenation instead. On the first iteration of the loop, str(final_cipher) creates the string representation of an empty list "[]". Look familiar? Keep a list and build the string at the end.
final_cipher = []
loop = 0
alphabet = string.ascii_lowercase + " " + string.ascii_lowercase + " "
while loop < len(final_positions_of_letters):
new_letter =alphabet[final_positions_of_letters[loop]]
final_cipher.append(str(new_letter))
loop += 1
final_cipher = ''.join(final_cipher)
print final_cipher

Categories