is there a way to "metaprogrammatically" obtain a block of code with the following structure:
if r1 < R1
s = 1
elseif r1 < R2
s = 2
... etc until N
end
end
Thanks!
Check out Base.Cartesian.#nif
I think this should work for you...
julia> macroexpand(:(#nif 10 d->(r1 < R_d) d->begin s=d; break end))
:(if r1 < R_1 # REPL[9], line 1:
s = 1 # REPL[9], line 1:
break
else
if r1 < R_2 # REPL[9], line 1:
s = 2 # REPL[9], line 1:
break
else
if r1 < R_3 # REPL[9], line 1:
s = 3 # REPL[9], line 1:
break
else
if r1 < R_4 # REPL[9], line 1:
s = 4 # REPL[9], line 1:
break
else
if r1 < R_5 # REPL[9], line 1:
s = 5 # REPL[9], line 1:
break
else
if r1 < R_6 # REPL[9], line 1:
s = 6 # REPL[9], line 1:
break
else
if r1 < R_7 # REPL[9], line 1:
s = 7 # REPL[9], line 1:
break
else
if r1 < R_8 # REPL[9], line 1:
s = 8 # REPL[9], line 1:
break
else
if r1 < R_9 # REPL[9], line 1:
s = 9 # REPL[9], line 1:
break
else # REPL[9], line 1:
s = 10 # REPL[9], line 1:
break
end
end
end
end
end
end
end
end
end)
Related
The i+=1 isn't working, it should have increased the i value but it isn't
n = int(input())
for j in range(n):
a = input()
pair = 0
for i in range(len(a)-1):
print(i)
if a[i] == "x" and a[i+1] == "y":
pair += 1
print("*")
elif a[i] == "y" and a[i+1] =="x":
pair += 1
print('**')
else:
continue
i+=1
print(pair)
print("****")
print(pair)strong text
```
You are trying to modify a parameter that is implicitly set by the for loop.
This isn't C-Code, increasing the counter variable will not skip the next iteration.
The reason for that is quite simple: for itself does not increase i in every iteration, it just steps through the given iteratable. In this case the iteratable is a range, which behaves like for would increase i every iteration, but it really just takes the next value from the range.
So i+=1 doesn't have an effect on the next iteration, as it doesn't modify the next value in the range.
Your for-loop already increments i on every iteration. But if you want to increment by more than 1 when certain condition is satisfied, then you can use while loop as follows:
n = int(input())
for j in range(n):
a = input()
pair = 0
i = 0
while i < len(a)-1:
print(i)
if a[i] == "x" and a[i+1] == "y":
pair += 1
print("*")
elif a[i] == "y" and a[i+1] =="x":
pair += 1
print('**')
else:
i += 1
continue
i+=2
print(pair)
print("****")
print(pair)strong text
You could explicitely skip the next iteration when a pair is found.
Here is your code with the changes pointed at by # <---.
n = int(input())
for j in range(n):
a = input()
pair = 0
skip_next = False # <---
for i in range(len(a)-1):
if skip_next is True: # <---
skip_next = False # <---
continue # <---
print(i)
if a[i] == "x" and a[i+1] == "y":
pair += 1
print("*")
skip_next = True # <---
elif a[i] == "y" and a[i+1] =="x":
pair += 1
print('**')
skip_next = True # <---
else:
continue
print(pair)
print("****")
print(pair)
I am attempting to make minesweeper in Python by using tkinter. When the program checks for bombs, it works just fine unless the tile clicked is at 0, 0 (top left), in which case the program always has tileNorth and tileWest True, causing the program to check a variable that doesn't exist. This causes an error and leaves the 0, 0 tile blank. The checking works in every other tile, including corners, just not the top left. This should not be happening.
TLDR:
My minesweeper program works just fine, but it always messes up at 0, 0 and creates an error. I don't understand what's wrong...
The Error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "<string>", line 11, in <lambda>
File "/home/pi/Documents/Python/Minesweeper/Minesweeper.py", line 133, in tileClicked
stringVar_{x}_{y}.set(tileValue)""")
File "<string>", line 56
if bomb_-1_-1 == True:
^
SyntaxError: invalid token
It mentions bomb_-1_-1 which doesn't exist and can't exist... This is why that one if statement needs to work.
My Code:
import random
import tkinter
# Functions
def tileClicked(x, y): # Function is ran when a tile is clicked. The tile is defined by the inputted 'x' and 'y' values.
exec(f"""
global tileNorth, tileEast, tileSouth, tileWest
if y > 0:
tileNorth = True
else:
tileNorth = False
if x < game.size[0] - 1:
tileEast = True
else:
tileEast = False
if y < game.size[1] - 1:
tileSouth = True
else:
tileSouth = False
if x > 0:
tileWest = True
else:
tileWest = False""")
print(f"""{tileNorth}
{tileEast}
{tileSouth}
{tileWest}
DIV""")
exec(f"""
print("{x}, {y}")
if bomb_{x}_{y} == True:
stringVar_{x}_{y}.set("Bomb")
game.failed = True
if x == 0 and y == 0:
tileValue = int(0)
if tileNorth == True:
if tileEast == True:
if bomb_{x + 1}_{y - 1} == True:
tileValue += 1
if tileEast == True:
if bomb_{x + 1}_{y} == True:
tileValue += 1
if tileSouth == True:
if tileEast == True:
if bomb_{x + 1}_{y + 1} == True:
tileValue += 1
if tileWest == True:
if bomb_{x - 1}_{y + 1} == True:
tileValue += 1
if bomb_{x}_{y + 1} == True:
tileValue += 1
if tileWest == True:
if bomb_{x - 1}_{y} == True:
tileValue += 1
else:
tileValue = int(0)
if tileNorth == True:
if tileEast == True:
if bomb_{x + 1}_{y - 1} == True:
tileValue += 1
if tileWest == True:
if bomb_{x - 1}_{y - 1} == True:
tileValue += 1
if bomb_{x}_{y - 1} == True:
tileValue += 1
if tileEast == True:
if bomb_{x + 1}_{y} == True:
tileValue += 1
if tileSouth == True:
if tileEast == True:
if bomb_{x + 1}_{y + 1} == True:
tileValue += 1
if tileWest == True:
if bomb_{x - 1}_{y + 1} == True:
tileValue += 1
if bomb_{x}_{y + 1} == True:
tileValue += 1
if tileWest == True:
if bomb_{x - 1}_{y} == True:
tileValue += 1
if tileValue == 0:
tileValue = "Clear"
stringVar_{x}_{y}.set(tileValue)""")
# Classes
class game:
title = "Minesweeper"
bg = "white"
fg = "black"
size = [10, 10]
tileWidth = 3
tileHeight = 2
failed = False
bombFrequency = 4
flagMode = False
# Execution
window = tkinter.Tk() # The window.
window.title(game.title)
window.config(bg = game.bg)
mainFrame = tkinter.Frame(window, bg = game.bg) # Main frame that everything is located in.
titleFrame = tkinter.Frame(mainFrame, bg = game.bg) # Title frame.
titleLabel = tkinter.Label(titleFrame, bg = game.bg, fg = game.fg, text = game.title, font = "none 20").grid(row = 0, column = 0)
titleFrame.grid(row = 0, column = 0)
tileFrame = tkinter.Frame(mainFrame, bg = game.bg) # Frame where tiles are located.
x = 0
y = 0
for tiles_x in range(game.size[0]): # Generates tiles.
for tiles_y in range(game.size[1]):
exec(f"""global tile_{x}_{y}, stringVar_{x}_{y}, bomb_{x}_{y}
bomb_{x}_{y} = random.randint(1, game.bombFrequency)
if bomb_{x}_{y} == 1:
bomb_{x}_{y} = True
else:
bomb_{x}_{y} = False
stringVar_{x}_{y} = tkinter.StringVar(tileFrame)
tile_{x}_{y} = tkinter.Button(tileFrame, bg = 'lightgrey', fg = 'black', width = game.tileWidth, height = game.tileHeight, textvariable = stringVar_{x}_{y}, command = lambda: tileClicked({x}, {y})).grid(row = {y}, column = {x})""")
y += 1
x += 1
y = 0
tileFrame.grid(row = 1, column = 0)
mainFrame.pack() # The main frame is packed so everything is centered.
window.mainloop()
I don't care if you think dynamic variables are inefficient, it's my choice. I don't want people to comment on my methods of accomplishing a task... unless it's causing the problem...
Thanks!
Using dynamic variables is bad practice, and your experience is a good demonstration why.
Variable names cannot have a minus sign in them. The minus sign is interpreted as the arithmetic operator. So bomb_-1_-1 is interpreted as bomb_ - 1_ - 1. The bomb_ part is understood as a variable name, the 1 as a number, but the underscore following that number is triggering the syntax error.
This also demonstrates that dynamic code is not that great: syntax errors only pop up when certain circumstances are created (like selecting a particular cell).
A quick fix, just to show a work around, is to test first the values of x and y:
if {x} >= 0 and {y} >= 0 and bomb_{x}_{y} == True:
You would have to do similar tests for any other place where you create a dynamic reference like that. So also:
if {x} >= 1 and {y} >= 1 and bomb_{x-1}_{y-1} == True:
...etc.
But this is really patching a terrible design.
Note that even if only one of the variables is negative, you'll evaluate an expression that you did not really intend. You could get this for when only y == -1: bomb_5_-1. This produces no syntax error, but it evaluates as bomb_5_ minus 1. Obviously that is not intended by the algorithm.
Instead of dynamic variables and parsing code at run-time, use lists. They can be nested to have the 2D coverage.
This is my code for the game of fifteen, excluding the 'won' function:
import sys
d = int(sys.argv[1])
dimension = (d * d) - 1
board = [[0 for x in range(d)] for y in range(d)]
def main():
global d
if len(sys.argv) != 2 or 0 > d or d > 9:
print("usage: python fifteen.py size")
exit()
def init():
global d
global dimension
global board
for row in range(d):
for col in range(d):
board[row][col] = dimension
dimension -= 1
if d % 2 == 0:
board[d-1][d-3] = 1
board[d-1][d-2] = 2
def draw():
global d
global dimension
global board
for row in range(d):
for col in range(d):
if board[row][col] == 0:
print("__", end="")
else:
print("{:0=2d} ".format(board[row][col]), end="")
print("")
def move():
global d
global dimension
global board
while True:
tile = int(input("Tile to move: "))
if tile > 0:
break
for row in range(d):
for col in range(d):
if board[row][col] == tile:
colleft = col - 1
colright = col + 1
rowup = row - 1
rowdown = row + 1
if board[row][colleft] == 0 and colleft >= 0:
board[row][colleft] = tile
board[row][col] = 0
return True
elif board[row][colright] == 0 and colright < d:
board[row][colright] = tile
board[row][col] = 0
return True
elif board[rowup][col] == 0 and rowup >= 0:
board[rowup][col] = tile
board[row][col] = 0
return True
elif board[rowdown][col] == 0 and rowdown < d:
board[rowdown][col] = tile
board[row][col] = 0
return True
return False
return True
main()
init()
draw()
move()
draw()
When I want to move 2 or 3 for instance, I keep getting "IndexError: list index out of range":
Erorr message:
python3 fifteen.py 3
Traceback (most recent call last):
File "fifteen.py", line 83, in <module>
move()
File "fifteen.py", line 72, in move
elif board[rowdown][col] == 0 and rowdown < d:
IndexError: list index out of range
What do I have to do to make this work properly?
because rowdown and colright could be bigger than the max index of your board.
for example, d = 3.
when row = 2, rowdown = 3 which is out of index of board.
I have a nested for loop:
for i in range(0,6):
for j in range(0,10):
print(j, end="")
print("\n",0)
Which results in the following:
0123456789
0
0123456789
0
0123456789
0
0123456789
0
0123456789
0
0123456789
0
How do I omit the last 0 from the result?
you can simply add an if as follows:
for i in range(0, 6):
for j in range(0, 10):
print(j, end="")
if i != 5:
print("\n", 0)
You can keep a variable to see if the process is complete and there is no need for more zeroes.
done = False
for i in range(0,6):
for j in range(0,10):
print(j, end="")
if i == 5 and j == 9:
done = True
if not done:
print("\n",0)
# You can also use this variable to break the loop
# after the process is complete.
I am making a connect four like game in python, what I have so far is creating the board and implementing game play against the computer. I am running into the issue that does not allow me to play past the second row. Any ideas on why?
#Define the board
row = int(input("Please enter # of rows: ")) #User input Rows
column = int(input("Please enter # of columns: ")) #User input Columns
board = [] #empty board
space = ' '
p1 = 'x'
p2 = 'o'
#create board based on user input
for i in range(0,row):
board.append([])
for j in range(0, column):
board[i].append(space)
print(board)
#print board with character decorations
for i in board:
line=''
print('+'+'-+'*len(i))
for j in range(len(i)):
line = line + '|'+i[j]
line = line + '|'
print(line)
print('+'+'-+'*len(i))
print(len(board))
while True:
#User input column
myC = int(input("Player 1, choose your column: "))
i = len(board)-1
x = len(board)-1
while i >= 0:
if board[x][myC] == space:
i = i+1
board[x][myC] = 'x'
break
elif board[x][myC] == p1 or p2:
i = i+1
x = x - 1
print(x)
board[x][myC] = 'x'
break
# print the board!
for i in board:
line=''
print('+'+'-+'*len(i))
for j in range(len(i)):
line = line + '|'+i[j]
line = line + '|'
print(line)
print('+'+'-+'*len(i))
#Computer input column
from random import randint
theC = randint(0, len(board)-1)
print("Computer's Turn: Column " , theC)
i = len(board)-1
x = len(board)-1
while i >= 0:
if board[x][theC] == space:
board[x][theC] = 'o'
i = i+1
break
elif board[x][theC] == p1 or p2:
i = i+1
x = x - 1
print(x)
board[x][theC] = 'o'
break
# print the board!
for i in board:
line=''
print('+'+'-+'*len(i))
for j in range(len(i)):
line = line + '|'+i[j]
line = line + '|'
print(line)
print('+'+'-+'*len(i))
I believe I figured out what's going on. Your x is always initialized to len(board)-1 and then if the space is occupied it is reduced by one. If you make a (>2)x(>2) board and row 0 is occupied then this will always force x = 2.
This is close to correct, but what you actually need is to iterate through all rows until you find the first unoccupied row. I created a loop that will find the first row and assign that to the value of x. I tested it out and I'm now able to play passed 2 rows.
#Define the board
row = int(input("Please enter # of rows: ")) #User input Rows
column = int(input("Please enter # of columns: ")) #User input Columns
board = [] #empty board
space = ' '
p1 = 'x'
p2 = 'o'
#create board based on user input
for i in range(0,row):
board.append([])
for j in range(0, column):
board[i].append(space)
print(board)
#print board with character decorations
for i in board:
line=''
print('+'+'-+'*len(i))
for j in range(len(i)):
line = line + '|'+i[j]
line = line + '|'
print(line)
print('+'+'-+'*len(i))
print(len(board))
while True:
#User input column
myC = int(input("Player 1, choose your column: "))
i = len(board)-1
x = len(board)-1
while i >= 0:
if board[x][myC] == space:
i = i+1
board[x][myC] = 'x'
break
# Find last empty row for new piece
elif board[x][myC] == p1 or p2:
for j in range(x-1,-1,-1):
if board[j][myC] == space:
x = j
break
i = i+1
#x = x - 1
print(x)
board[x][myC] = 'x'
break
# print the board!
for i in board:
line=''
print('+'+'-+'*len(i))
for j in range(len(i)):
line = line + '|'+i[j]
line = line + '|'
print(line)
print('+'+'-+'*len(i))
#Computer input column
from random import randint
theC = randint(0, len(board)-1)
print("Computer's Turn: Column " , theC)
i = len(board)-1
x = len(board)-1
while i >= 0:
if board[x][theC] == space:
board[x][theC] = 'o'
i = i+1
break
# Find last empty row for new piece
elif board[x][theC] == p1 or p2:
for j in range(x-1,-1,-1):
if board[j][theC] == space:
x =j
break
i = i+1
#x = x - 1
print(x)
board[x][theC] = 'o'
break
# print the board!
for i in board:
line=''
print('+'+'-+'*len(i))
for j in range(len(i)):
line = line + '|'+i[j]
line = line + '|'
print(line)
print('+'+'-+'*len(i))