Function adds an unwanted line - python

class board:
def __init__(self, length, height, letter):
self.layout = ((' ' + letter) * length + ' \n') * height
self.length = length
self.height = height
self.objects = {}
def draw(self, length=None, height=None, letter=None, double=False, show=True):
#adds a line every time
if length == None or height == None or letter == None:
print(self.layout)
else:
if letter != '':
letter = letter[0]
layout = self.layout.split('\n')[:-1]
if layout[0] == '':
layout = layout[1:]
old = ''
for num in range(height):
if num != height:
num = num - 1
old = old + layout[num] + '\n'
new = old
num = length * 2
n = 0
old = ''
for item in layout[height]:
n = n + 1
if n == num:
old_block = item
old = old + letter
else:
old = old + item
string = new + old + '\n'
print(len(layout[height-1:len(layout) -1]))
print(len(layout))
string = string + '\n'.join(layout[height-1:len(layout) -1]) + '\n'
self.layout = string
self.objects[letter] = (length, height, old_block)
if show:
if double:
print(string.replace(' ', ' '))
else:
print(string)
I am trying to create a module which a function that draws a board and you can also add an object at a specific space, but sadly my function called draw adds an unwanted line.
I would be very grateful if you could help me!

self.layout = (((' ' + letter) * length + ' \n') * height)[:-2]
also
self.objects[letter] = (length, height, old_block)
string = string[:-2]
if show:

Related

A little Tic-tac-toe program with the __str__ method, python 3

I have to write a Tic-tac-toe program with python and I use Jupyter Notebook. I want to write a class with the __str__ method. I've first try with a method I've called afficher, in the class Terrain. And it seem to work. But when I try with the __str__ method, it doesn't work.
class Case:
def __init__(self, a = ' '):
self.occupe = a
def jouer1(self):
if self.occupe == ' ':
self.occupe = 'X'
def jouer2(self):
if self.occupe == ' ':
self.occupe = 'O'
*** In need to replace the affiche methode by __str__ methode ***
class Terrain:
def __init__(self):
self.grille = []
for i in range(0, 9):
self.grille.append(Case())
self.tour = 1
def afficher(self):
for i in range(9):
if (i + 1)%3 != 0:
print(self.grille[i].occupe + ' | ', end =" ")
else:
print(self.grille[i].occupe)
def jouer(self, k):
if self.tour == 1:
self.grille[k].jouer1()
self.tour = 2
else:
self.grille[k].jouer2()
self.tour = 1
** this is the output I need, but with the __str__ method in the class Terrain**
terrain = Terrain()
terrain
terrain.jouer(3)
terrain.jouer(2)
terrain.jouer(4)
terrain.jouer(6)
terrain.jouer(5)
terrain.afficher()
*** this is how I replace the afficher method in the Terrain class (It doesn't work ... I don't know why ...) ***
class Case:
def __init__(self, a = ' '):
self.occupe = a
def jouer1(self):
if self.occupe == ' ':
self.occupe = 'X'
def jouer2(self):
if self.occupe == ' ':
self.occupe = 'O'
class Terrain:
def __init__(self):
self.grille = []
for i in range(0, 9):
self.grille.append(Case())
self.tour = 1
def __str__(self):
for i in range(9):
if (i + 1)%3 != 0:
return self.grille[i].occupe + ' | '
else:
return self.grille[i].occupe + ' \ '
def jouer(self, k):
if self.tour == 1:
self.grille[k].jouer1()
self.tour = 2
else:
self.grille[k].jouer2()
self.tour = 1
terrain = Terrain()
terrain
terrain.jouer(3)
terrain.jouer(2)
terrain.jouer(4)
terrain.jouer(6)
terrain.jouer(5)
print(terrain)
Sorry for my english.
Try the following for generating a string for the entire range rather than only one row
def __str__(self):
content = []
for i in range(9):
if (i + 1)%3 != 0:
content.append(self.grille[i].occupe + ' | ')
else:
content.append(self.grille[i].occupe)
return '\n'.join(content)
Thank you so much OneCriketeer.
I try this, and it works !
'
def str(self):
content = []
for i in range(9):
if (i + 1)%3 != 0:
content.append(self.grille[i].occupe + ' | ')
else:
content.append(self.grille[i].occupe + ' \n')
return ''.join(content)
'

Why does Python 3 for loop output and behave differently?

This is a password generator, I couldn't really determine where the problem is, but from the output, I could say it's around turnFromAlphabet()
The function turnFromAlphabet() converts an alphabetical character to its integer value.
The random module, I think doesn't do anything here as it just decides whether to convert a character in a string to uppercase or lowercase. And if a string is in either, when sent or passed to turnFromAlphabet() it is converted to lowercase first to avoid errors but there are still errors.
CODE:
import random
import re
#variables
username = "oogisjab" #i defined it already for question purposes
index = 0
upperOrLower = []
finalRes = []
index2a = 0
#make decisions
for x in range(len(username)):
decision = random.randint(0,1)
if(decision is 0):
upperOrLower.append(True)
else:
upperOrLower.append(False)
#Apply decisions
for i in range(len(username)):
if(upperOrLower[index]):
finalRes.append(username[index].lower())
else:
finalRes.append(username[index].upper())
index+=1
s = ""
#lowkey final
s = s.join(finalRes)
#reset index to 0
index = 0
def enc(that):
if(that is "a"):
return "#"
elif(that is "A"):
return "4"
elif(that is "O"):
return "0" #zero
elif(that is " "):
# reduce oof hackedt
decision2 = random.randint(0,1)
if(decision2 is 0):
return "!"
else:
return "_"
elif(that is "E"):
return "3"
else:
return that
secondVal = []
for y in range(len(s)):
secondVal.append(enc(s[index]))
index += 1
def turnFromAlphabet(that, index2a):
alp = "abcdefghijklmnopqrstuvwxyz"
alp2 = list(alp)
for x in alp2:
if(str(that.lower()) == str(x)):
return index2a+1
break
else:
index2a += 1
else:
return "Error: Input is not in the alphabet"
#real final
finalOutput = "".join(secondVal)
#calculate some numbers and chars from a substring
amount = len(finalOutput) - round(len(finalOutput)/3)
getSubstr = finalOutput[-(amount):]
index = 0
allFactors = {
};
#loop from substring
for x in range(len(getSubstr)):
hrhe = re.sub(r'\d', 'a', ''.join(e for e in getSubstr[index] if e.isalnum())).replace(" ", "a").lower()
print(hrhe)
#print(str(turnFromAlphabet("a", 0)) + "demo")
alpInt = turnFromAlphabet(hrhe, 0)
print(alpInt)
#get factors
oneDimensionFactors = []
for p in range(2,alpInt):
# if mod 0
if(alpInt % p) is 0:
oneDimensionFactors.append(p)
else:
oneDimensionFactors.append(1)
indexP = 0
for z in oneDimensionFactors:
allFactors.setdefault("index{0}".format(index), {})["keyNumber"+str(p)] = z
index+=1
print(allFactors)
I think that you are getting the message "Error: input is not in the alphabet" because your enc() change some of your characters. But the characters they becomes (for example '#', '4' or '!') are not in your alp variable defined in turnFromAlphabet(). I don't know how you want to fix that. It's up to you.
But I have to say to your code is difficult to understand which may explain why it can be difficult for you to debug or why others may be reluctant to help you. I tried to make sense of your code by removing code that don't have any impact. But even in the end I'm not sure I understood what you tried to do. Here's what I understood of your code:
import random
import re
#username = "oogi esjabjbb"
username = "oogisjab" #i defined it already for question purposes
def transform_case(character):
character_cases = ('upper', 'lower')
character_to_return = character.upper() if random.choice(character_cases) == 'upper' else character.lower()
return character_to_return
username_character_cases_modified = "".join(transform_case(current_character) for current_character in username)
def encode(character_to_encode):
translation_table = {
'a' : '#',
'A' : '4',
'O' : '0',
'E' : '3',
}
character_translated = translation_table.get(character_to_encode, None)
if character_translated is None:
character_translated = character_to_encode
if character_translated == ' ':
character_translated = '!' if random.choice((True, False)) else '_'
return character_translated
final_output = "".join(encode(current_character) for current_character in username_character_cases_modified)
amount = round(len(final_output) / 3)
part_of_final_output = final_output[amount:]
all_factors = {}
for (index, current_character) in enumerate(part_of_final_output):
hrhe = current_character
if not hrhe.isalnum():
continue
hrhe = re.sub(r'\d', 'a', hrhe)
hrhe = hrhe.lower()
print(hrhe)
def find_in_alphabet(character, offset):
alphabet = "abcdefghijklmnopqrstuvwxyz"
place_found = alphabet.find(character)
if place_found == -1 or not character:
raise ValueError("Input is not in the alphabet")
else:
place_to_return = place_found + offset + 1
return place_to_return
place_in_alphabet = find_in_alphabet(hrhe, 0)
print(place_in_alphabet)
def provide_factors(factors_of):
for x in range(1, int(place_in_alphabet ** 0.5) + 1):
(quotient, remainder) = divmod(factors_of, x)
if remainder == 0:
for current_quotient in (quotient, x):
yield current_quotient
unique_factors = set(provide_factors(place_in_alphabet))
factors = sorted(unique_factors)
all_factors.setdefault(f'index{index}', dict())[f'keyNumber{place_in_alphabet}'] = factors
print(all_factors)
Is near what your wanted to do?

Moving a character around within a text file using Python

In order to implement a 'maze game' I need to move a character 'X' around a pre-built maze that exists as a .txt file. I have been trying to achieve this via various read/write/append methods but thus far have had no luck. The best I've been able to do is to read and print the coordinates of the 'X' in the text, but not manipulate it in any way. Any help in sorting out a means by which to move it would be greatly appreciated.
class game():
def __init__(self):
self.score = 0
self.exit = False
self.board = []
filepath = 'maze.txt'
with open(filepath,'r') as fp:
line = fp.readline()
while(line):
self.board.append(list(line))
line = fp.readline()
def show_board (self):
CSI="\x1b["
print ("----------")
print(CSI+"38;40m" + 'score:'+ str(self.score) + CSI + "0m")
for i in range(len(self.board)):
for j in range(len(self.board[i])):
if self.board[i][j] == "X":
CSI="\x1b["
print(CSI+"33;91m" + ''.join(self.board[i][j])+ CSI + "0m", end='', flush=True)
elif self.board[i][j] == "*":
CSI="\x1b["
print(CSI+"36;40m" + ''.join(self.board[i][j])+ CSI + "0m", end='', flush=True)
elif self.board[i][j] == "#":
CSI="\x1b["
print(CSI+"32;40m" + ''.join(self.board[i][j])+ CSI + "0m", end='', flush=True)
else:
CSI="\x1B["
print(CSI+"31;40m" + ''.join(self.board[i][j])+ CSI + "0m", end='', flush=True)
def detect_start_point(self):
for x in range(len(self.board)):
for y in range(len(self.board[x])):
if self.board[x][y] == 'X':
self.i,self.j = x,y
def move_player(self, move):
return
#you may remove return (if it is not required)
board = game()
board.detect_start_point()
board.show_board()
while(True): # you may need to change the condition
# get the selected action from the user here
move=input()
# implement
board.move_player(move)
board.show_board()
In theory I should only need to finish the:
def move_player(self, move):
return
#you may remove return (if it is not required)
But my attempts to produce even basic movement have failed.
For anyone interested in the particulars, the text file (referred to in the code as 'maze.txt') contains:
##############################
# X * # #
# ############ # #
# * # # #
# # * # #
# ###### #
# #
########## # #
#* # #
# # ##############
# # * # * #
# # #
# * #
##############################
Where the * are items to collect, and # is a gate to finish the level. I have no issue coding the conditions for those however.
You don't have to change in file but self.board.
First: you should remeber that self.board keeps data in [row][column] which means [y][x] instead of [x][y]
First you should check if new position is empty ie.
# move down (y+1)
if self.board[self.y+1][self.x] in (' ', "#', '*'):
Next you have to remove player from old place, move its x,y and put in new place
self.board[self.y][self.x] = ' ' # clear old place
self.y += 1
self.board[self.y][self.x] = 'X' # put in new place
Before move it could be good to keep old value in some variable - to use it later to receognize if player is standing on # or *
self.current = self.board[self.y][self.x]
I used io.StringIO to simulate file in memory so I could keep code and data in one file for test.
Only one direction: d moves down
text = """##############################
# X * # #
# ############ # #
# * # # #
# # * # #
# ###### #
# #
########## # #
#* # #
# # ##############
# # * # * #
# # #
# * #
##############################"""
import io
# --- constants ---
CSI = "\x1b["
C0 = "\x1b[0m" # color 0 (zero)
CX = "\x1b[33;91m" # color X (player)
CS = "\x1b[36;40m" # color * (star)
CA = "\x1b[32;40m" # color # (at)
C_ = "\x1b[31;40m" # color _ (floor)
# ---
class Game():
def __init__(self):
self.score = 0
self.exit = False
self.board = []
filepath = 'maze.txt'
#with open(filepath,'r') as fp:
with io.StringIO(text) as fp:
for line in fp:
self.board.append(list(line))
def show_board (self):
print ("----------")
print(CSI+"38;40m" + 'score:'+ str(self.score) + C0)
for row in self.board:
for item in row:
if item == "X":
print(CX + item + C0, end='', flush=True)
elif item == "*":
print(CS + item + C0, end='', flush=True)
elif item == "#":
print(CA + item + C0, end='', flush=True)
else:
print(C_ + item + C0, end='', flush=True)
def detect_start_point(self):
for y, row in enumerate(self.board):
for x, item in enumerate(row):
if item == 'X':
self.x, self.y = x, y
def move_player(self, move):
if move == 'd': # down
#if self.board[self.y+1][self.x] in (' ', "#', '*'):
if self.board[self.y+1][self.x] == ' ':
self.board[self.y][self.x] = ' ' # clear old place
self.y += 1
self.board[self.y][self.x] = 'X' # put in new place
return
#you may remove return (if it is not required)
board = Game()
board.detect_start_point()
board.show_board()
while(True): # you may need to change the condition
# get the selected action from the user here
move = input()
# implement
board.move_player(move)
board.show_board()
EDIT: version more univeral. Player can move u, d, l, r (up/down/left/right) but code is shorter.
text = """##############################
# X * # #
# ############ # #
# * # # #
# # * # #
# ###### #
# #
########## # #
#* # #
# # ##############
# # * # * #
# # #
# * #
##############################"""
import io
# --- constants ---
CSI = "\x1b["
C0 = "\x1b[0m" # color 0 (zero)
CX = "\x1b[33;91m" # color X (player)
CS = "\x1b[36;40m" # color * (star)
CA = "\x1b[32;40m" # color # (at)
C_ = "\x1b[31;40m" # color _ (floor)
# ---
class Game():
def __init__(self):
self.score = 0
self.exit = False
self.board = []
filepath = 'maze.txt'
#with open(filepath,'r') as fp:
with io.StringIO(text) as fp:
for line in fp:
self.board.append(list(line))
def show_board (self):
print ("----------")
print(CSI+"38;40m" + 'score:'+ str(self.score) + C0)
for row in self.board:
for item in row:
if item == "X":
print(CX + item + C0, end='', flush=True)
elif item == "*":
print(CS + item + C0, end='', flush=True)
elif item == "#":
print(CA + item + C0, end='', flush=True)
else:
print(C_ + item + C0, end='', flush=True)
def detect_start_point(self):
for y, row in enumerate(self.board):
for x, item in enumerate(row):
if item == 'X':
self.x, self.y = x, y
def move_player(self, move):
moved = False
if move == 'r': # right
new_x = self.x + 1
new_y = self.y
moved = True
if move == 'l': # left
new_x = self.x - 1
new_y = self.y
moved = True
if move == 'd': # down
new_x = self.x
new_y = self.y + 1
moved = True
if move == 'u': # up
new_x = self.x
new_y = self.y - 1
moved = True
if moved:
if self.board[new_y][new_x] in (' ', '#', '*'):
self.current = self.board[new_y][new_x]
self.board[self.y][self.x] = ' ' # clear old place
self.x = new_x
self.y = new_y
self.board[self.y][self.x] = 'X' # put in new place
if self.current == '*':
self.score += 10
self.current = ' ' # no more gold in current place
return
#you may remove return (if it is not required)
board = Game()
board.detect_start_point()
board.show_board()
while(True): # you may need to change the condition
# get the selected action from the user here
move = input()
# implement
board.move_player(move)
board.show_board()

I got stuck on Python error TypeError: unhashable type: 'slice'

from informedSearch import *
from search import *
class EightPuzzleProblem(InformedProblemState):
"""
Inherited from the InformedProblemState class. To solve
the eight puzzle problem.
"""
def __init__(self, myList, list = {}, operator = None):
self.myList = list
self.operator = operator
def __str__(self):
## Method returns a string representation of the state.
result = ""
if self.operator != None:
result += "Operator: " + self.operator + ""
result += " " + ' '.join(self.myList[0:3]) + "\n"
result += " " + ' '.join(self.myList[3:6]) + "\n"
result += " " + ' '.join(self.myList[6:9]) + "\n"
return result
def illegal(self):
## Tests whether the state is illegal.
if self.myList < 0 or self.myList > 9: return 1
return 0
def equals(self, state):
## Method to determine whether the state instance
## and the given state are equal.
return ' '.join(self.myList) == ' '.join(state.myList)
## The five methods below perform the tree traversing
def move(self, value):
nList = self.myList[:] # make copy of the current state
position = nList.index('P') # P acts as the key
val = nList.pop(position + value)
nList.insert(position + value, 'P')
nList.pop(position)
nList.insert(position, val)
return nList
def moveleft(self):
n = self.move(-1)
return EightPuzzleProblem(n, "moveleft")
def moveright(self):
n = self.move(1)
return EightPuzzleProblem(n, "moveright")
def moveup(self):
n = self.move(-3)
return EightPuzzleProblem(n, "moveup")
def movedown(self):
n = self.move(+3)
return EightPuzzleProblem(n, "movedown")
def operatorNames(self):
return ["moveleft", "moveright", "moveup", "movedown"]
def enqueue(self):
q = []
if (self.myList.index('P') != 0) and (self.myList.index('P') != 3) and (self.myList.index('P') != 6):
q.append(self.moveleft())
if (self.myList.index('P') != 2) and (self.myList.index('P') != 5) and (self.myList.index('P') != 8):
q.append(self.moveright())
if self.myList.index('P') >= 3:
q.append(self.moveup())
if self.myList.index('P') >= 5:
q.append(self.movedown())
def applyOperators(self):
return [self.moveleft(), self.moveright(), self.moveup(), self.movedown()]
def heuristic():
counter = 0
for i in range(len(self.myList)):
if ((self.myList[i] != goal.myList[i]) and self.myList[i] != 'P'):
## Position of current:
current = goal.myList.index(self.myList[i])
if current < 3: goalRow = 0
elif current < 6: goalRow = 1
else: goalRow = 2
if i < 3: initRow = 0
elif i < 6: initRow = 1
else: startRow = 2
initColumn = i % 3
goalColumn = current % 3
counter += (abs(goalColumn - initColumn) + abs(goalRow - initRow))
return counter
#Uncomment to test the starting states:
init = ['1','3','P','8','2','4','7','6','5'] #A
#init = ['1','3','4','8','6','2','P','7','5'] #B
#init = ['P','1','3','4','2','5','8','7','6'] #C
#init = ['7','1','2','8','P','3','6','5','4'] #D
#init = ['8','1','2','7','P','4','6','5','3'] #E
#init = ['2','6','3','4','P','5','1','8','7'] #F
#init = ['7','3','4','6','1','5','8','P','2'] #G
#init = ['7','4','5','6','P','3','8','1','2'] #H
goal = ['1','2','3','8','P','4','7','6','5'] #goal state
InformedSearch(EightPuzzleProblem(init), EightPuzzleProblem(goal))
I run it and it shows error
line 34, in __str__ result += " " + ' '.join(self.myList[0:3]) + "\n"
TypeError: unhashable type: 'slice'
Any Ideas?
You're setting the "list" to a dictionary as a default value: list = {} in:
def __init__(self, myList, list = {}, operator = None):
and then assigning it to myList with:
self.myList = list
A dictionary cannot be sliced like a list. So when you try to slice it:
self.myList[0:3]
it fails.

Error in generating gradient

I have an error somewhere in this script that is supposed to generate a gradient. When the depth is equal to the difference the gradient is perfect, but floating point increments seem to screw it up. I've been staring at this code for so long I can't see the answer.
What's wrong with this code?
def interpolate(s, e, n):
start = list(s)
end = list(e)
incrementlst = []
for i in range(0,len(start)):
diff = int(end[i]) - int(start[i])
if diff == 0:
increment = 0.0
else:
increment =diff/n
incrementlst.append(increment)
return incrementlst
def incrementedValue(s, i, n):
start = list(s)
increment = list(i)
n = n-1
finallst = [0,0,0,0]
if n < 1:
return start
for i in range(0,len(start)):
finallst[i] = start[i] + (n*(increment[i]))
return finallst
def formatIncrementedValue(l):
cmykList = list(l)
formattedString = str(int(round(cmykList[0], 0))) + " " + str(int(round(cmykList[1], 0))) + " " + str(int(round(cmykList[2], 0))) + " " + str(int(round(cmykList[3], 0)))
return formattedString
# Get user inputs.
depth = int(ca_getcustomvalue ("depth", "0"))
start = ca_getcustomvalue("start", "0")
end = ca_getcustomvalue("end", "0")
startlst = start.split(" ")
startlst = [int(i) for i in startlst]
endlst = end.split(" ")
endlst = [int(i) for i in endlst]
# draw a line and incrementally change the pen colour towards the end colour
colorlst = interpolate(startlst, endlst, depth)
for i in range(1,depth-1):
color = formatIncrementedValue(incrementedValue(startlst, colorlst, i))
#Draw line at correct offset in colour "color"
This:
increment =diff/n
is doing integer division, so for instance if diff is 3 and n is 2, you get 1, not 1.5.
Make the expression float, to fix this:
increment = float(diff) / n

Categories

Resources