Strange L-system in python turtle graphics - python

I tried to use the turtles module in Python 3 to recreate the fractal found here:
https://en.wikipedia.org/wiki/L-system#Example_7:_Fractal_plant
but whenever I try it it gives me a very strange result...
Here's my code:
import turtle
wn = turtle.Screen()
wn.bgcolor("white")
wn.screensize(10000, 10000)
tess = turtle.Turtle()
tess.color("lightgreen")
tess.pensize(1)
tess.speed(0)
tess.degrees()
inst = 'X'
steps = 3
for counter in range(steps):
_inst = ''
for chtr in inst:
if chtr == 'X':
_inst += 'F−[[X]+X]+F[+FX]−X'
elif chtr == 'F':
_inst += 'FF'
else:
_inst += chtr
inst = _inst
print(inst)
for chtr in inst:
if (chtr == 'F'):
tess.forward(25)
elif (chtr == '+'):
tess.right(25)
elif (chtr == '-'):
tess.left(25)
elif (chtr == '['):
angle = tess.heading()
pos = [tess.xcor(), tess.ycor()]
elif (chtr == ']'):
tess.setheading(angle)
tess.penup()
tess.goto(pos[0], pos[1])
tess.pendown()
wn.exitonclick()
I triple-checked everything and I seem to have no bugs - but it still does not work. What am I doing terribly wrong?
Thanks in advance for any help!

There are two issues in your code.
The first is that your code doesn't handle nested brackets properly. The inner opening bracket saves its state over the top of the previous state saved when the outer opening bracket was seen. This won't matter for immediately nested brackets like [[X]+X] (since both have the same starting state), but once you get more complicated nesting (as you will after a few substitution loops), the issue starts to make things go wrong.
To solve this you probably want to store your saved state values to a stack (a list can do). Push the values you want to save, and pop them back off when you're ready to restore them.
stack = [] # use a list for the stack
for chtr in inst:
if (chtr == 'F'):
tess.forward(25)
elif (chtr == '+'):
tess.right(25)
elif (chtr == '-'):
tess.left(25)
elif (chtr == '['):
angle = tess.heading()
pos = [tess.xcor(), tess.ycor()]
stack.append((angle, pos)) # push state to save
elif (chtr == ']'):
angle, pos = stack.pop() # pop state to restore
tess.setheading(angle)
tess.penup()
tess.goto(pos[0], pos[1])
tess.pendown()
The second issue is more trivial. Your parser looks for the "minus" character (-). But your pattern generating code uses a different, slightly longer kind of dash (−). Change one of them to match the other (it doesn't really matter which one) and your code will work as expected.

According to the Wikipedia page, the symbol '[' means to save the current state (angle and positions). The matching ']' means to restore the previously saved position. Because the '[' and ']' can be nested, a stack is needed.
from collections import deque
...
stack = deque()
for chtr in inst:
if (chtr == 'F'):
tess.forward(25)
elif (chtr == '+'):
tess.right(25)
elif (chtr == '-'):
tess.left(25)
elif (chtr == '['):
angle = tess.heading()
pos = [tess.xcor(), tess.ycor()]
stack.append((angle, pos)) ### New statement
elif (chtr == ']'):
angle, pos = stack.pop() ### New statement
tess.setheading(angle)
tess.penup()
tess.goto(pos[0], pos[1])
tess.pendown()
. . .

Related

Skipping through all elifs to the end and activating the last statements

I am making a very creative tetris clone for a project with a friend and we have custom sprites for every shape (including the rotations) and we made a wall of else if statements for the rotations. It's supposed to work like this: It calls a random shape out of list of the main 7 shapes and every time the user presses "a" it changes the left facing gif of that shape using the giant el if wall. However, we ran unto an error where instead of executing the elif statements, it just skips to the last line and changes to the J shape no matter what shape was called in the random statement. Any help would be awesome, thank you! (We are still learning btw) also the rotate function is also supposed to happen when the user presses the "d" key but its supposed to change to the other direction.
import turtle as trtl
import random as rand
wn = trtl.Screen()
#configurations
tetris = trtl.Turtle()
drawer = trtl.Turtle()
background = trtl.Turtle()
starty = int(-400)
square = ("sqaure_block.gif")
s_block_normal = ("S_block_norm.gif")
s_block_standing = ("S_block_right.gif")
invert_s_block_normal = ("Z_block_norm.gif")
invert_s_block_standing = ("Z_block_right.gif")
l_block_normal = ("L_block_norm.gif")
l_block_180 = ("L_block_180.gif")
l_block_right = ("L_block_right.gif")
l_block_left = ("L_block_left.gif")
line_normal = ("line_block_norm.gif")
line_standing = ("line_block_standing.gif")
t_block_normal = ("T_block_norm.gif")
t_block_180 = ("T_block_180.gif")
t_block_right = ("T_BLOCK_RIGHT.gif")
t_block_left = ("T_block_left.gif")
j_block_normal = ("J_block_norm.gif")
j_block_180 = ("J_block_180.gif")
j_block_right = ("J_block_right.gif")
j_block_left = ("J_block_left.gif")
wn.addshape (square)
wn.addshape(s_block_normal)
wn.addshape(s_block_standing)
wn.addshape(invert_s_block_normal)
wn.addshape(invert_s_block_standing)
wn.addshape(l_block_normal)
wn.addshape(l_block_180)
wn.addshape(l_block_right)
wn.addshape(l_block_left)
wn.addshape(line_normal)
wn.addshape(line_standing)
wn.addshape(t_block_normal)
wn.addshape(t_block_180)
wn.addshape(t_block_right)
wn.addshape(t_block_left)
wn.addshape(j_block_normal)
wn.addshape(j_block_180)
wn.addshape(j_block_right)
wn.addshape(j_block_left)
Tshape = [square, s_block_normal, invert_s_block_normal, l_block_normal, line_normal, t_block_normal, j_block_normal]
squarecor = [-50, -25, -100, -50]
wn.bgcolor("lightblue")
background.speed("fastest")
background.hideturtle()
background.pu()
background.goto(-400,-200)
background.fillcolor("blue")
background.pencolor("blue")
background.begin_fill()
background.pd()
background.goto(400,-200)
background.goto(400,-350)
background.goto(-400,-350)
background.goto(-400,-200)
background.end_fill()
#sprite direction change
def sprite_right():
global tetris
tetris.hideturtle()
if (tetris.shape(s_block_normal)):
tetris.shape(s_block_standing)
elif (tetris.shape(invert_s_block_normal)):
tetris.shape(invert_s_block_standing)
elif (tetris.shape(line_normal)):
tetris.shape(line_standing)
elif (tetris.shape(l_block_normal)):
tetris.shape(l_block_right)
elif (tetris.shape(t_block_normal)):
tetris.shape(t_block_right)
elif (tetris.shape(j_block_normal)):
tetris.shape(j_block_right)
elif (tetris.shape(l_block_right)):
tetris.shape(l_block_180)
elif (tetris.shape(t_block_right)):
tetris.shape(t_block_180)
elif (tetris.shape(j_block_right)):
tetris.shape(j_block_180)
elif (tetris.shape(s_block_standing)):
tetris.shape(s_block_normal)
elif (tetris.shape(invert_s_block_standing)):
tetris.shape(invert_s_block_normal)
elif (tetris.shape(line_standing)):
tetris.shape(line_normal)
elif (tetris.shape(l_block_180)):
tetris.shape(l_block_left)
elif (tetris.shape(t_block_180)):
tetris.shape(t_block_left)
elif (tetris.shape(j_block_180)):
tetris.shape(j_block_left)
elif (tetris.shape(l_block_left)):
tetris.shape(l_block_normal)
elif (tetris.shape(t_block_left)):
tetris.shape(t_block_normal)
elif (tetris.shape(j_block_left)):
tetris.shape(j_block_normal)
tetris.showturtle()
def sprite_left():
tetris.hideturtle()
if (tetris.shape(s_block_normal)):
tetris.shape(s_block_standing)
elif (tetris.shape(invert_s_block_normal)):
tetris.shape(invert_s_block_standing)
elif (tetris.shape(line_normal)):
tetris.shape(line_standing)
elif (tetris.shape(l_block_normal)):
tetris.shape(l_block_left)
elif (tetris.shape(t_block_normal)):
tetris.shape(t_block_left)
elif (tetris.shape(j_block_normal)):
tetris.shape(j_block_left)
elif (tetris.shape(l_block_left)):
tetris.shape(l_block_180)
elif (tetris.shape(t_block_left)):
tetris.shape(t_block_180)
elif (tetris.shape(j_block_left)):
tetris.shape(j_block_180)
elif (tetris.shape(s_block_standing)):
tetris.shape(s_block_normal)
elif (tetris.shape(invert_s_block_standing)):
tetris.shape(invert_s_block_normal)
elif (tetris.shape(line_standing)):
tetris.shape(line_normal)
elif (tetris.shape(l_block_180)):
tetris.shape(l_block_right)
elif (tetris.shape(t_block_180)):
tetris.shape(t_block_right)
elif (tetris.shape(j_block_180)):
tetris.shape(j_block_right)
elif (tetris.shape(l_block_right)):
tetris.shape(l_block_normal)
elif (tetris.shape(t_block_right)):
tetris.shape(t_block_normal)
elif (tetris.shape(j_block_right)):
tetris.shape(j_block_normal)
tetris.showturtle()
'''
def (fast_down):
global tetris
tetris.setheading(270)
tetris.forward(10)
'''
#turn right
def turn_right():
tetris.speed("fastest")
tetris.setheading(0)
tetris.speed(1)
tetris.forward(10)
tetris.speed("fastest")
tetris.setheading(270)
#turn left
def turn_left():
tetris.speed("fastest")
tetris.setheading(180)
tetris.speed(1)
tetris.forward(10)
tetris.speed("fastest")
tetris.setheading(270)
#down
#tetris container/backround
drawer.pensize(5)
drawer.speed("fastest")
drawer.penup()
drawer.goto(150, 200)
drawer.pendown()
drawer.setheading(270)
drawer.forward(400)
drawer.setheading(180)
drawer.forward(300)
drawer.setheading(90)
drawer.forward(400)
drawer.hideturtle()
#game WIP!!!!!!!!!!
y = 0
space = int(1)
tracer = True
def spawn_T():
new_T=rand.choice(Tshape)
tetris.shape(t_block_180)
tetris.pu()
tetris.goto(0, 200)
tetris.setheading(270)
tetris.forward(10)
'''
if ((abs(space - starty)) < 200):
tetris.forward(2)
else:
'''
tetris.stamp()
'''
space = space =+ 1
'''
tetris.hideturtle()
tetris.goto(0,200)
tetris.showturtle()
if (y == 0):
spawn_T()
#changeing the directions of the sprites
#events
wn.onkeypress(turn_right, "Right")
wn.onkeypress(turn_left, "Left")
wn.onkeypress(sprite_right, "a")
wn.onkeypress(sprite_left, "d")
'''
wn.onkeypress(fast_down, "s")
'''
wn.listen()
wn.mainloop()
Here is the google drive file https://drive.google.com/drive/folders/1Q_zXEqm4aFHQ4RV-ZvEXCK2Wi7SHMxrW?usp=share_link
I think the indentation is wrong here. Maybe try putting the last else-statement one tab further?
Please use elif instead of the else: if formulation to get away from the bewildering indentation - here's how it should look:
def sprite_right():
global tetris
tetris.hideturtle()
if (tetris.shape(s_block_normal)):
tetris.shape(s_block_standing)
elif (tetris.shape(invert_s_block_normal)):
tetris.shape(invert_s_block_standing)
elif (tetris.shape(line_normal)):
tetris.shape(line_standing)
elif (tetris.shape(l_block_normal)):
tetris.shape(l_block_right)
elif (tetris.shape(t_block_normal)):
tetris.shape(t_block_right)
elif (tetris.shape(j_block_normal)):
tetris.shape(j_block_right)
elif (tetris.shape(l_block_right)):
tetris.shape(l_block_180)
elif (tetris.shape(t_block_right)):
tetris.shape(t_block_180)
elif (tetris.shape(j_block_right)):
tetris.shape(j_block_180)
elif (tetris.shape(s_block_standing)):
tetris.shape(s_block_normal)
elif (tetris.shape(invert_s_block_standing)):
tetris.shape(invert_s_block_normal)
elif (tetris.shape(line_standing)):
tetris.shape(line_normal)
elif (tetris.shape(l_block_180)):
tetris.shape(l_block_left)
elif (tetris.shape(t_block_180)):
tetris.shape(t_block_left)
elif (tetris.shape(j_block_180)):
tetris.shape(j_block_left)
elif (tetris.shape(l_block_left)):
tetris.shape(l_block_normal)
elif (tetris.shape(t_block_left)):
tetris.shape(t_block_normal)
elif (tetris.shape(j_block_left)):
tetris.shape(j_block_normal)
tetris.showturtle()
def sprite_left():
tetris.hideturtle()
if (tetris.shape(s_block_normal)):
tetris.shape(s_block_standing)
elif (tetris.shape(invert_s_block_normal)):
tetris.shape(invert_s_block_standing)
elif (tetris.shape(line_normal)):
tetris.shape(line_standing)
elif (tetris.shape(l_block_normal)):
tetris.shape(l_block_left)
elif (tetris.shape(t_block_normal)):
tetris.shape(t_block_left)
elif (tetris.shape(j_block_normal)):
tetris.shape(j_block_left)
elif (tetris.shape(l_block_left)):
tetris.shape(l_block_180)
elif (tetris.shape(t_block_left)):
tetris.shape(t_block_180)
elif (tetris.shape(j_block_left)):
tetris.shape(j_block_180)
elif (tetris.shape(s_block_standing)):
tetris.shape(s_block_normal)
elif (tetris.shape(invert_s_block_standing)):
tetris.shape(invert_s_block_normal)
elif (tetris.shape(line_standing)):
tetris.shape(line_normal)
elif (tetris.shape(l_block_180)):
tetris.shape(l_block_right)
elif (tetris.shape(t_block_180)):
tetris.shape(t_block_right)
elif (tetris.shape(j_block_180)):
tetris.shape(j_block_right)
elif (tetris.shape(l_block_right)):
tetris.shape(l_block_normal)
elif (tetris.shape(t_block_right)):
tetris.shape(t_block_normal)
elif (tetris.shape(j_block_right)):
tetris.shape(j_block_normal)
tetris.showturtle()
That said, because this is all the code you've provided, it's not possible to run it and examine why it's not working. Can you please provide an example of an implementation of these functions?
According to the documentation, shape() returns the current shape with no parameters, and sets it with one parameter. Therefore in:
if tetris.shape(s_block_normal):
shape(name) returns None, which is always False. So, if you change to:
if tetris.shape() == s_block_normal:
It should function as required.
Also, you can get rid of the if ladder completely by, for instance, something like:
next_left_shape = {s_block_normal: s_block_standing,
invert_s_block_normal: invert_s_block_standing,
... }
tetris.shape(next_left_shape[tetris.shape()])

How to move my character on my generated board?

A few days ago a started making my simple board game. First of all, I generate a board for the game. It looks like this:
the gameboard generated for 13x13
Secondly, I place my character on the board, which is 'A':
The player placed
I made a dice for it which generates numbers from 1 to 6.
My goal right now is to get the 'A' character moving around by the dice on the '*' symbols, until it gets at the top left corner:
I need to get here by the dice
So here is my code that I tried:
import math
import random
import os
board= []
def generator(boardsize):
for row in range(boardsize+1):
brow = []
for column in range(boardsize+1):
if row == column == 0:
brow.append(' ')
elif row==0:
brow.append(str(column-1)[-1])
elif column==0:
brow.append(str(row-1)[-1])
elif ((math.ceil(boardsize/2)-1 )<= column) and(column <= (math.ceil(boardsize/2)+1)) or ((math.ceil(boardsize/2)-1 )<= row) and(row <= (math.ceil(boardsize/2)+1)):
if row == 1 or column == 1 or row == boardsize or column == boardsize:
brow.append('*')
else:
if row == (math.ceil(boardsize/2)) and column == (math.ceil(boardsize/2)):
brow.append('X')
elif row == (math.ceil(boardsize/2)) or column == (math.ceil(boardsize/2)):
brow.append('D')
else:
brow.append('*')
else:
brow.append(' ')
board.append(brow)
return board
def print_table(x):
os.system('cls')
for x in board:
print(' '.join(x))
number_from_dice= []
def dice():
min = 1
max = 6
x = random.randint(min, max)
number_from_dice[:]= [x]
return number_from_dice
def player1(x):
generator(x)
prev_char_y = 1
prev_char_x = math.ceil(x/2)+1
char_y= 1
char_x= math.ceil(x/2)+1
board[char_y][char_x] = "A"
print_table(x)
dice()
f = number_from_dice[0]
for i in range(f):
if(char_y<x):
if (board[char_y+1][char_x]) == '*':
char_y= char_y +1
board[char_y][char_x] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x
prev_char_y = char_y
print_table(x)
else:
if(char_x!=x):
char_x2 = char_x
if (board[char_y][char_x+1]=='*'):
char_x = char_x +1
board[char_y][char_x] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x
prev_char_y = char_y
print_table(x)
else:
if (board[char_y+1][char_x]) == '*':
char_y= char_y +1
board[char_y][char_x] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x
prev_char_y = char_y
print_table(x)
else:
if (board[char_y][char_x2-1]) == '*':
char_x2 = char_x2 -1
board[char_y][char_x2] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x2
prev_char_y = char_y
print_table(x)
else:
if (board[char_y+1][char_x2]) == '*':
char_y = char_y +1
board[char_y][char_x2] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x2
prev_char_y = char_y
print_table(x)
print('Number from dice: ', end='')
print(f)
player1(13)
Does the technic I used have potential? Or is it too complicated? How would you do it?
Just in a generic sense you've made it overly complicated.
Consider this - the board, as far as movement is concerned, is just a set of ordered spaces.
But right now you have information about how the board is created as part of the player code.
Best to separate this, and you will find that things get simpler.
Instead, have the player simply track it's progress, in other words, what numbered space is it on.
Then you can generate the board and, knowing the space numbers, you can see if it matches the player location.
And then take it one step further (and simpler still) and just draw the board on a 2D array, and then output that, instead of trying to figure out the board as you go line-by-line.

brainfuck intepreter printing out wrong

I recently decided to try to code "yet another" brainfuck interpreter, but I have a problem. It prints out the wrong numbers, when it should put our hello,world!. Does anyone know why this is happening? Thanks in advance! I cannot figure out why it's doing this. Please help! I am only a beginner. Sorry for the bad coding style, but please don't change the whole thing. I would rather recieve tips.
from copy import copy
import sys
def brainfuckintepreter(program):
# find pairs of brackets
brackets = {}
bbrackets = {}
def findmatchingclosingbracket(ctr):
level = 0
if program[ctr] == '[':
while True:
if program[ctr] == '[':
level += 1
elif program[ctr] == ']':
level -= 1
if level == 0:
return ctr
break
ctr += 1
def findmatchingopeningbracket(ctr):
level = 0
if program[ctr] == ']':
while True:
if program[ctr] == '[':
level -= 1
elif program[ctr] == ']':
level += 1
if level == 0:
return ctr
break
ctr -= 1
"""
ctr = 0
for a in program:
if a == '[':
f = copy(findmatchingclosingbracket(ctr))
brackets[ctr] = f
bbrackets[f] = ctr
ctr += 1
print(brackets)
print(bbrackets)
"""
# running the program
tape = [0] * 3000
pointer = 1500
counter = 0
results = ""
valid = True
while counter != len(program) and valid:
a = program[counter]
# move right
if a == '>':
if pointer == len(tape) - 1:
tape.append(0)
pointer += 1
# move left
elif a == '<':
if pointer == 0:
raise ValueError("On index ", counter, ", the program tried to move to -1 on the tape")
valid = False
return valid
else:
pointer -= 1
# increment
elif a == '+':
if tape[pointer] == 255:
tape[pointer] = 0
else:
tape[pointer] += 1
# decrement
elif a == '-':
if tape[pointer] == 0:
tape[pointer] = 255
else:
tape[pointer] -= 1
# output character
elif a == '.':
t = chr(tape[pointer])
results += t
print(t, end='')
# input character
elif a == ',':
tape[pointer] = ord(sys.stdin.read(1))
# opening bracket
elif a == '[':
if tape[pointer] == 0:
pointer = findmatchingclosingbracket(pointer)
# closing bracket
elif a == ']':
if tape[pointer] != 0:
pointer = findmatchingopeningbracket(counter)
counter += 1
"""
for b in tape:
if b != 0:
print(b)
"""
brainfuckintepreter('++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.')
Edit:
I changed my code after some revisions, but same problem.
Your loops are the problem.
level = 0
while level > 0:
...
That loop will never be entered. The condition is immediately false (you're setting level to 0, right before checking if it is greater than 0).
You could change that to a do..while loop instead of a while loop (make a while true loop and check the condition at the end to decide whether to break out of the loop or not) and start checking at the current pointer position (include the current [ or ]), not at the next character after it.
Also here:
if tape[pointer] == 0:
pointer = findmatchingclosingbracket(pointer)
you should be passing and updating the program counter, not the tape pointer on the second line. And likewise for the other one just below it.

Need help returning a variable for use outside a function (Python)

Im working on a program in which I need to plot the movement of a turtle on a plane starting at (100,100) and facing right. In three steps the user can either walk and input how far they wish to go, or turn, where they would change directions in 90 degrees. I have written my function which takes in the original coordinates, manipulates them and returns new coordinates, but my program refuses to accept this. My program returns a manipulated value of my plot variable (renamed coor) , but python doesn't acknlowedge it when I attempt to call it.
plot= [100,100]
i=0
def movement(step,coor,i):
x= coor[0]
y= coor[1]
if step == 'turn':
i = i+1
return coor,i
else:
if i == 0:
direct= 'right'
elif i == 1:
direct= 'down'
elif i == 2:
direct= 'left'
elif i ==3:
direct= 'up'
else:
i = 0
direct= 'right'
if direct == 'right':
coor= [x-step,y]
return coor
elif direct == 'down':
coor= [x,y+step]
return coor
elif direct== 'left':
coor == [x+step, y]
return coor
elif direct == 'up':
coor == [x, y-step]
return coor
step1= raw_input('Step choice (turn or walk) => ')
print step1
step1=step1.lower()
if step1 == 'walk':
numsteps1= input('Number of steps => ')
movement(numsteps1,plot,0)
elif step1== 'turn':
movement('turn',plot,0)
else:
print 'Illegal step choice.'
step2= raw_input('Step choice (turn or walk) => ')
print step2
step2=step2.lower()
if step2== 'walk':
numsteps2= input('Number of steps => ')
movement(numsteps2,coor,i)
if step2=='turn':
movement('turn',coor,i)
else:
print 'Illegal step choice.'
step3=raw_input('Step choice (turn or walk) => ')
print step3
step3=step3.lower()
if step3=='walk':
numsteps3= input('Number of steps => ')
movement(numsteps3,coor,i)
if step3=='turn':
movement('turn',coor,i)
else:
print 'Illegal step choice.'
print coor
You need to assign the value movement returns in the main body.
The variables you create in a function are destroyed once you exit the function.
Do
coor=movement(inputs...)
instead of
movement(inputs...)
coor is only defined within your function, so you can't access it directly from outside of the function without making it global, or by returning the value (as you are) and assigning it to a variable (which you aren't).
When you call the function, do it like so:
coords = movement('turn',coor,i)
Then you will be able see the current value when you try to print it using:
print coords

IndexError in unused conditional

def menurender():
global pos
global menulist
line1=menulist[pos]
if pos == len(menulist):
line2="back"
else:
line2=menulist[pos+1]
lcd.clear()
lcd.message(str(pos)+' ' +line1+ "\n"+str(pos+1)+' '+ line2)
In my block of code, I have a conditional in the menurender() function that checks to make sure that the list menulist has a valid index before referencing it, but i receive IndexError: list index out of range. I understand that the else statement is causing it, but I am confused because python shouldn't be executing it.
Full code
#!/usr/bin/python
#################################################
#IMPORTS#########################################
#################################################
from Adafruit_CharLCDPlate import Adafruit_CharLCDPlate
from Adafruit_I2C import Adafruit_I2C
#################################################
#OBJECTS#########################################
#################################################
lcd = Adafruit_CharLCDPlate()
#################################################
#VARIABLES#######################################
#################################################
#current button value
prevbutton = "NULL"
#for SELECT key and determining clicks
action = False
#variable for menu position
pos = 0
#on screen cursor 0 for top line, 1 for bottom line
cursor = 0
#Handles list structure and action when clicked
menulist= []
menulist.append("CPU")
menulist.append("RAM")
menulist.append("STORAGE")
menulist.append("NETWORK")
#get input from keys and return the currently pressed key
def buttonstatus():
bstatus = "Null"
if lcd.buttonPressed(lcd.SELECT) == True:
bstatus="SELECT"
elif lcd.buttonPressed(lcd.UP) == True:
bstatus="UP"
elif lcd.buttonPressed(lcd.DOWN) == True:
bstatus="DOWN"
elif lcd.buttonPressed(lcd.LEFT) == True:
bstatus="LEFT"
elif lcd.buttonPressed(lcd.RIGHT) == True:
bstatus="RIGHT"
return bstatus
#checks buttons pressed and converts that into action for top menu
def getinput():
global prevbutton
global pos
if buttonstatus() != prevbutton:
prevbutton = buttonstatus()
if buttonstatus() == "SELECT":
print "select"
elif buttonstatus() == "DOWN":
pos = pos + 1
elif buttonstatus() == "UP":
pos = pos -1
#elif buttonstatus() == "LEFT":
#print "left"
#elif buttonstatus() == "RIGHT":
#print "right"
#defines bounds for the position of the cursor
def posbounds():
global pos
global menulist
if pos < 0:
pos = 0
if pos == len(menulist):
pos = len(menulist)
#code renders the menu on the LCD
def menurender():
global pos
global menulist
line1=menulist[pos]
if pos == len(menulist):
line2="back"
else:
line2=menulist[pos+1]
lcd.clear()
lcd.message(str(pos)+' ' +line1+ "\n"+str(pos+1)+' '+ line2)
while True:
getinput()
posbounds()
menurender()
There are lots if values for pos != len(menulist) for which menulist[pos+1] gives an IndexError (including pos == len(menulist) - 1). You should check
if pos > (len(menulist) - 2):
You should probably change if pos == len(menulist): to if pos == len(menulist) - 1: if you want to check if pos is the index of the last element, or to if pos == len(menulist) - 2: if you want to check for the second to last element.
A better way of doing this may be by using a try ... except block.
try:
line2 = menulist[pos+1]
except IndexError:
# Out of range -> pos is greater than len(menulist)-1
line2 = 'back'
However - this doesn't seem lika a Pythonic way of doing anything at all in Python. Maybe you could tell us what you are trying to achieve, and someone here may propose a better way of doing it.

Categories

Resources