i am supposed to draw a clock in python without using any modules that need downloading like turtle module, rather id have to use the stddraw module. The clock would also have to give the current time in hours, minutes, and seconds represented on the clock. I am struggling to understand how i'm supposed to go about doing this since i havent done any drawing or anything before so this is really new territory in terms of programming. Any ideas on how to go about doing this or advice is greatly appreciated!
without using any modules that need downloading like turtle module,
rather id have to use the stddraw module
As #PurpleIce starts to get at, you've got this backward. The turtle module comes with Python, the stddraw module needs to be downloaded (from Princeton.)
Your question has inspired me to see if it is possible to make a minimalist working clock using Python turtle:
from time import localtime
from turtle import * # avoid wildcard imports like this
ATTRIBUTES = ['tm_hour', 'tm_min', 'tm_sec']
def tick():
record = localtime()
hands['tm_hour'].seth(record.tm_hour % 12 * 30 + record.tm_min / 2 + record.tm_sec / 120)
hands['tm_min'].seth(record.tm_min * 6 + record.tm_sec / 10)
hands['tm_sec'].seth(record.tm_sec * 6)
ontimer(tick, 1000)
mode("logo") # make 0 degrees be straight up the page
hands = {}
for size, attr in enumerate(ATTRIBUTES, start=1):
hands[attr] = Turtle('triangle')
hands[attr].shapesize(1 / size, size * 10)
tick()
mainloop()
Hopefully, this will give you insight on how to begin building your own clock using the stddraw module:
Related
I'd like to program a graphical clock, which has three pointers, one for the hour, another for the minute and the last for the second. The time is synced with my local PC time, so I need the clock pointers infinitely move like a real clock, unless I end the program. How can I determine the moving clock pointers? Is there a function for that? I looked it up in Turtle's documentation, but found none. Maybe I've missed something. Here's my yet incomplete code:
import time
import os
import cursor
import turtle
cursor.show()
s = turtle.Turtle()
turtle.bgcolor('Black')
hour = int(time.strftime('%H'))
minute = int(time.strftime('%M'))
second = int(time.strftime('%S'))
s.pensize(5)
s.pencolor('Red')
s.circle(200)
s.penup()
s.goto(0,200)
s.pendown()
s.left(90)
s.forward(100) #how can I make this rotate 30 degrees???
turtle.done()
Thank you in advance :))
I currently try to repeat a sound every x ms - where x is dependent on an UDP packet I receive via socket - and I decided to use pygame for that. I used this SO answer to repeat something every x ms: https://stackoverflow.com/a/18954902/3475778
But now I have the problem, that the sound is played very irregular and made a minimal-working example where the problem persists:
import pygame
from pygame.locals import *
pygame.mixer.init()
sound = pygame.mixer.Sound('sound.wav')
def play_sound():
sound.stop()
sound.play()
pygame.init()
clock = pygame.time.Clock()
pygame.time.set_timer(USEREVENT+1, 200)
while True:
# clock.tick(30)
for event in pygame.event.get():
if event.type == USEREVENT+1:
play_sound()
Here is the waveform of what I have recorded from the script via Audacity:
You see that for some reason some samples were played longer than the others. Not very nice for some kind of metronome I want to build.
edit UPDATE:
It is not a problem of pygame.time.set_timer, because this code doesn't solve the problem and doesn't rely on pygame.time.set_timer:
import pygame
from datetime import datetime
d = datetime.now()
pygame.mixer.init()
sound = pygame.mixer.Sound('horn_short.wav')
pygame.init()
while True:
if (datetime.now() - d).total_seconds() > 0.2:
sound.play()
d = datetime.now()
has the same problem. The Problem is also under Ubuntu 16.04, Python 3.5 64bit (Anaconda) and a fresh installed pygame.
Here is an idea for an alternative approach.
If the goal is to play a sound in regular intervals,
you might get better results if you (dynamically) pad the sound to the desired interval length,
and then simply loop it with Sound.play(loops=-1).
If there are just a handful of valid intervals, it might be easiest to
store dedicated sound files and load the appropriate one.
Otherwise, the pygame.sndarray module provides access to
a numpy array of the raw sound data, which makes it possible
to dynamically generate sound objects of the desired length:
import pygame
import numpy
# Helper function
def getResizedSound(sound, seconds):
frequency, bits, channels = pygame.mixer.get_init()
# Determine silence value
silence = 0 if bits < 0 else (2**bits / 2) - 1
# Get raw sample array of original sound
oldArray = pygame.sndarray.array(sound)
# Create silent sample array with desired length
newSampleCount = int(seconds * frequency)
newShape = (newSampleCount,) + oldArray.shape[1:]
newArray = numpy.full(newShape, silence, dtype=oldArray.dtype)
# Copy original sound to the beginning of the
# silent array, clipping the sound if it is longer
newArray[:oldArray.shape[0]] = oldArray[:newArray.shape[0]]
return pygame.mixer.Sound(newArray)
pygame.mixer.init()
pygame.init()
sound = pygame.mixer.Sound('sound.wav')
resizedSound = getResizedSound(sound, 0.2)
resizedSound.play(loops=-1)
while True:
pass
Using just pygame (and numpy), this approach should have a good chance for an accurate playback.
For me the thing worked much better, if i did:
pygame.mixer.pre_init(44100, -16, 2, 256)
before any of the pygame init functions.
Ok, you should try using the other way to load a sound:
pygame.mixer.music.load(file=file_directory str)
To play the sound use:
pygame.mixer.music.play(loops=*optional* int, start=*optional* float)
Your code may look like this:
import pygame
pygame.init()
pygame.mixer.init()
sound = pygame.mixer.music.load('sound.wav')
def playSound():
sound.pause()
sound.play()
while True:
pass
For me, that worked better but I am on python 3.7.2 . I don't know about python 3.5, but there aren't many difference between 3.5 and 3.7.2. That should work!
I am currently remaking flappy bird in Tkinter. (I understand this is bad, I explain why at the bottom.) My issue is with the pipes, and the speeds they scroll at and the distance they are from each other. Unless something is wrong with my logic, if a start the two pipes separated from each other then move them when they get to a certain point, and place them at the same point, they should retain the gap between them. This may be better explained in code.
from tkinter import *
import random
root = Tk()
root.geometry('430x640')
root.configure(background='turquoise')
canvas = Canvas(root,width=int(435),height=int(645))
canvas.configure(background='turquoise')
canvas.pack()
x, x2 = 400, 700
y = random.randint(0,300)
y2 = random.randint(0,300)
def drawPipe():
global x,x2,y,y2
canvas.coords(pipeTop,(x,0,(x+50),y))
canvas.coords(pipeBottom,(x,640,(x+50),(y+150)))
canvas.coords(pipeTop2,(x2,0,(x2+50),y2))
canvas.coords(pipeBottom2,(x2,640,(x2+50),(y2+150)))
x -= 3
x2 -= 3
if x < -46:
x = 435
y = random.randint(5,540)
if x2 <-46:
x2 = 435
y2 = random.randint(5,540)
root.after(1,drawPipe)
pipeTop = canvas.create_rectangle(x,0,(x+50),y,fill='green')
pipeBottom = canvas.create_rectangle(x,640,x+50,y+150,fill='green')
pipeTop2 = canvas.create_rectangle(x2,0,(x2+50),y,fill='green')
pipeBottom2 = canvas.create_rectangle(x2,640,(x2+50),(y2+150),fill='green')
drawPipe()
root.mainloop()
This is not my full code, but it is the bit concerned with drawing and updating the pipes. When run, this code will show you how the pipes scrolling speed up and down. I do not understand how this is possible. All the values for the pipes are the same apart from the starting positions. Is this due to the inefficient way Tkinter uses the after method? I attempted to use threading but this produced problems when using root.bind (see my previous question). Or is it due to a logic error? Thank you in advance to anyone who can help me.
Side note: I realise I should not be making a game in tkinter, especially one that requires multiple things to be happening at once. However, I am doing this at school and the modules I would like to use (Pygame or Pyglet) cannot be downloaded just for me to make a game that has no real purpose. If I could use something other than tkinter I probably would. Thank you for your help.
Using after(1,..) you get 1000FPS (Frames Per Second) but you don't need it - use after(20, ...) to get 50 FPS.
Beside using after(1,..) your program have no time to do other things - it have no time to execute all after() so you can get different speed.
With after(1,..) I couldn't even move window.
And my CPU became hotter so fan started working faster and louder.
I am testing out pyglet for usage in a larger project, and apparently pyglet recommends/wants you to use it's own loop (with pyglet.app.run())
This is a something I don't want, for reasons of compatibility of other packages and also to not have to rewrite the entire program structure.
Here I have prototype code stuck together from different parts and tutorials and docs.
It runs for 5-15 iterations and then just freezes, not printing anything and also not doing any draw updates.
from __future__ import division, print_function
import sys
import pyglet
window = pyglet.window.Window(800, 800, resizable=True)
window.set_caption('Pyglet Testing')
window.flip()
image = pyglet.resource.image('Sprites/scout.png')
def draw(dt):
image.blit(700-dt, 400)
while not window.has_exit:
dt = pyglet.clock.tick()
window.dispatch_events()
window.clear()
draw(dt)
window.flip()
print(dt)
My suspicion is that I have done nothing to catch events and handle them, so at a certain point it just overflows with events and blocks the whole thing. I couldn't understand how to do this however, and getting overflowed with events in under 1 second seems a bit much.
Any help?
Basically what you are doing is sending as many image.blit(...) commands to the window, until the pc probably can't handle it anymore.
For instance, if you change your code like this:
add this code:
import time
from time import sleep
change code:
def draw(dt):
image.blit(700-dt, 400)
sleep(0.1) #insert this line
When executing the modified code, you will notice that it does not freeze and that the output dt is around 0.11 seconds, which is the number of seconds since the last "tick" = the time slept (0.1 second) + the remainder time (clear window, display new frame ...)
I need to figure out the delay between sending a command to change the background color or playing a sound and these events actually occurring using timeit.(I'm on windows, Python 2.73)
I'm doing a reaction time test where I'll record the time(using time.clock()) before either changing the background color or playing a sound. Then, when the subject presses a key I record the time again and take difference to find the reaction time.
For the sound playing, here's what I did:
import timeit
t = timeit.Timer(stmt = "winsound.PlaySound('C:\WINDOWS\media\Windows XP Error.wav', winsound.SND_FILENAME)",setup = "import winsound")
n = t.timeit(number = 100)
print n/100 -0.999
The 0.999 is the duration of the Windows XP Error.wav in seconds.
This gave me something like 56ms. I'm not sure if its reasonable and if its the right way to do it as well as should I be enabling the garbage collection or not?
For the background changing I'm having more problems. Since I'm doing the test in fullscreen mode I tried to put all of these into the setup parameter:
from Tkinter import Tk
root=Tk()
root.overrideredirect(True)
root.geometry("{0}x{1}+0+0".format(root.winfo_screenwidth(),root.winfo_screenheight()))
root.mainloop()
Even though I separate them all with ; I still get syntax errors. When I try it not in full screen
setup = 'from Tkinter import Tk; root=Tk(); root.mainloop()' the window actually opens, yet nothing happens and if I close it I see other errors.Invalid command name "."
The statement that I'm actually measuring is root.configure(background='red').
Here's an example of a way to create a multi-line setup string for use with timeit:
setup = """
import random
l1 = [random.randrange(100) for _ in xrange(100)]
l2 = [random.randrange(100) for _ in xrange(10)]
"""
Here's another tip. To get an accurate measurement, it's important to time things following this basic pattern:
time = min(timeit.repeat(statements, setup=setup, repeat=R, number=N))
With an R of at least 3 (R = 3). This takes the fastest value obtained by doing everything 3 times, which will eliminate differences due to the many other things running on your system in the background.
This doesn't answer your whole question, but may be helpful in your quest.