Related
I am trying to make a platforming game and I keep getting this error when I tried to add particles for when the character jumps, and I can't figure it out. Everytime I try and jump with the character the error pops up. I will need some help in order to fix this.
Code for the Level
import pygame
# Importing the necessary files
from tiles import Tile
from settings import tile_size, screen_width
from player import Player
from particles import ParticleEffect
class Level:
def __init__(self, level_data, surface):
# Level setup
self.display_surface = surface
self.setup_level(level_data)
self.world_shift = 0
self.current_x = 0
# Particles
self.dust_sprite = pygame.sprite.GroupSingle()
def setup_level(self, layout):
self.tiles = pygame.sprite.Group()
self.player = pygame.sprite.GroupSingle()
for row_index, row in enumerate(layout):
for column_index, cell in enumerate(row):
x = column_index * tile_size
y = row_index * tile_size
if cell == "X":
tile = Tile((x, y), tile_size)
self.tiles.add(tile)
if cell == "P":
player_sprite = Player((x, y), self.display_surface, self.jump_particles)
self.player.add(player_sprite)
def jump_particles(self, pos):
jump_particle_sprite = ParticleEffect(pos, 'Jump')
self.dust_sprite.add(jump_particle_sprite)
def scroll_x(self):
player = self.player.sprite
player_x = player.rect.centerx
direction_x = player.direction.x
if player_x < screen_width / 4 and direction_x < 0:
self.world_shift = 8
player.speed = 0
elif player_x > screen_width - (screen_width / 4) and direction_x > 0:
self.world_shift = -8
player.speed = 0
else:
self.world_shift = 0
player.speed = 8
# Checks for horizontal collisions with the tiles
def horizontal_collision(self):
player = self.player.sprite
player.rect.x += player.direction.x * player.speed
for sprite in self.tiles.sprites():
if sprite.rect.colliderect((player.rect)):
if player.direction.x < 0:
player.rect.left = sprite.rect.right
player.on_left = True
self.current_x = player.rect.left
elif player.direction.x > 0:
player.rect.right = sprite.rect.left
player.on_right = True
self.current_x = player.rect.right
if player.on_left == True and (player.rect.left < self.current_x or player.direction.x >= 0):
player.on_left = False
if player.on_right == True and (player.rect.left > self.current_x or player.direction.x <= 0):
player.on_right = False
def vertical_collision(self):
player = self.player.sprite
player.apply_gravity()
for sprite in self.tiles.sprites():
if sprite.rect.colliderect((player.rect)):
if player.direction.y > 0:
player.rect.bottom = sprite.rect.top
player.direction.y = 0
player.on_ground = True
elif player.direction.y < 0:
player.rect.top = sprite.rect.bottom
player.direction.y = 0
player.on_ceiling = True
if player.on_ground == True and player.direction.y < 0 or player.direction.y > 1:
player.on_ground = False
if player.on_ceiling == True and player.direction.y > 0:
player.on_ceiling = False
def run(self):
# Tiles for the level
self.tiles.update(self.world_shift)
self.tiles.draw(self.display_surface)
self.scroll_x()
# Dust Particles
self.dust_sprite.update(self.world_shift)
self.dust_sprite.draw(self.display_surface)
# Player for the level
self.player.update()
self.horizontal_collision()
self.vertical_collision()
self.player.draw(self.display_surface)
Code for the Class ParticleEffect
import pygame
from support import import_folder
class ParticleEffect(pygame.sprite.Sprite):
def _init__(self, pos, type):
super().__init__()
self.frame_index = 0
self.animation_speed = 0.5
if type == 'Jump':
self.frames = import_folder('Hero/Dust Particles/Jump')
if type == 'Land':
self.frames = import_folder('Hero/Dust Particles/Land')
self.image = self.frames[self.frame_index]
self.rect = self.image.get_rect(center = pos)
def animate(self):
self.frame_index += self.animation_speed
if self.frame_index >= len(self.frames):
self.kill()
else:
self.image = self.frames[int(self.frame_index)]
def update(self, x_shift):
self.animate()
self.rect.x += x_shift
import_folder is just a class used for loading images.
The full error is
File "C:\School\KS5\Computer Science\Project\Coding\pythonProject\player.py", line 109, in get_input
self.jump_particles(self.rect.midbottom)
File "C:\School\KS5\Computer Science\Project\Coding\pythonProject\level.py", line 35, in jump_particles
jump_particle_sprite = ParticleEffect(pos, 'Jump')
File "C:\School\KS5\Computer Science\Project\Coding\pythonProject\venv\lib\site-packages\pygame\sprite.py", line 115, in __init__
self.add(*groups)
File "C:\School\KS5\Computer Science\Project\Coding\pythonProject\venv\lib\site-packages\pygame\sprite.py", line 133, in add
self.add(*group)
File "C:\School\KS5\Computer Science\Project\Coding\pythonProject\venv\lib\site-packages\pygame\sprite.py", line 133, in add
self.add(*group)
TypeError: pygame.sprite.Sprite.add() argument after * must be an iterable, not int
You have a typo in the __init__() method in your ParticleEffect class that is causing this issue.
The def _init__(self, pos, type) is missing a underscore _ at the beginning.
I'm trying to create a function that tells me if two canvas objects(in my code, rec and block) touch each other in Tkinter. I tried to do so with the information of their coordinates but it doesn't seem to work. Can you please help me?
The function will be used in snake which I'm creating in the code below, so don't ask my why the code is so long.
The function is in the line 119, same_poz
This is my code:
from tkinter import *
import time
import random
import threading
root = Tk()
root.title('Snake')
x, y = 484, 484
recX, recY = x // 2, y // 2
recW, recH = recX + 22, recY + 22
randoms = []
for i in range(484):
if i % 11 == 0:
randoms.append(i)
blockX, blockY = random.choice(randoms), random.choice(randoms)
blockW, blockH = blockX + 22, blockY + 22
c = Canvas(root, bg='black', width=x, height=y)
c.pack()
class Snake(threading.Thread):
def __init__(self, c, x, y, recX, recY, recW, recH, blockX, blockY, blockW, blockH):
super(Snake, self).__init__()
self.c = c
self.x = x
self.y = y
self.recX = recX
self.recY = recY
self.recW = recW
self.recH = recH
self.blockW = blockW
self.blockH = blockH
self.rec = c.create_rectangle(recX, recY, recW, recH, fill='red', outline='white')
self.blockX = blockX
self.blockY = blockY
self.block = c.create_rectangle(blockX, blockY, blockW, blockH, fill='green',
outline='white')
self.moving_right = False
self.moving_left = False
self.moving_up = False
self.moving_down = False
self.moving = False
def movingright(self):
self.moving_right = True
self.moving_left = False
self.moving_up = False
self.moving_down = False
self.moving = True
c.move(self.rec, 11, 0)
self.after4 = root.after(150, self.movingright)
def movingleft(self):
self.moving_left = True
self.moving_left = False
self.moving_up = False
self.moving_down = False
self.moving = True
c.move(self.rec, -11, 0)
self.after3 = root.after(150, self.movingleft)
def movingup(self):
self.moving_up = True
self.moving_right = False
self.moving_left = False
self.moving_up = False
self.moving = True
c.move(self.rec, 0, -11)
self.after = root.after(150, self.movingup)
def movingdown(self):
self.moving_down = True
self.moving_right = False
self.moving_left = False
self.moving_down = False
self.moving = True
c.move(self.rec, 0, 11)
self.after2 = root.after(150, self.movingdown)
def stop(self):
self.moving_right = False
self.moving_left = False
self.moving_up = False
self.moving_down = False
self.moving = False
try:
root.after_cancel(self.after)
except AttributeError:
pass
try:
root.after_cancel(self.after2)
except AttributeError:
pass
try:
root.after_cancel(self.after3)
except AttributeError:
pass
try:
root.after_cancel(self.after4)
except AttributeError:
pass
def move(self, n):
if n.keysym == 'Up':
self.stop()
self.movingup()
if n.keysym == 'Down':
self.stop()
self.movingdown()
if n.keysym == 'Right':
self.stop()
self.movingright()
if n.keysym == 'Left':
self.stop()
self.movingleft()
def same_poz(self):
if self.blockY == self.recY:
self.helpY = random.randint(10, self.y - self.blockY)
self.c.move(self.block, 0, self.helpY)
if self.blockX == self.recY:
self.helpX = random.randint(10, self.x - self.blockX)
self.c.move(self.block, 0, self.helpX)
if self.blockW == self.recW:
self.helpW = random.randint(10, self.x - self.blockW)
self.c.move(self.block, 0, self.helpW)
if self.blockH == self.recH:
self.helpH = random.randint(10, self.y - self.blockH)
self.c.move(self.block, 0, helpH)
cube = Snake(c, x, y, recX, recY, recW, recH, blockX, blockY, blockW, blockH)
cube.start()
cube.c.bind_all('<Key>', cube.move, cube.stop)
cube.c.bind_all('<Key>', cube.moving_left, cube.moving_right)
cube.c.bind_all('<Key', cube.moving_up, cube.moving_down)
cube.c.bind(cube.same_poz)
root.mainloop()
There are way too many problems with your code, with what you provided. I do not know why you are programming using Tkinter when you are still lacking the basics of Python. (Don't mean to sound harsh)
I do not know why you decided to inherit from threading.Thread when
you do not have any use for anything Thread provides in that
class.
Way too many instance parameters which you have no use for at all, and too many instance parameters that you have to change every single time.
Not using elif and instead using if constantly.
If you are using a thread to handle Tkinter changes outside of mainloop, there is no need to use .after since it basically does that.
Tkinter has dedicated bindings for every single key, including combinations of keys. There is no need to catch every single key event.
Use if __name__ == '__main__': if you are working with a single script, for testing it.
Some reading material on Tkinter - http://effbot.org/tkinterbook/
Here is a minimal rework of the code, that is working.
import time
import random
import threading
from tkinter import *
MOVINGUP = 'u'
MOVINGDOWN = 'd'
MOVINGLEFT = 'l'
MOVINGRIGHT = 'r'
NOTMOVING = '0'
class Snake:
def __init__(self, root, recX, recY, recW, recH, blockX, blockY, blockW, blockH):
self.root = root
self.c = Canvas(root, bg='black', width=x, height=y)
self.c.pack()
self.rec = self.c.create_rectangle(recX, recY, recW, recH, fill='red', outline='white')
self.block = self.c.create_rectangle(blockX, blockY, blockW, blockH, fill='green', outline='white')
self.direction = NOTMOVING
self.root.bind('<Up>', lambda e: self.moveset(MOVINGUP))
self.root.bind('<Down>', lambda e: self.moveset(MOVINGDOWN))
self.root.bind('<Left>', lambda e: self.moveset(MOVINGLEFT))
self.root.bind('<Right>', lambda e: self.moveset(MOVINGRIGHT))
def moveset(self, direction):
self.direction = direction
def movement(self):
if self.direction == MOVINGUP:
self.c.move(self.rec, 0, -11)
elif self.direction == MOVINGDOWN:
self.c.move(self.rec, 0, 11)
elif self.direction == MOVINGLEFT:
self.c.move(self.rec, -11, 0)
elif self.direction == MOVINGRIGHT:
self.c.move(self.rec, 11, 0)
self.same_poz()
def run(self):
while True:
time.sleep(0.15)
self.movement()
def same_poz(self):
# Snake (x0, y0, x1, y1)
snakepos = self.c.bbox(self.rec)
# Food block (x0, y0, x1, y1)
food = self.c.bbox(self.block)
# If direction matters, if not then possible to only use self.hit in a single condition.
if self.direction == MOVINGRIGHT and self.hit(snakepos, food):
print('Caught the food moving right.')
elif self.direction == MOVINGLEFT and self.hit(snakepos, food):
print('Caught the food moving left.')
elif self.direction == MOVINGUP and self.hit(snakepos, food):
print('Caught the food moving up.')
elif self.direction == MOVINGDOWN and self.hit(snakepos, food):
print('Caught the food moving down.')
def hit(self, snakepos, food):
"""
Recieves coordinates of food block and snake block and returns if they collide.
:param snakepos: Tuple containing (x0, y0, x1, y1) of the snake.
:param food: Tuple containing (x0, y0, x1, y1) of the food block.
:return: Boolean whether they collide
"""
snakex = (snakepos[0], snakepos[2])
snakey = (snakepos[1], snakepos[3])
foodx = (food[0], food[2])
foody = (food[1], food[3])
# Returns True if any of the snake x cooridnates are between the food x coordinates, or both x coordinates match.
if any((foodx[0] < xcoord < foodx[1] for xcoord in snakex)) or foodx == snakex:
# Returns True if any of the snake y cooridnates are between the food y coordinates, or both y coordinates match.
return any((foody[0] < ycoord < foody[1] for ycoord in snakey)) or foody == snakey
return False
if __name__ == '__main__':
root = Tk()
root.title('Snake')
x, y = 484, 484
recX, recY = x // 2, y // 2
recW, recH = recX + 22, recY + 22
randoms = []
for i in range(484):
if i % 11 == 0:
randoms.append(i)
blockX, blockY = random.choice(randoms), random.choice(randoms)
blockW, blockH = blockX + 22, blockY + 22
snake = Snake(root, recX, recY, recW, recH, blockX, blockY, blockW, blockH)
threading.Thread(target=snake.run, daemon=True).start()
root.mainloop()
This is full code base. Im trying to simulate a mouse click in the graph which is self.graph which is a plotwidget. I want the mouse click to happen in the plotrunnable class so afte I click the graph button it will automatically update and right before going to sleep it will simulate a click on the graph to make it seem like its automatically updating
# Form implementation generated from reading ui file 'U:\Embedded Graphics View2.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
import pyqtgraph as pg
import pyodbc as db
import pandas as pd
import time, os
from time import strptime as strptime
from time import mktime as mktime
from time import gmtime, strftime
from pyqtgraph import AxisItem
from datetime import datetime, timedelta
from numpy import ceil
import numpy as np
import sip
os.environ['TZ']='EST'
now=time.asctime(time.localtime())
start_time=time.time()
print('starting at '+now)
def time(date):
if date == '':
return None
else:
datetime = date
pattern = '%Y%m%d %H:%M:%S'
epoch = int(mktime(strptime(datetime, pattern)))
return epoch
def connecttosql():
host='{SQL Server}'
server='SERVER' ######### DEV - WILL CHANGE TO PRODUCTION WHEN DELIVERED
database='DB'
username='user'
password='pass'
try:
cs= 'Driver=%s;Server=%s;Uid=%s;Pwd=%s;Database=%s;' % (host,server, username, password, database)
global conn #### THIS WILL BE USED ON THE QUERY
conn= db.connect(cs)
print ('Connected successfully to '+host+', '+server)
except Exception as e:
print ('Error: ' + str (e))
def testconnection():
cursor=conn.cursor()
try:
cursor.execute("SELECT VERSION()")
res=cursor.fetchone()
print(res)
ver=res[0]
if ver in None:
return False
else:
return True
except:
print ("ERROR IN CONNECTION")
return False
def closeconnection():
conn.close
print('CONNECTION WITH DATABASE HAS BEEN CLOSED')
def query(ticker,interval,ST,ET):
# target='U:/py/sql csv/'+ticker+' - '+interval+'.csv'
global conn
table = 'BAR_BB' ### hard code
qry = f"SELECT * FROM {table} WHERE SY = {ticker} AND IL = {interval} AND ST >= {ST} AND ST <= {ET}"
df=pd.read_sql(qry,conn) ###### format will change
df.set_index('ST',inplace=True)
#df.to_csv(target,encoding='utf-8',index=False)
st=df.index.tolist()
op=df['O'].tolist()
hi=df['H'].tolist()
lo=df['L'].tolist()
cl=df['C'].tolist()
bars=[]
x=0
for i in st:
bar=[st[x],op[x],cl[x],lo[x],hi[x]]
bars.append(bar)
x=x+1
data=bars
return data
##Picture that goes in the UI
class CandlestickItem(pg.GraphicsObject):
def __init__(self):
pg.GraphicsObject.__init__(self)
self.flagHasData = False
#QtCore.pyqtSlot(list)
def set_data(self, data):
self.data = data
self.flagHasData = True
self.generatePicture()
self.informViewBoundsChanged()
def generatePicture(self):
## pre-computing a QPicture object allows paint() to run much more quickly,
## rather than re-drawing the shapes every time.
self.picture = QtGui.QPicture()
p = QtGui.QPainter(self.picture)
p.setPen(pg.mkPen('w'))
w = (self.data[1][0] - self.data[0][0]) / 3.
for (t, open, close, min, max) in self.data:
p.drawLine(QtCore.QPointF(t, min), QtCore.QPointF(t, max))
if open > close:
p.setBrush(pg.mkBrush('r'))
else:
p.setBrush(pg.mkBrush('g'))
p.drawRect(QtCore.QRectF(t-w, open, w*2, close-open))
p.end()
def paint(self, p, *args):
p.drawPicture(0, 0, self.picture)
def boundingRect(self):
## boundingRect _must_ indicate the entire area that will be drawn on
## or else we will get artifacts and possibly crashing.
## (in this case, QPicture does all the work of computing the bouning rect for us)
return QtCore.QRectF(self.picture.boundingRect())
class DateAxisItem(AxisItem):
"""
A tool that provides a date-time aware axis. It is implemented as an
AxisItem that interpretes positions as unix timestamps (i.e. seconds
since 1970).
The labels and the tick positions are dynamically adjusted depending
on the range.
It provides a :meth:`attachToPlotItem` method to add it to a given
PlotItem
"""
# Max width in pixels reserved for each label in axis
_pxLabelWidth = 80
def __init__(self, *args, **kwargs):
AxisItem.__init__(self, *args, **kwargs)
self._oldAxis = None
def tickValues(self, minVal, maxVal, size):
"""
Reimplemented from PlotItem to adjust to the range and to force
the ticks at "round" positions in the context of time units instead of
rounding in a decimal base
"""
maxMajSteps = int(size/self._pxLabelWidth)
dt1 = datetime.fromtimestamp(minVal)
dt2 = datetime.fromtimestamp(maxVal)
dx = maxVal - minVal
majticks = []
if dx > 63072001: # 3600s*24*(365+366) = 2 years (count leap year)
d = timedelta(days=366)
for y in range(dt1.year + 1, dt2.year):
dt = datetime(year=y, month=1, day=1)
majticks.append(mktime(dt.timetuple()))
elif dx > 5270400: # 3600s*24*61 = 61 days
d = timedelta(days=31)
dt = dt1.replace(day=1, hour=0, minute=0,
second=0, microsecond=0) + d
while dt < dt2:
# make sure that we are on day 1 (even if always sum 31 days)
dt = dt.replace(day=1)
majticks.append(mktime(dt.timetuple()))
dt += d
elif dx > 172800: # 3600s24*2 = 2 days
d = timedelta(days=1)
dt = dt1.replace(hour=0, minute=0, second=0, microsecond=0) + d
while dt < dt2:
majticks.append(mktime(dt.timetuple()))
dt += d
elif dx > 7200: # 3600s*2 = 2hours
d = timedelta(hours=1)
dt = dt1.replace(minute=0, second=0, microsecond=0) + d
while dt < dt2:
majticks.append(mktime(dt.timetuple()))
dt += d
elif dx > 1200: # 60s*20 = 20 minutes
d = timedelta(minutes=10)
dt = dt1.replace(minute=(dt1.minute // 10) * 10,
second=0, microsecond=0) + d
while dt < dt2:
majticks.append(mktime(dt.timetuple()))
dt += d
elif dx > 120: # 60s*2 = 2 minutes
d = timedelta(minutes=1)
dt = dt1.replace(second=0, microsecond=0) + d
while dt < dt2:
majticks.append(mktime(dt.timetuple()))
dt += d
elif dx > 20: # 20s
d = timedelta(seconds=10)
dt = dt1.replace(second=(dt1.second // 10) * 10, microsecond=0) + d
while dt < dt2:
majticks.append(mktime(dt.timetuple()))
dt += d
elif dx > 2: # 2s
d = timedelta(seconds=1)
majticks = range(int(minVal), int(maxVal))
else: # <2s , use standard implementation from parent
return AxisItem.tickValues(self, minVal, maxVal, size)
L = len(majticks)
if L > maxMajSteps:
majticks = majticks[::int(ceil(float(L) / maxMajSteps))]
return [(d.total_seconds(), majticks)]
def tickStrings(self, values, scale, spacing):
"""Reimplemented from PlotItem to adjust to the range"""
ret = []
if not values:
return []
if spacing >= 31622400: # 366 days
fmt = "%Y"
elif spacing >= 2678400: # 31 days
fmt = "%Y %b"
elif spacing >= 86400: # = 1 day
fmt = "%b/%d"
elif spacing >= 3600: # 1 h
fmt = "%b/%d-%Hh"
elif spacing >= 60: # 1 m
fmt = "%H:%M"
elif spacing >= 1: # 1s
fmt = "%H:%M:%S"
else:
# less than 2s (show microseconds)
# fmt = '%S.%f"'
fmt = '[+%fms]' # explicitly relative to last second
for x in values:
try:
t = datetime.fromtimestamp(x)
ret.append(t.strftime(fmt))
except ValueError: # Windows can't handle dates before 1970
ret.append('')
return ret
def attachToPlotItem(self, plotItem):
"""Add this axis to the given PlotItem
:param plotItem: (PlotItem)
"""
self.setParentItem(plotItem)
viewBox = plotItem.getViewBox()
self.linkToView(viewBox)
self._oldAxis = plotItem.axes[self.orientation]['item']
self._oldAxis.hide()
plotItem.axes[self.orientation]['item'] = self
pos = plotItem.axes[self.orientation]['pos']
plotItem.layout.addItem(self, *pos)
self.setZValue(-1000)
def detachFromPlotItem(self):
"""Remove this axis from its attached PlotItem
(not yet implemented)
"""
raise NotImplementedError() # TODO
class TimeAxisItem(pg.AxisItem):
def tickStrings(self, values, scale, spacing):
return [datetime.fromtimestamp(value) for value in values]
##UI SetUP
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1442, 1018)
MainWindow.setAutoFillBackground(False)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.graphicsView = QtWidgets.QWidget(self.centralwidget)
self.flagHasData = False
self.graphicsView.setGeometry(QtCore.QRect(0, 0, 1201, 991))
font = QtGui.QFont()
font.setPointSize(18)
self.graphicsView.setFont(font)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
self.graphicsView.setObjectName("graphicsView")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setEnabled(True)
self.lineEdit.setGeometry(QtCore.QRect(1280, 20, 151, 21))
font = QtGui.QFont()
font.setPointSize(11)
self.lineEdit.setFont(font)
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_2.setGeometry(QtCore.QRect(1280, 80, 151, 20))
font = QtGui.QFont()
font.setPointSize(11)
self.lineEdit_2.setFont(font)
self.lineEdit_2.setText("")
self.lineEdit_2.setObjectName("lineEdit_2")
self.lineEdit_3 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_3.setGeometry(QtCore.QRect(1280, 160, 151, 20))
font = QtGui.QFont()
font.setPointSize(11)
self.lineEdit_3.setFont(font)
self.lineEdit_3.setObjectName("lineEdit_3")
self.lineEdit_4 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_4.setGeometry(QtCore.QRect(1280, 230, 151, 20))
font = QtGui.QFont()
font.setPointSize(11)
self.lineEdit_4.setFont(font)
self.lineEdit_4.setObjectName("lineEdit_4")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(1280, 0, 91, 16))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(1280, 60, 111, 16))
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(self.centralwidget)
self.label_3.setGeometry(QtCore.QRect(1280, 120, 51, 16))
self.label_3.setObjectName("label_3")
self.label_4 = QtWidgets.QLabel(self.centralwidget)
self.label_4.setGeometry(QtCore.QRect(1280, 190, 101, 16))
self.label_4.setObjectName("label_4")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(1280, 260, 75, 23))
self.pushButton.setObjectName("pushButton")
self.label_5 = QtWidgets.QLabel(self.centralwidget)
self.label_5.setGeometry(QtCore.QRect(1280, 140, 170, 20))
self.label_5.setObjectName("label_5")
self.label_6 = QtWidgets.QLabel(self.centralwidget)
self.label_6.setGeometry(QtCore.QRect(1280, 210, 170, 20))
self.label_6.setObjectName("label_6")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(1360, 260, 75, 23))
self.pushButton_2.setObjectName("pushButton_2")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.pushButton.clicked.connect(self.btn_click)
self.pushButton_2.clicked.connect(self.clear)
self.main_layout = QtWidgets.QHBoxLayout()
self.graphicsView.setLayout(self.main_layout)
self.graph = None
self.glayout = None
self.data = []
self.vb = None
self.main_layout.addWidget(self.graph)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
##renaming all the Labels and Window
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Graph Interface"))
self.label.setText(_translate("MainWindow", "Ticker (Bloomberg)"))
self.label_2.setText(_translate("MainWindow", "Interval (In Seconds)"))
self.label_3.setText(_translate("MainWindow", "Start Time"))
self.label_4.setText(_translate("MainWindow", "End Time (Optional)"))
self.pushButton.setText(_translate("MainWindow", "Graph"))
self.label_5.setText(_translate("MainWindow", "YYYYMMDD 00:00:00 (UTC)"))
self.label_6.setText(_translate("MainWindow", "YYYYMMDD 00:00:00 (UTC)"))
self.pushButton_2.setText(_translate("MainWindow", "Clear"))
global mouse_click_event
def mouse_click_event(self):
graph.clicked()
#Button Click function.
def btn_click(self):
global ticker, interval, start_time, end_time, graph
global DRAW_GRAPH
connecttosql()
self.data = [ ## fields are (time, open, close, min, max).
(1., 10, 13, 5, 15),
(2., 13, 17, 9, 20),
(3., 17, 14, 11, 23),
(4., 14, 15, 5, 19),
(5., 15, 9, 8, 22),
(6., 9, 15, 8, 16)]
self.graph = pg.PlotWidget(name = 'Whatever', aixsItems = {'bottom' : TimeAxisItem(orientation = 'bottom')})
# self.ticker = self.lineEdit.text()
#self.interval = self.lineEdit_2.text()
#self.start_time = time(self.lineEdit_3.text())
#self.end_time = time(self.lineEdit_4.text())
# if self.end_time == None:
# self.end_time = time(strftime("%Y%m%d %H:%M:%S", gmtime()))
# else:
# self.end_time = time((self.lineEdit_4.text()))
# self.ticker = "'{}'".format(self.ticker)
# self.interval = "'{}'".format(self.interval)
# ticker = self.ticker
# interval = self.interval
# start_time = self.start_time
# end_time = self.end_time
self.glayout = pg.GraphicsLayout()
self.vb = self.glayout.addViewBox()
self.vb.enableAutoRange(axis='xy',enable = True)
#self.data = query(self.ticker,self.interval,self.start_time,self.end_time)
self.item = CandlestickItem()
self.item.set_data(self.data)
self.graph.addItem(self.item)
self.axis1 = DateAxisItem(orientation = 'bottom')
self.axis1.attachToPlotItem(self.graph.getPlotItem())
self.graph.showGrid(y=True, alpha = 0.8)
self.main_layout.addWidget(self.graph)
runnable = PlotRunnable(self.item)
QtCore.QThreadPool.globalInstance().start(runnable)
def clear(self):
self.parent = self.graph.parent()
self.graph.setParent(None)
self.graph.setParent(self.parent)
class PlotRunnable(QtCore.QRunnable):
def __init__(self, it):
QtCore.QRunnable.__init__(self)
self.it = it
def run(self):
while True:
data = self.it.data
# end_time = end_time = time(strftime("%Y%m%d %H:%M:%S", gmtime()))
rand =[ ## fields are (time, open, close, min, max).
(1., 10, 13, 5, 15),
(2., 13, 17, 9, 20),
(3., 17, 14, 11, 23),
(4., 14, 15, 5, 19),
(5., 15, 9, 8, 22),
(6., 9, 15, 8, 16),
(7., 8, 16, 10, 17)]
new_bar = rand[-1]
data.append(new_bar)
QtCore.QMetaObject.invokeMethod(self.it, "set_data",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(list, data))
#put mouse click here
print("ran")
#interval = int("{}".format(interval))
QtCore.QThread.msleep(1000)
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
I'm learning Python from this lecture: Lec 19 | MIT 6.00 Introduction to Computer Science and Programming. I'm using Python 3.6.2, lecture example runs on Python 2.x. Whats the proper way to set values of x and y in function ans_quest?
x, y = loc_list[-1].get_coords()
Can this method be called like this? This was the example in the lecture.
Full code:
import math, random, pylab, copy
class Location(object):
def __init__(self, x, y):
self.x = float(x)
self.y = float(y)
def move(self, xc, yc):
return Location(self.x+float(xc), self.y+float(yc))
def get_coords(self):
return self.x, self.y
def get_dist(self, other):
ox, oy = other.get_coords()
x_dist = self.x - ox
y_dist = self.y - oy
return math.sqrt(x_dist**2 + y_dist**2)
class Compass_Pt(object):
possibles = ('N', 'S', 'E', 'W')
def __init__(self, pt):
if pt in self.possibles: self.pt = pt
else: raise ValueError('in Compass_Pt.__init__')
def move(self, dist):
if self.pt == 'N': return (0, dist)
elif self.pt == 'S': return (0, -dist)
elif self.pt == 'E': return (dist, 0)
elif self.pt == 'W': return (-dist, 0)
else: raise ValueError('in Compass_Pt.move')
class Field(object):
''' Cartesian plane where object will be located '''
def __init__(self, drunk, loc):
self.drunk = drunk
self.loc = loc
def move(self, cp, dist):
old_loc = self.loc
xc, yc = cp.move(dist)
self.loc = old_loc.move(xc, yc)
def get_loc(self):
return self.loc
def get_drunk(self):
return self.drunk
class Drunk(object):
''' Point itself '''
def __init__(self, name):
self.name = name
def move(self, field, cp, dist = 1):
if field.get_drunk().name != self.name:
raise ValueError('Drunk.move called with drunk not in the field')
for i in range(dist):
field.move(cp, 1)
class Usual_Drunk(Drunk):
def move(self, field, dist = 1):
''' Drunk.move superclass method override. Sends additional cp attribute.'''
cp = random.choice(Compass_Pt.possibles)
Drunk.move(self, field, Compass_Pt(cp), dist)
class Cold_Drunk(Drunk):
def move(self, field, dist = 1):
cp = random.choice(Compass_Pt.possibles)
if cp == 'S':
Drunk.move(self, field, Compass_Pt(cp), 2*dist)
else:
Drunk.move(self, field, Compass_Pt(cp), dist)
class EW_Drunk(Drunk):
def move(self, field, time = 1):
cp = random.choice(Compass_Pt.possibles)
while cp != 'E' and cp != 'W':
cp = random.choice(Compass_Pt.possibles)
Drunk.move(self, field, Compass_Pt(cp), time)
def perform_trial(time, f):
start = f.get_loc()
distances = [0,0]
for t in range(1, time + 1):
f.get_drunk().move(f)
new_loc = f.get_loc()
distance = new_loc.get_dist(start)
distances.append(distance)
return distances
def perform_sim(time, num_trials, drunk_type):
dist_lists = []
loc_lists = []
for trial in range(num_trials):
d = drunk_type('Drunk' + str(trial))
f = Field(d, Location(0, 0))
distances = perform_trial(time, f)
locs = copy.deepcopy(distances)
dist_lists.append(distances)
loc_lists.append(locs)
return dist_lists, loc_lists
def ans_quest(max_time, num_trials, drunk_type, title):
dist_lists, loc_lists = perform_sim(max_time, num_trials, drunk_type)
means = []
for t in range(max_time + 1):
tot = 0.0
for dist_l in dist_lists:
tot += dist_l[t]
means.append(tot/len(dist_lists))
pylab.figure()
pylab.plot(means)
pylab.ylabel('distance')
pylab.xlabel('time')
pylab.title('{} Ave. Distance'.format(title))
lastX = []
lastY = []
for loc_list in loc_lists:
x, y = loc_list[-1].get_coords()
lastX.append(x)
lastY.append(y)
pylab.figure()
pylab.scatter(lastX, lastY)
pylab.ylabel('NW Distance')
pylab.title('{} Final location'.format(title))
pylab.figure()
pylab.hist(lastX)
pylab.xlabel('EW Value')
pylab.ylabel('Number of Trials')
pylab.title('{} Distribution of Final EW Values'.format(title))
num_steps = 50
num_trials = 10
ans_quest(num_steps, num_trials, Usual_Drunk, 'Usual Drunk ' + str(num_trials) + ' Trials')
ans_quest(num_steps, num_trials, Cold_Drunk, 'Cold Drunk ' + str(num_trials) + ' Trials')
ans_quest(num_steps, num_trials, EW_Drunk, 'EW Drunk ' + str(num_trials) + ' Trials')
pylab.show()
Error:
Traceback (most recent call last):
File "/home/tihe/Documents/CODING/Project Home/Python/biased_random_walks.py", line 194, in <module>
ans_quest(num_steps, num_trials, Usual_Drunk, 'Usual Drunk ' + str(num_trials) + ' Trials')
File "/home/tihe/Documents/CODING/Project Home/Python/biased_random_walks.py", line 175, in ans_quest
x, y = loc_list[-1].get_coords()
AttributeError: 'float' object has no attribute 'get_coords'
This method could be called like this if you had a list of Location objects. The error is because the loc_list is populated with distances and not Location objects. That happens in function perform_sim when instead of geting the location you are making a deep copy of distance.
Perhaps you could try something like this:
def perform_trial(time, f):
start = f.get_loc()
distances = [0,0]
locations = []
for t in range(1, time + 1):
f.get_drunk().move(f)
new_loc = f.get_loc()
locations.append(new_loc)
distance = new_loc.get_dist(start)
distances.append(distance)
return distances, locations
def perform_sim(time, num_trials, drunk_type):
dist_lists = []
loc_lists = []
for trial in range(num_trials):
d = drunk_type('Drunk' + str(trial))
f = Field(d, Location(0, 0))
distances, locations = perform_trial(time, f)
dist_lists.append(distances)
loc_lists.append(locations)
return dist_lists, loc_lists
I hope that helped you out.
I am creating a "stopwatch" for a competition. A participants starts doing something, i star the program, and the participant can see his own placement which is updated dynamically with the watch. I have a fully functional code below:
import sys
from PyQt4 import QtGui, QtCore
class Main(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ms = 0
self.s = 0
self.m = 0
self.data_list = {
"asd": "00:02:01",
"bsd": "00:07:01",
"csd": "00:01:01",
"rrsd": "00:04:01",
"fghsd": "00:01:41",
"tzu": "00:09:01",
"azud": "00:02:01",
"cvb": "00:01:41",
"jkl": "00:01:06",
"aertt": "00:11:01"
}
self.next_comp = ""
self.timer_state = False
self.table_rows = 9
self.table_cols = 3
self.participants_above = 6
self.initUI()
def initUI(self):
centralwidget = QtGui.QWidget(self)
self.lcd = QtGui.QLCDNumber(self)
time = "{0:02d}:{1:02d}:{2:02d}".format(self.m, self.s, self.ms)
self.lcd.setDigitCount(len(time))
self.lcd.display(time)
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self.Time)
self.start = QtGui.QPushButton("Start/Stop", self)
self.start.clicked.connect(self.Start)
self.reset = QtGui.QPushButton("Reset", self)
self.reset.clicked.connect(self.Reset)
self.le_name = QtGui.QLineEdit()
self.table = QtGui.QTableWidget()
self.table.setStyleSheet('QTableWidget { font-size: 24pt; padding: 10px; }')
self.table.setRowCount(self.table_rows)
self.table.setColumnCount(self.table_cols)
self.table.setShowGrid(False)
self.table.verticalHeader().setDefaultSectionSize(60)
self.table.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch)
self.table.verticalHeader().setVisible(False)
self.table.horizontalHeader().setVisible(False)
self.update_table()
grid = QtGui.QGridLayout()
grid.addWidget(self.start, 1, 0)
grid.addWidget(self.reset, 1, 2)
grid.addWidget(self.lcd, 2, 0, 1, 3)
grid.addWidget(self.le_name, 3, 0, 1, 3)
grid.addWidget(self.table, 4, 0, 1, 3)
grid.setRowMinimumHeight(2, 100)
centralwidget.setLayout(grid)
self.setCentralWidget(centralwidget)
# ---------Window settings --------------------------------
self.setGeometry(300, 300, 380, 370)
# self.showFullScreen()
def update_table(self, new_entry=""):
local_data = self.data_list
local_data.update(new_entry)
local_data = [(v, k) for k, v in local_data.items()]
local_data.sort(reverse=True)
if new_entry:
pos = local_data.index(tuple([(v, k) for k, v in new_entry.items()])[0])
else:
pos = len(local_data) - 1
local_data = [(i, k) for i, k in enumerate(local_data)]
if pos > self.participants_above:
local_data = local_data[pos - self.participants_above:]
for i, j in enumerate(local_data):
self.a = QtGui.QTableWidgetItem(str(j[0] + 1))
self.a.setTextAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignRight)
self.table.setItem(i, 0, self.a)
if new_entry and j[1] == tuple([(v, k) for k, v in new_entry.items()])[0]:
self.table.item(i, 0).setBackground(QtGui.QColor("red"))
self.a = QtGui.QTableWidgetItem(j[1][0])
self.a.setTextAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignCenter)
self.table.setItem(i, 1, self.a)
if new_entry and j[1] == tuple([(v, k) for k, v in new_entry.items()])[0]:
self.table.item(i, 1).setBackground(QtGui.QColor("red"))
self.a = QtGui.QTableWidgetItem(j[1][1])
self.a.setTextAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignLeft)
self.table.setItem(i, 2, self.a)
if new_entry and j[1] == tuple([(v, k) for k, v in new_entry.items()])[0]:
self.table.item(i, 2).setBackground(QtGui.QColor("red"))
def clear_table(self):
for i in range(self.table_rows):
for j in range(self.table_cols):
self.table.setItem(i, j, QtGui.QTableWidgetItem(""))
def Reset(self):
self.timer.stop()
self.clear_table()
self.update_table()
self.timer_state = False
self.s = 0
self.m = 0
self.ms = 0
time = "{0:02d}:{1:02d}:{2:02d}".format(self.m, self.s, self.ms)
self.lcd.setDigitCount(len(time))
self.lcd.display(time)
def Start(self):
if not self.timer_state:
self.timer_state = True
self.timer.start(10)
else:
self.timer_state = False
self.timer.stop()
def Time(self):
if self.ms < 99:
self.ms += 1
else:
if self.s < 59:
self.ms = 0
self.s += 1
elif self.s == 59 and self.m < 99:
self.m += 1
self.ms = 0
self.s = 0
else:
self.timer.stop()
time = "{0:02d}:{1:02d}:{2:02d}".format(self.m, self.s, self.ms)
self.update_table({self.le_name.text(): time})
self.lcd.setDigitCount(len(time))
self.lcd.display(time)
app = QtGui.QApplication(sys.argv)
main = Main()
main.show()
sys.exit(app.exec_())
As you can see the timer points to the Time function, and fires it every milisec. Inside the timer i update the list, so the participant and the viewers can see his placement all the time. The problem is that the timer is slower with every participant.
I assume its because the computer is slow, and cant update the graphical table this fast, however i am struggling to come up with a better idea to make the clock work as a real clock, and maintain the dynamic update of the list as well.
Any help would be appreciated!