Python program freezes (using pandas and turtle modules) - python-3.x

The problem is my program freezes and I can't find what's wrong: I've being re-reading the code over and over, I've searched here and I've also googled and couldn't find a reason. I've seen a theme where the program of one coder froze because of an infinite loop and looked for it in my code but didn't see one. Here is the code below. Thank you for your time!
P.S. I've read the recommendation on less code in the question but it seemed to me that in my case every part is important, maybe that's because I'm a newbie yet.
First, I import the csv file with the names of the states. It has 50 states and it looks like this:
state,x,y
Alabama,139,-77
Alaska,-204,-170
Arizona,-203,-40
etc...
Now this is the code of my program:
import turtle
import pandas
screen = turtle.Screen()
screen.title("U.S. States Game")
# This belowe is the image with the blank_country where my guessed states names will be viewed. It use it as a background.
image = "blank_states_img.gif"
screen.addshape(image)
Tim = turtle.Turtle()
Tim.hideturtle()
Tim.penup()
turtle.shape(image)
print(screen.screensize())
states_data = pandas.read_csv("50_states.csv")
states_list = states_data.state.to_list()
number_of_states = len(states_list)
guessed_states = []
number_of_guessed_states = len(guessed_states)
answer_state = screen.textinput(title="Guess the state", prompt="What's another state's name?").title()
print(answer_state)
while number_of_guessed_states < 50:
if answer_state == "Exit":
missing_states = []
for state in states_list:
if state not in guessed_states:
missing_states.append(state)
new_data = pandas.DataFrame(missing_states)
new_data.to_csv("states_to_learn.csv")
break
if answer_state in states_list:
guessed_states.append(answer_state)
current_state = states_data[states_data.state == answer_state]
Tim.goto(int(current_state.x) - 15, int(current_state.y))
Tim.pendown()
Tim.write(answer_state, align="left", font=("Arial", 6, "bold"))
Tim.penup()
answer_state = screen.textinput(title=f"{number_of_guessed_states}/{number_of_states} states correct",
prompt="What's another state's name?").title()
states_list.pop(states_list.index(answer_state))
if number_of_guessed_states == number_of_states:
Tim.goto(-30, 0)
Tim.pendown()
Tim.write("Congratulations. This doesn't make you smart, but you've guessed all the states and won.",
font=("Arial", 10, "normal"))

One problem with your code is you lock in the value of number_of_guessed_states before the loop and never update it:
number_of_guessed_states = len(guessed_states)
so even though guessed_states is changing, number_of_guessed_states isn't. Also, this seems an odd choice:
screen.addshape(image)
...
turtle.shape(image)
vs. doing:
screen.bgpic(image)
Duplicating this prompt:
answer_state = screen.textinput(...).title()
seems error prone vs. having it once at the top of the loop. For example, here:
answer_state = screen.textinput(...).title()
states_list.pop(states_list.index(answer_state))
You remove the current answer but never removed the answer from before the loop. See if the following rework of your code runs as you intended:
from turtle import Screen, Turtle
import pandas
# This belowe is the image with the blank_country where my guessed states names will be viewed. It use it as a background.
image = "blank_states_img.gif"
screen = Screen()
screen.title("U.S. States Game")
screen.bgpic(image)
turtle = Turtle()
turtle.hideturtle()
turtle.penup()
states_data = pandas.read_csv("50_states.csv")
states_list = states_data.state.to_list()
number_of_states = len(states_list)
guessed_states = []
while len(guessed_states) < number_of_states:
answer_state = screen.textinput(title=f"{len(guessed_states)}/{number_of_states} states correct", prompt="What's another state's name?").title()
if answer_state == 'Exit':
missing_states = []
for state in states_list:
if state not in guessed_states:
missing_states.append(state)
new_data = pandas.DataFrame(missing_states)
new_data.to_csv("states_to_learn.csv")
screen.bye()
if answer_state in states_list:
guessed_states.append(states_list.pop(states_list.index(answer_state)))
current_state = states_data[states_data.state == answer_state]
turtle.goto(int(current_state.x) - 15, int(current_state.y))
turtle.write(answer_state, align='left', font=('Arial', 6, 'bold'))
if len(guessed_states) == number_of_states:
turtle.goto(-30, 0)
turtle.write("Congratulations. This doesn't make you smart, but you've guessed all the states and won.", font=('Arial', 10, 'normal'))
screen.mainloop()

Related

Python Print to String

I have some code that works perfectly, but am now trying to move it into a GUI. The issue so far is that I'm using pygame, and I have so far only managed to show text from a single assigned string.
# --- calculate all variables
for i in range(0, num_rows):
ticker['ticker{0}'.format(i+1)] = df['Ticker'][i] #could also use 'ticker'+str(i) instead of .format
tickerci['tickerci{0}'.format(i+1)] = df['Carbon Intensity'][i]
tickerobject['tickerobject{0}'.format(i+1)] = yf.Ticker(ticker['ticker{0}'.format(i+1)])
tickervalue['tickervalue{0}'.format(i+1)] = (tickerobject['tickerobject{0}'.format(i+1)]).info['marketCap']
tickerprice['tickerprice{0}'.format(i+1)] = (tickerobject['tickerobject{0}'.format(i+1)]).info['regularMarketPrice']
socialcost['socialcost{0}'.format(i+1)] = round((tickervalue['tickervalue{0}'.format(i+1)])*(tickerci['tickerci{0}'.format(i+1)])*carbonprice)
print ("the current price of ", ticker['ticker'+str(i+1)]," is €", tickerprice['tickerprice'+str(i+1)], ".")
print ("the current market cap of ", ticker['ticker'+str(i+1)]," is €", tickervalue['tickervalue'+str(i+1)], ".")
print ("the current social cost of ", ticker['ticker'+str(i+1)],"'s CO2 emissions is €", socialcost['socialcost'+str(i+1)])
print ()
# --- main ---
pygame.init()
screen = pygame.display.set_mode((960, 720))#, pygame.FULLSCREEN, vsync=1)
screen_rect = screen.get_rect()
font = pygame.font.SysFont(None, 50)
description = "put the text to display here"
desc_text = font.render(description, True, (255, 255, 255))
desc_rect = desc_text.get_rect(left=screen_rect.right)
Basically I want to assign the outputs of the print command in the loop to a string (or a string dictionary), which can then be called in the "description" part of the pygame module.
The end goal here is to have the strings that are currently printed, shown scrolling endlessly like a marquee.
There should be some way of modifying this basic bit of string io to work, I think, but I haven't been able to figure it out yet.
import io
def print_to_string(*args, **kwargs):
output = io.StringIO()
print(*args, file=output, **kwargs)
contents = output.getvalue()
output.close()
return contents

How to get the the vector of mouse position in python ursina

I'm making a Platform-Maker and I need to get the position of the mouse, then I place a object in there. Then I need to store it into a array so I can convert it to code later on. Right now I have to store it into a array, but when I do that it Gives me an empty array:
Edit On Image: This array is suppose to be containing A Vector3 Position where the mouse was clicked.
from ursina import *
from ursina.prefabs.sky import Sky
from ursina.shaders import basic_lighting_shader
app = Ursina(borderless = False)
window.fullscreen = True
window.fps_counter.enabled = False
editor = EditorCamera()
camera.fov = 90
class StartPlatform(Entity):
def __init__(self):
super().__init__(
parent = scene,
model = "cube",
position = (0, 0, 0),
scale = (10, 2, 10),
collider = "mesh",
shader = basic_lighting_shader,
texture = "white_cube",
color = color.lime
)
class AddPlatform(Entity):
def __init__(self, position = (0, 0, 0)):
super().__init__(
parent = scene,
model = "cube",
position = position,
scale = (10, 2, 10),
collider = "mesh",
shader = basic_lighting_shader,
texture = "white_cube",
color = color.azure
)
def input(key):
if held_keys["escape"]:
quit()
def update():
if held_keys["left mouse"]:
platform= AddPlatform(position = (mouse.world_point, mouse.world_point, mouse.world_point))
platforms = []
for i in platforms:
platform[i].append(platforms)
print(platforms)
Sky()
StartPlatform()
app.run()
Firt off: py position = (mouse.world_point, mouse.world_point, mouse.world_point)
is wrong, it should be
position = mouse.world_point
Secondly, this part doesn't make sense.
platforms = []
for i in platforms:
platform[i].append(platforms)
print(platforms)
Here's what it does:
platforms = [] Every frame, create a new list called platforms
for i in platforms: loop through every element. However you just set it to be an empty list, so this will just be skipped since there's nothing there.
platform[i].append(platforms) platform is a Entity you instantiated earlier. What is [i] of that? You can't get a member of a an entity that way.
print(platforms) This would return [] since it's not been changed.
If what you want to do is to add the platform you created to a list, you'd define the list outside of the function and add the append the platform to it. You're also using update for this, which gets called every frame. This means you'll probably be creating about 60 platforms every second you're holding the mouse button down. You probably want to use input instead.
platforms = []
def input(key):
if key == 'left mouse down' and mouse.world_point:
platform = AddPlatform(position=mouse.world_point)
platforms.append(platform)

I have a total of two errors, return outside function as well as error with defining variables

I am having trouble with coding this as i am quite new, my code is supposed to take data, return average, as well as make a chart for the information and plot the peaks/valleys of the data
I don't know why it isn't returning and that fault is what makes the code faulty towards the end, the only part that shows error is the code that is supposed to find the peaks/valley values of my code. It also shows invalid syntax when I try to develop a variable (more specifically 'original_data')
EDIT: Thanks to Jono and Ken, I have fixed some of my code, but I checked the values of my lists and they only have one value stored in each, so its not printing all the peaks/valleys of the dataset i had. I getting KeyError: -331 and i can't find results as to how to fix it
# My Favorite Function
import os
clear = lambda: os.system('cls')
clear()
#import modules
import pandas as pd
import matplotlib.pyplot as plt
#key variables
data_set = pd.read_csv('C:/Users/sanderj/Documents/Work/Work_Experience/Day4.csv')
data = data_set["Data"]
peaks = []
valleys = []
#loop functions
for x in data:
if data[x] == data[0] and data[x] > data[x+1]:
peaks.append(x)
elif data[x] > data[x+1] and data[x] > data[x-1]:
peaks.append(x)
else:
continue
for x in data:
if data[x] == data[0] and data[x] < data[x+1]:
valleys.append(x)
elif data[x] < data[x+1] and data[x] < data[x-1]:
valleys.append(x)
else:
continue
#establishing points
a = peaks
b = valleys
plt.plot(a, b, 'ro')
plt.axis([ 0, 1024, -1000, 1000])
plt.title("Peaks and Valleys")
#final
clear()
plt.show()

Defining a file descriptor in python3 - to work with pyudev/evdev

I'm currently trying to detect the connexion of a bluetooth button on a raspberry pi 3 (that part works) and once connected, detect when the button is pressed (that part doesn't work).
I've started with the code provided by evdev and tried to tweak it for my use (see hereunder), but I cannot manage to create the correct file descriptor to use with select (if I correctly understood what's happening).
import functools
import pyudev
import evdev
from select import select
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem='bluetooth')
monitor.start()
fds = {monitor.fileno(): monitor}
finalizers = []
while True:
r, w, x = select(fds, [], [])
if monitor.fileno() in r:
r.remove(monitor.fileno())
for udev in iter(functools.partial(monitor.poll, 0), None):
devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
for device in devices:
if device.name.strip() == 'AB Shutter3':
if udev.action == u'add':
print('Device added: %s' % udev)
fds[dev.fd] = device #This here breaks. dev.fd undefined.
break
if udev.action == u'remove':
print('Device removed: %s' % udev)
def helper():
global fds
fds = {monitor.fileno(): monitor}
finalizers.append(helper)
break
for fd in r:
dev = fds[fd]
for event in dev.read():
print(event)
for i in range(len(finalizers)):
finalizers.pop()()
The problem is that when I try to add the device, dev.fd is not defined. I've tried to define it, but I've got no idea how to define a file descriptor. What should I do ?
Device added: Device('/sys/devices/platform/soc/3f201000.serial/tty/ttyAMA0/hci0/hci0:64')
Traceback (most recent call last):
File "dev_status.py", line 27, in <module>
fds = {dev.fd:device} #This here breaks. dev.fd undefined.
NameError: name 'dev' is not defined
Other information : Raspberry Pi 3 running Raspbian Strech & Python 3.5.3
Also, this is my first question on Stack Overflow, so if anything's missing or could be more detailed, feel free to mention it.
Thanks,
Pôm'
OK, I've managed to find a solution. Here it is, if it can help anybody.
#!/usr/bin/env python3
import functools
import pyudev
import evdev
from select import select
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem='bluetooth')
monitor.start()
fds = {monitor.fileno(): monitor}
time = 0.0
udevices = context.list_devices(subsystem='bluetooth')
link_up = False
for udevice in udevices :
if udevice.device_type == 'link' and udevice.is_initialized :
link_up = True
print('yiha')
evdevices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
if len(evdevices) > 0:
for evdevice in evdevices:
if evdevice.name.strip() == 'AB Shutter3' and link_up:
print('Device existing: %s' % udevice)
fds[evdevice.fileno()] = evdevice
while True:
r, w, x = select(fds, [], [])
if monitor.fileno() in r:
for udevice in iter(functools.partial(monitor.poll, 0), None):
evdevices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
for evdevice in evdevices:
if evdevice.name.strip() == 'AB Shutter3':
if udevice.action == u'add':
print('Device added: %s' % udevice)
fds[evdevice.fileno()] = evdevice
break
if udevice.action == u'remove':
print('Device removed: %s' % udevice)
fds.pop(evdevice.fileno(),None)
break
if evdevice.fileno() in r:
dev = fds[evdevice.fileno()]
for event in dev.read():
if event.type == evdev.ecodes.EV_KEY:
data = evdev.categorize(event)
if data.keystate == 1 and data.event.timestamp() - time > 0.05 :
if data.scancode == 115:
print("Big button")
elif data.scancode == 28:
print("Small button")
time = data.event.timestamp()
I'm pretty sure I will look at this in horror in a few months' time, but for the moment, it does the job.

Shorten a Python turtle program for a house

Below is my turtle program for drawing a yellow house. I can't figure out a way to create a for loop in order to keep the turtle program short. Does anyone have any idea on how to create a loop for the program below?
import turtle
import math
def yellowHouse () :
wn=turtle.Screen()
wn.title("Yellow House")
wn.bgcolor("Blue")
#sideLength = 200
house=turtle.Turtle()
Diagonal_length= 0.5*math.sqrt(2 *(200 ** 2 ))
house.pensize(5)
house.speed(4.6)
house.color("Yellow")
house.left(90)
house.forward(200)
house.right (135)
house.forward(Diagonal_length)
house.right(90)
house.forward(Diagonal_length)
house.left(135)
house.forward(200)
house.left(135)
house.forward(Diagonal_length)
house.right(90)
house.forward(Diagonal_length)
house.left(135)
house.forward(200)
house.right(135)
house.forward(Diagonal_length)
house.right(90)
house.forward(Diagonal_length)
house.right(45)
house.forward(200)
house.left(90)
wn.mainloop()
yellowHouse ()
Since you're building the house out of one shape repeated, I'd opt for stamping over drawing:
from turtle import Turtle, Screen
def yellowHouse(side_length):
wn.register_shape("brick", ((0, 0), (-0.5, -0.5), (0.5, -0.5)))
house = Turtle('brick', visible=False)
house.shapesize(stretch_wid=side_length, outline=5)
house.color("yellow", wn.bgcolor())
house.penup()
for angle in range(360, 0, -90):
house.setheading(angle)
house.stamp()
house.forward(side_length)
house.stamp()
wn = Screen()
wn.title("Yellow House")
wn.bgcolor("blue")
yellowHouse(200)
wn.exitonclick()
This solution prints the house in the center of the screen. You pass in the size of the house you want. (And it's about 1/3 less code.)
Creating a loop is a good way to make the program code short, you can achieve that in many ways, in your example:
Method 1
use loop to draw the square, then draw the diagonal cross lines and the top
import turtle
def yellowHouse() :
wn=turtle.Screen()
wn.title("Yellow House")
wn.bgcolor("Blue")
house=turtle.Turtle()
house.pensize(5)
house.speed(4.6)
house.color("Yellow")
side = 200
diag = (2*(side**2))**0.5
ang = 90
for i in range(4):
house.fd(side)
house.lt(ang)
house.lt(ang/2)
moves = [(diag,ang),(diag/2,ang),(diag/2,ang),(diag,ang)]
for (move,turn) in moves:
house.fd(move)
house.lt(turn)
wn.mainloop()
yellowHouse()
Method 2
use loop through array of steps to draw the whole shape
import turtle
def yellowHouse() :
wn=turtle.Screen()
wn.title("Yellow House")
wn.bgcolor("Blue")
house=turtle.Turtle()
house.pensize(5)
house.speed(4.6)
house.color("Yellow")
side = 200
diag = (2*(side**2))**0.5
ang = 90
moves = [(side,ang),(side,ang),(side,ang),(side,ang),
(0,ang/2),(diag,ang),(diag/2,ang),(diag/2,ang),(diag,ang)]
for (move,turn) in moves:
house.fd(move)
house.lt(turn)
wn.mainloop()
yellowHouse()
Notice we didn't need to import math, since we only need sqrt() to calculate the square root which we can achieve using the ** exponent operator sqrt(x) is same as x**0.5
here is your code with forloop, you have to maintain event and event value index only..
import turtle
import math
def yellowHouse() :
wn=turtle.Screen()
wn.title("Yellow House")
wn.bgcolor("Blue")
#sideLength = 200
house=turtle.Turtle()
Diagonal_length= 0.5*math.sqrt(2 *(200 ** 2 ))
event = ["pensize","speed","color","left","forward","right","forward","right","forward","left","forward","left","forward","right","forward","left","forward","right","forward","right","forward","right","forward","left"]
event_val = [5,4.6,"Yellow",90,200,135,Diagonal_length,90,Diagonal_length,135,200,135,Diagonal_length,90,Diagonal_length,135,200,135,Diagonal_length,90,Diagonal_length,45,200,90]
event_zip = zip(event, event_val)
for i,j in event_zip:
if type(j).__name__ == "str":
eval("house.{}('{}')".format(i,j))
else:
eval("house.{}({})".format(i,j))
yellowHouse()

Resources