find function does not display desired string - python

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

Related

how can i get the grid representation of the integer

I need to create a method set_from_integer(self, integer_encoding) that sets the colours of all points of the board according to the given integer_encoding which does not change the size of the board. To convert an integer n to ternary representation, as required by set_from_integer(), get the last digit by computing n mod 3. You get the next digit by computing [n/3]mod 3 and so on. For example, to get the last two digits of the ternary representation of 7473:
#This is the problematic part
def set_from_integer(self, integer_encoding):
n = int(integer_encoding)
list1 = []
while n != 0:
rem = n % 3
list1.append(rem)
n = n // 3
list1.reverse()
for i in list1:
print(i, end="")
So for now the above is what i came up with to get the ternary base of the decimal number but i need to convert this into a grid of symbols according to the given :
(empty = 0, white = 1, black = 2)
My entire code is as follows:
def load_board(filename):
result = " "
with open(filename) as f:
print(f)
for index, line in enumerate(f):
if index == 0:
result += ' '+' '.join([chr(alphabets + 65) for alphabets in range(len(line) - 1)]) + '\n' # the alphabetical column heading
result += f"{19 - index:2d}"
result += ' ' + ' '.join(line.strip()) + '\n'
return result
def save_board(filename, board):
with open(filename, "wt") as f:
f.write(board)
from string import ascii_uppercase as letters
class Board:
#Dictionary created for the colours and the respected symbols
points = {'E': '.', 'B': '#', 'W': 'O'}
#Constructor
def __init__(self,size=19,from_strings=None):
assert 2 <= size <= 26, "Illegal board size: must be between 2 and 26."
if from_strings != None:
if type(from_strings) != list:
raise AssertionError("input is not a list")
if len(from_strings) != size:
raise AssertionError("length of input list does not match size")
for i in range(size):
if type(from_strings[i]) != str:
raise AssertionError("row " + str(i) + " is not a string")
if len(from_strings[i]) != size:
raise AssertionError("length of row " + str(i) + " does not match size")
for j in range(size):
if from_strings[i][j] not in ".#O":
raise AssertionError("invalid character in row " + str(i))
self.size = size
self.grid = [['E'] * size for _ in range(size)]
self.from_strings = [] if from_strings is None else from_strings
def get_size(self): #Returns the size of the grid created by the constructor
return self.size
def __str__(self): # creating the grid
padding = ' ' # Creating a variable with a space assigned so that it acts as a padding to the rows that have a single digit
heading = ' ' + ' '.join(letters[:self.size]) # Alphabetical heading is created
lines = [heading] # adding the alphabetical heading into a list named lines to which the rows will be added later
for r, row in enumerate(self.grid):
if len(self.grid) < 10: # for the grid with a size less than 10 to add the space to the start of the row for the single digits to be aligned
if (self.from_strings):
line = " " + f'{self.size - r} ' + ' '.join(self.from_strings[r])
else:
line = " " + f'{self.size - r} ' + ' '.join(self.points[x] for x in row)
lines.append(line)
else: # for the grids that are larger than 9
if r > 9: # for rows 1 to 9 the single digits are aligned according to the first digit from the right of the two digit rows
if (self.from_strings):
line = f'{self.size - r} ' + ' '.join(self.from_strings[r])
else:
line = f'{self.size - r} ' + ' '.join(self.points[x] for x in row)
line = padding + line # adding the space using the variable padding to the row created
lines.append(line) # adding the row to the list of rows
else: # for the rows 10 onwards - as there is no requirement to add a padding it is not added here
if (self.from_strings):
line = f'{self.size - r} ' + ' '.join(self.from_strings[r])
else:
line = f'{self.size - r} ' + ' '.join(self.points[x] for x in row) # creation of the row
lines.append(line) # adding the newly created row to the list of rows
return '\n'.join(lines)
def _to_row_and_column(self, coords):
# destructure coordinates like "B2" to "B" and 2
alpha, num = coords
colnum = ord(alpha) - ord('A') + 1
rownum = self.size - int(num) + 1
assert 1 <= rownum <= self.size,"row out of range"
assert 1 <= colnum <= self.size,'column out of range'
return rownum, colnum
def set_colour(self, coords, colour_name):
rownum, colnum = self._to_row_and_column(coords)
assert len(coords)==2 or len(coords)==3, "invalid coordinates"
assert colour_name in self.points,"invalid colour name"
self.grid[rownum - 1][colnum - 1] = colour_name
def get_colour(self, coords):
rownum, colnum = self._to_row_and_column(coords)
return self.grid[rownum - 1][colnum - 1]
def to_strings(self):
padding = ' '
lines = []
for r, row in enumerate(self.grid):
if self.from_strings:
lines.append(''.join(self.from_strings[r]))
else:
lines.append(''.join(self.points[x] for x in row))
return lines
def to_integer(self):
digit_colour=""
for line in self.to_strings():
for character in line:
if character=='.':
character=0
elif character=='O':
character=1
elif character=='#':
character=2
character=str(character)
digit_colour+=character
return int(digit_colour,3)
# return ''.join(self.to_int[x] for line in self.grid for x in line)
def set_from_integer(self, integer_encoding):
n = int(integer_encoding)
list1 = []
while n != 0:
rem = n % 3
list1.append(rem)
n = n // 3
list1.reverse()
for i in list1:
print(i, end="")
print(type(list1))
print(list1)
for i in range(self.size):
for j in range(self.size):
if list1[i * self.size + j] == "0":
self.grid[i][j] = "."
elif list1[i * self.size + j] == "1":
self.grid[i][j] = "#"
elif list1[i * self.size + j] == "2":
self.grid[i][j] = "O"
c = Board(3)
c.set_from_integer(14676)
print(c)
d = Board(5)
d.set_from_integer(1)
print(d)
and the expected output is shown below:
A B C
3 # . #
2 . O .
1 O # .
A B C D E
5 . . . . .
4 . . . . .
3 . . . . .
2 . . . . .
1 . . . . O

Replace a single character in a string

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"

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

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.

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)

PYTHON IndexError : string index out of range

Problem statement : Write a function called censor that takes two strings, text and word, as input. It should return the text with the word you chose replaced with asterisks
Here is my code,
def censor(text, word):
i = 0
j = 0
ans = ""
while i<len(text):
while text[j] == word[j]:
j = j + 1
if text[j+1] == " " or j+1 == len(text):
while i<j:
ans += "*"
i = i + 1
ans += " "
i = i + 1
else:
while text[j] != " ":
j = j + 1
while i<=j:
ans += text[i]
i = i + 1
i = i + 1
j = j + 1
return ans
print censor("how are you? you are not fine.","you")
But I am getting the following error,
Traceback (most recent call last):
File "python", line 27, in <module>
File "python", line 7, in censor
IndexError: string index out of range
This is much more complicated than it needs to be. You can just do this:
def censor(text, censored_word):
return text.replace(censored_word, '*'*len(censored_word))
>>> censor('How are you? Are you okay?', 'you')
'How are ***? Are *** okay?'
If you don't want the word youth to be censored but you do want you to be censored, here's how:
def censor(text, censored_word):
repl = '*'*len(censored_word)
return ' '.join([repl if word == censored_word else word for word in text.split()])
If you want to have multiple censored words:
def censor(text, censored_words):
return ' '.join(['*'*len(word) if word in censored_words else word for word in text.split()])
When dealing with index errors, it is often helpful to print out the index and figure out why the index has a value not within the required bounds.
It's good to use string replace in python for replacing the string.
In your case, you should make use of word's length to match word in the text as:
def censor(text, word):
i = 0
j = 0
ans = ""
wl=len(word)
while i<(len(text)):
if word==text[i:i+wl]:
ans=ans+'*'*wl
i=i+wl
else:
ans=ans+text[i]
i = i + 1
return ans
print censor("how are you? you are not fine.","you")

Categories