Incrementing variable increments before draw function runs - python-3.x

I am a new programmer using code sculptor with python 3. I have an animation project and one of the requirements is to change the background between two different settings 100 times
At the bottom, I've added print(i) to show what the problem with my code is. Basically, the "i" variable gets incremented, but it doesn't run the draw function, so the variable is incremented without the background changing. I've tried changing the positions of the draw function and nothing seems to be working. I am wondering if someone on this site could give me pointers on what to do in this situation. My overall goal is to run the program and have the background change as the train moves. You can see the program running by changing the values in the for loops to low values such as 1 and 1.
<pre>import simplegui
import time
def draw_handler(canvas):
global x
global flag
x = x+3
flag = flag + 2
if flag >= 320:
x = x-930
flag = -300
canvas.draw_circle([550,50], 40, 4, "yellow", "yellow")
points = [[0,500], [0,600], [600,600], [600,500]]
canvas.draw_polygon(points, 1, "black", "sienna")
points2 = [[155+x,325], [155+x,450], [455+x,450], [455+x,325]]
canvas.draw_polygon(points2, 1, "black", "deepskyblue")
points3 = [[155+x,250],[155+x,325],[235+x,325],[235+x,250]]
canvas.draw_polygon(points3, 1, "black", "deepskyblue")
canvas.draw_circle([190+x,470], 35, 4, "dimgrey","lightgray")
canvas.draw_circle([267+x,470], 35, 4, "dimgrey","lightgray")
canvas.draw_circle([344+x,470], 35, 4, "dimgrey","lightgray")
canvas.draw_circle([421+x,470], 35, 4, "dimgrey","lightgray")
points4 = [[120+x,225],[120+x,255],[265+x,255],[265+x,225]]
canvas.draw_polygon(points4, 1, "black", "black")
points5 = [[425+x,235], [425+x,325], [445+x,325], [445+x,235]]
canvas.draw_polygon(points5, 1, "black", "black")
canvas.draw_line([410+x,230], [460+x, 230], 7, "black")
canvas.draw_line([175+x,350], [427+x, 350], 2, "red")
canvas.draw_line([175+x,350], [175+x, 420], 2, "red")
canvas.draw_line([427+x,350], [427+x, 420], 2, "red")
canvas.draw_line([175+x,420], [427+x, 420], 2, "red")
global color
color = ""
global y
global i
i = 0
for i in range(100):
for i in range(20000):
i = i + 10
print(i)
if i <= 10000:
color = "aliceblue"
elif i > 10000:
color = "red"
elif i > 20000:
i = 0
frame = simplegui.create_frame('Testing', 600, 600)
frame.set_draw_handler(draw_handler)
frame.set_canvas_background(color)
x = 0
flag = 0
frame.start()</pre>
edit: Here is a direct link to the code in CodeSkulptor - https://py3.codeskulptor.org/#user302_ZF0cMFUoOAK9PvH.py

Related

How to separate 2 label far apart with tkinter Python?

I would like to separate 2 elements far apart in Tkinter.
I have tried using column such that label_1 is column = 0, row = 0 and label 2 is column 19 and label 3 is column 20 but this still results in them being side by side in the middle. I have set my frame with pack(side =TOP).
I also tried using pack on my label such that label 2 & 3 are right and label 1 is left but still ended up with an unexpected result.
Hence is there a way to separate the 2 elements far apart?
Example
First I use a frame using pack() to display.
self.frameTop.pack(fill=BOTH, expand=NO)
Apparently the condition expand and fill played an important role in display the expected result.
The bottom shows the code for the layout of each element and its anchoring
# Monty Logo
self.icon = Label(self.frameTop, image = self.iconImage, font=('Zilla Slab', 16, 'bold'), borderwidth = 0, highlightthickness = 0, bg="#FFFFFF")
self.icon.pack(padx = 8, pady = 8, side = LEFT, anchor=NW)
# Use a canvas line to deine the cutting
self.labelSeperator = Separator(self.window, orient="horizontal")#Label(self.frameTop, bg="#000000", height= 2, width = int(ws)).pack(side= BOTTOM)
self.labelTitle_time = Label(self.frameTop, font=('Zilla Slab', 16), anchor = "w", borderwidth = 0, highlightthickness = 0, bg="#FFFFFF")
self.labelTitle_time.pack(padx=8,side = RIGHT, anchor=CENTER)
self.labelTitle_day = Label(self.frameTop, font=('Zilla Slab', 16, 'bold'), borderwidth = 0, highlightthickness = 0,bg="#FFFFFF")
self.labelTitle_day.pack(side = RIGHT, anchor=CENTER)

Making visible lifebars via checking for colision in python 3.5 tkinter

I'm trying to use check for collision tricks for tkinter. (I don't use pygame) but I need a visible life bar that can change colours. Here's my script:
#Tkinter loader
from tkinter import *
HEIGHT = 500
WIDTH = 800
window = Tk()
window.title ('VOID')
c = Canvas (window, width=WIDTH, height=HEIGHT, bg= 'black')
c.pack()
ship_id = c.create_polygon (5, 5, 5, 25, 25, 25, 25, 5, fill='white')
SHIP_R = 25
MID_X = WIDTH / 2
MID_Y = HEIGHT / 2
c.move (ship_id, MID_X, MID_Y)
# Movment control
SHIP_SPD = 10
def move_ship(event):
if event.keysym == 'w':
c.move (ship_id, 0, -SHIP_SPD)
elif event.keysym == 's':
c.move (ship_id, 0, SHIP_SPD)
elif event.keysym == 'a':
c.move (ship_id, -SHIP_SPD, 0)
elif event.keysym == 'd':
c.move (ship_id, SHIP_SPD, 0)
c.bind_all ('<Key>', move_ship)
# Spawning system (needs copying)
from random import randint
bub_id = list()
bub_r = list()
bub_speed = list()
MIN_BUB_R = 20
MAX_BUB_R = 30
MAX_BUB_SPD = 20
GAP = 100
def create_bubble():
x = WIDTH + GAP
Y = randint (0, HEIGHT)
r = randint (MIN_BUB_R, MAX_BUB_R)
id1 = c.create_polygon (5, 5, 5, 25, 25, 25, 25, 5, fill='lime')
bub_id.append(id1)
bub_r.append(r)
bub_speed.append(randint(1, MAX_BUB_SPD))
def move_bubbles():
for i in range(len(bub_id)):
c.move(bub_id[i], -bub_speed[i], 0)
from time import sleep, time
BUB_CHANCE = 10
#MAIN GAME LOOP
while True:
if randint (1, BUB_CHANCE) == 1:
create_bubble()
move_bubbles()
window.update()
sleep(0.01)
With the fact that both lifebars will go up and down, but at different rates. (so that health takes smaller steps than level.) also with a system were if health or level go to 0 or 100 precent, than something happens like steps. (so you go down a level if the level bar goes to low, and go up a level with the background changing with the lifebar levels.) and the colour will pulse depending on the level you are at.
Thanks.

VPython startMenu

My main program for a Bloxorz-Type program is working fine. Only issue I have is having to implement a system where the game shows a message on the screen if the block falls off the map, and a gameFinished message on the screen when the block hits the hole vertically. I'm thinking the way it would work is to match the coordinates of the hole and if the coordinates of the hole match the square-bases of the block, it will show a message.
My first real issue is being able to display a startMenu message, where it will display "Press S to Start" and "press Q to quit". I know how to use the scene.kb.getkey(), the only problem is displaying the text on the screen, which i will implement into my main while True loop. Here is my code:
from __future__ import division, print_function
from visual import *
import math, sys
from visual.graph import *
from sys import exit
"""Necessary Python Libraries"""
# top, left, bottom, right, front, back
tlbrfb = ( 2.0, -0.5, 0.0, 0.5, 0.5, -0.5 ) #the area that the block covers (dimensions)
Top = 0
Left = 1
Bottom = 2
Right = 3
Front = 4
Back = 5
"""Modules defining the Movement of the Block"""
def moveRight():
global tlbrfb
for r in range(0, 9):
rate(30)
block.rotate( angle = pi/18, axis = vector( 0, 0, -1), origin = vector(tlbrfb[Right], 0, 0) ) #pi/18 = 10degrees,
tlbrfb = (tlbrfb[Right]-tlbrfb[Left], tlbrfb[Right], 0, tlbrfb[Right]+tlbrfb[Top], tlbrfb[Front], tlbrfb[Back]) #update block's state of stance
def moveDown():
global tlbrfb
for r in range(0, 9):
rate(30)
block.rotate( angle = pi/18, axis = vector( +1, 0, 0), origin = vector(0, 0, tlbrfb[Front]) )
tlbrfb = (tlbrfb[Front]-tlbrfb[Back], tlbrfb[Left], 0, tlbrfb[Right], tlbrfb[Front]+tlbrfb[Top], tlbrfb[Front])
def moveLeft():
global tlbrfb
for r in range(0, 9):
rate(30)
block.rotate( angle = pi/18, axis = vector( 0, 0, +1), origin = vector(tlbrfb[Left], 0, 0) )
tlbrfb = (tlbrfb[Right]-tlbrfb[Left], tlbrfb[Left]-tlbrfb[Top], 0, tlbrfb[Left], tlbrfb[Front], tlbrfb[Back] )
def moveUp():
global tlbrfb
for r in range(0, 9):
rate(30)
block.rotate( angle = pi/18, axis = vector( -1, 0, 0), origin = vector(0, 0, tlbrfb[Back]) )
tlbrfb = (tlbrfb[Front]-tlbrfb[Back], tlbrfb[Left], 0, tlbrfb[Right], tlbrfb[Back], tlbrfb[Back]-tlbrfb[Top])
level1 = [ #array on the tile placement
[1,1,1,0,0,0,0,0,0,0],
[1,1,1,1,1,0,0,0,0,0],
[1,1,1,1,1,1,1,1,1,0],
[0,0,0,0,0,1,1,0,1,1],
[0,0,0,0,0,0,1,1,1,0]
]
def draw_level(array):
for y in range(0, len(array)):
for x in range(0, len(array[y])):
if array[y][x] == 1:
box( pos=vector(x, -0.1, y), length=0.9, width = 0.9, height = 0.2, color = vector(0.9, 0.8, 0.8))
block = box( pos=vector(0,1,0), length = 1, width = 1, height = 2, color = vector(0.9, 0.9, 0.5))
def handle_events():
key = scene.kb.getkey()
if key =="up":
moveUp()
elif key =="down":
moveDown()
elif key == "left":
moveLeft()
elif key == "right":
moveRight()
elif key == "q":
quit()
elif key == "escape":
quit()
def mainGameLoop():
while True:
scene.center = vector(4.5, 0, 2)
scene.forward = scene.center - vector(2, 6, 10)
scene.background = vector(0.57, 0.2, 0.2)
draw_level(level1) #draw mapout
handle_events()
while True:
mainGameLoop()
handle_events()
print(block.pos)

tkinter histogram prints downwards

I am trying to draw two histograms alongside one another using tkinter canvas. Everything sort of works ( looks extremely scruffy at the moment) but the histograms are drawn downwards. I have tried making the y0 value negative, but then nothing at all is drawn.
I am using two lists of numerical data, the first with 50 observations and the other with eleven observations, the scales are not the same, but it is the qualitative effect I want at the moment.
The offending code is as follows:
root = Tk()
canvas = Canvas(root, width=620, height=400, background = "salmon")
canvas.grid()
# draw x-axis lines
canvas.create_line(0,2, 500, 0, width = 2, fill = "firebrick")
canvas.create_line(505,2, 610, 0, width = 2, fill = "dark slate blue")
# draw histograms
for idx in range(len(main_counts[0])):
canvas.create_rectangle(idx*10, main_counts[0][idx], 10 +(idx*10), 0, fill = "medium sea green", outline = "firebrick")
canvas.create_text(idx*10 + 8, 40, text = idx + 1, font = ("Comic sans MS",8), fill = "firebrick")
for idx in range(len(star_counts[2])):
canvas.create_rectangle((505 + idx*10), star_counts[2][idx], (515 + (idx*10)), 0, fill = "gold", outline = "dark slate blue")
canvas.create_text(505 + idx*10 + 8, 120, text = idx + 1, font = ("Comic sans MS", 8) , fill = "dark slate blue")
root.mainloop()
I know that I am missing something quite simple and obvious to all of you, but I just can't see it or the way to make my y0 negative which will presumably solve the problem. I can also not see my x-axes, but that may be because they are occluded by the histogram bars.
Many thanks for your patience and help! Any other suggestions about formatting the graphs will be welcomed including suggestions of best font to use for small digit screen display
The system coordinates start in the upper-left corner so you should write something like:
main_counts =[[10, 20, 30]]
for idx in range(len(main_counts[0])):
canvas.create_rectangle(idx*10, 200 -main_counts[0][idx], 10 +(idx*10), 200, fill = "medium sea green", outline = "firebrick")
canvas.create_text(idx*10 + 8, 210, text = idx + 1, font = ("Comic sans MS",8), fill = "firebrick")
You can use enumerate for more readable code:
for idx, val in enumerate(main_counts[0]):
canvas.create_rectangle(idx*10, 200 -val, 10 +(idx*10), 200, fill = "medium sea green", outline = "firebrick")
canvas.create_text(idx*10 + 8, 210, text = idx + 1, font = ("Comic sans MS",8), fill = "firebrick")
In simple terms - Try to create the histogram from a point on the coordinate according to your value as your second argument in rectangle_crete() function, and then go upto the point where you want your base of the histogram should,which will me constant for all your histograms. Because Tkinter coordinates starts from (0,0) and goes from up to down.
An example code is here -
from Tkinter import *
from random import randint # for testing histogram
master = Tk()
w = Canvas(master, width=1000, height=500)
w.pack()
start_point = 70
padding_y = 450
width = 50
height = 450
list = []
for i in range(1,10):
list.append(randint(1,4))
for i in range(1,10):
end_point = start_point+width
w.create_rectangle(start_point, list[i-1]*100, end_point, height, fill="blue")
start_point += width+20
mainloop()

Can i make the variable used in commands lock when using buttons and changing variables

I am making a Rubik's cube solver using Python and Tkinter and I have encountered a problem when trying to reduce the size of my code.
The peice of code I am showing is for getting to know the situation of the Cube. It draws a net of a cube using buttons with images, but they don't have fixed variables and so when i change a the variable the are defined with, the command variable also changes. is there a way to get round it simply
#Defines Images
White = PhotoImage(file="White.gif")
Yellow = PhotoImage(file="Yellow.gif")
Blue = PhotoImage(file="Blue.gif")
Green = PhotoImage(file="Green.gif")
Red = PhotoImage(file="Red.gif")
Orange = PhotoImage(file="Orange.gif")
#List with Images, positions and values
Colours = [[White, 550, 40, 0, "White"],
[Yellow, 550, 520, 1, "Yellow"],
[Blue, 790, 280, 2, "Blue"],
[Green, 310, 280, 3, "Green"],
[Red, 550, 280, 4, "Red"],
[Orange, 70, 280, 5, "Orange"]]
#Testing Function
def swicth(a):
global Colours
print(Colours[a][4])
#Creates the Buttons in specific locations
for i in Colours:
for j in range(3):
yOffset = (j * 80) + i[2]
for k in range(3):
xOffset = (k * 80) + i[1]
Button(Solver, image = i[0], command=lambda:swicth(i[3])).place(x=xOffset, y=yOffset)
This code works for the most part, but all the buttons have the same outcome of 5. I have got ways of getting around by having 6 sets of for loops for the six colours, but it would be great if anyone could help
change your lambda to this:
..., command=lambda arg=i[3]:swicth(arg)
This will cause i[3] to be bound to the lambda at the time the lambda is created.

Resources