How to change values of a running pi script - python

I have a LED-board which is powered with python.
To turn on the LED's a script has to continue running. But how do I influence the color variables of a running script?
I could read an sql(lite?) db, read the values of a file. Get values of some rest api. Or maybe something completely else.
What is the most neat way to do this?
I'm new to python so feel free to point out I'm completely doing it wrong.
Or provide alternative.
Please do provide sample code which I could follow.
#!/usr/bin/env python
import time
import unicornhat as unicorn
unicorn.set_layout(unicorn.AUTO)
unicorn.rotation(0)
unicorn.brightness(0.3)
count = 0
while True:
# somehow change these color values
# syqlite? reading a file? rest requesting some url? or some signal? how to do this?
color=[
[255,0,0], #red
[255,255,0], #yellow
[0,255,0], #green
[0,255,255], #light blue
[0,0,255], # blue
[255,0,255], #purple
[255,255,255], #white
[0,0,0], #off
]
unicorn.clear()
for y in xrange(8):
# make it "scroll"
row = y+count
if row>7:
row -= 8
for x in xrange(8):
unicorn.set_pixel(y, x, color[row][0], color[row][1], color[row][2])
unicorn.show()
if count == 7:
count = 0
else:
count = count + 1
time.sleep(0.2)

Related

Clearing NeoPixel LEDs after running animate()?

I'm trying to run an animation for a period of time, then clear the LEDs and go back to setting the colors manually with Neopixel.pixels.fill(). Only, after I run animation.animate(), I lose the ability to use pixels.fill() I tried using the sequence library with the auto_clear and auto_reset flags, but those did not seem to work either.
rainbow = Rainbow(macropad.pixels, speed = 0.005, period = 2)
animations = AnimationSequence(rainbow, auto_clear=True, auto_reset=True)
i = 0
while True:
animations.animate()
i += 1
if (i == 100):
animations.reset()
break

Optimising pygame

For my project in AH Computing I'm recreating my version of Nidhogg. Everything runs smoothly until the blood starts spraying. Im not too sure how i can make the code more efficient as i am still fairly new to python.
This is the class for the the spraying blood:
class bloodmaker():
def __init__(self,xv,yv,colour,x,y):
self.gravity = 2
self.air_resistance = 0.25
self.xv = xv
self.yv = yv
self.x = x
self.y = y
self.pastx = 0
self.pasty = 0
self.colour = colour
def move(self):
if self.y < 400:
self.pastx = self.x
self.pasty = self.y
#so that it doesnt curve backwards
if self.xv > 0:
self.xv -= self.air_resistance
self.yv += self.gravity
self.x += self.xv
self.y += self.yv
#so that the drawn line doesnt go over the edge
if self.y > 400:
self.y = 400
if self.colour is "o":
py.draw.line(screen, (255, 165, 0), (self.pastx-backgroundx, self.pasty), (self.x-backgroundx, self.y),5)
else:
py.draw.line(screen, (255, 255, 0), (self.pastx-backgroundx, self.pasty), (self.x-backgroundx, self.y),5)
else:
global bloodgrid
try:
#the bloodgrid are squares 5 pixels wide, covering the bottom section, so we we divide by 5 to find where to put the blood
bloodgrid[int(self.x/5)].insert(0,self.colour)
except:
pass
#deleting this object as it is no longer required
return True
[Here is an image of the blood spraying][1]
(excuse the incomplete sprite)
[1]: https://i.stack.imgur.com/hXiAa.png
Underneath there is a floor of blood that works using an array of stacks, which is added above code when it the blood reaches the floor.
bloodgrid = [[] for x in range(512)]
Here is the code for destroying the flying blood object and blitzing the blood floor to the screen.
def blood():
for i in range(len(bloodarray)):
killyourself = bloodarray[i].move()
if killyourself is True:
kill.append(i)
#appends to a kill list as if i popped here the list would get shorter while the for loop stays the same giving an out of index error
for i in range(len(kill)):
bloodarray.pop(kill[0]-i)
kill.pop(0)
#printing the entire bloodgrid
for i in range(512):
for ii in range(len(bloodgrid[i])):
try:
if bloodgrid[i][ii] is "o":
py.draw.rect(screen, (255, 165, 0), ((i*5)-backgroundx, ii*5+400, 5, 5))
else:
py.draw.rect(screen, (255, 255, 0), ((i*5)-backgroundx, ii*5+400, 5, 5))
except:
pass
I don't think it is possible to only update parts of the screen as the camera moves about and the blood on the floor moves too.
As more blood accumulates on the floor the game framerate starts to drop and it gets especially choppy when the blood sprays. Is there any ways I could make this more efficient? I don't want to hand in a choppy game but I really like how the blood looks. Thanks.
A couple of points that are hopefully helpful.
(This isn't directly related to speeding up your code, but...) Try to get away from using global variables. Just pass them into your functions. Several of the ones you posted are difficult to figure out because you are accessing variables that are outside the scope of the function.
First reason things are bogging down here: You are using insert() to insert new elements at the start of a list, and you are doing that inside of a loop where you call the move() function. Inserting anywhere into a list (except the end) is horribly slow for reasons beyond the scope of this post. You should consider putting a deque from collections in there, which can be inserted front or back efficiently. If that is daunting, you could also "do a little math" and insert at the end of your list and draw it backwards by counting down from the last element, which is also efficient.
Also in the same notion, as mentioned in the comments, poping things out of the middle of lists or arrays is also horribly slow. Figure out a different way or look at a different data structure. It is tough to give advice on this point because bloodarray is not defined in your code.
Basically: things are bogging down because you are choosing the wrong data structures. tweak a couple of them and you'll get better results.

how to set the orientation of the stimulus for each trial in psychopy

I am fairly new to the python language and psychopy. I am practicing it by creating dummy experiments. Here, I am trying to create an experiment about bayesian brain. Non-vertical lines will be presented to the participant while no respond is expected from the participants, just exposure. Then for the last trial (it stays on the monitor for longer period of time to be responded), it is expected from the participant to judge whether the last line trial is vertical or not? (after exposing to non-vertical lines, I am expecting to see a change in perception of verticality).
However, there are so many things that I couldn't learn from the web. I am pretty sure you guys can help me easily.
My primary problem is; how to set up the orientation of the line? I found out the stim.ori but not sure how to use it on 'line' stimuli. Below I've attached the codes that I made so far. Also, I have added some extra questions with #.
I tried to be clear as much as I can. Sorry for my bad english.
Thank you!
from psychopy import visual, core, event #import some libraries from PsychoPy
import random
#create a window
mywin = visual.Window([800,600],monitor="testMonitor", units="deg")
#stimuli
lineo = visual.Line(mywin, start=(-5, -1), end=(-5, 1))
fixation = visual.GratingStim(mywin, size=0.2, pos=[0,0], color = 'black')
#draw the stimuli and update the window
n = 5 # trial number
i = 0
while i < n:
#fixation
fixation.draw()
mywin.flip()
presses = event.waitKeys(1)
# stimulus
orientationlist = [20,30,40,50,60] # I want to draw the orientation info from this list
x = random.choice(orientationlist)
lineo.ori((x)) #
lineo.draw()
mywin.flip()
presses= event.waitKeys(2)
i +=1
if i == 5: # how do I change the number into the length of the trial; len(int(n) didnt work.
lineo.draw()
mywin.flip()
presses = event.waitKeys(4)
#quiting
# I dont know how to command psychopy for quiting the
# experiment when 'escape' is pressed.
#cleanup
mywin.close()
core.quit()
There's a few things that you would want to do differently. I've updated your code and marked changes with the comment "CHANGE". Changing the orientation of a stimulus is pretty consistent in psychopy, so it's no different for Line than any other visual stimulus type.
from psychopy import visual, core, event #import some libraries from PsychoPy
import random
#create a window
mywin = visual.Window([800,600],monitor="testMonitor", units="deg")
#stimuli
lineo = visual.Line(mywin, start=(-5, -1), end=(-5, 1))
fixation = visual.GratingStim(mywin, size=0.2, pos=[0,0], color = 'black')
orientationlist = [20,30,40,50,60] # CHANGED. No need to redefine on every iteration of the while-loop.
#draw the stimuli and update the window
n = 5 # trial number
for i in range(n): # CHANGED. This is much neater in your case than a while loop. No need to "manually" increment i.
#fixation
fixation.draw()
mywin.flip()
event.waitKeys(1) # CHANGED. No need to assign output to anything if it isn't used.
# stimulus
lineo.ori = random.choice(orientationlist) # CHANGED. Alternative: lineo.setOri(random.choice(orientationlist)).
lineo.draw()
mywin.flip()
event.waitKeys(2)
# At this point, all the stimuli have been shown. So no need to do an if-statement within the loop. The following code will run at the appropriate time
lineo.draw()
mywin.flip()
event.waitKeys(keyList=['escape']) # CHANGED. Listen for escape, do not assign to variable
# CHANGED. No need to call core.quit() or myWin.close() here since python automatically cleans everything up on script end.

Simple Graphics library not coloring lines

I'm a student learning to program, and my current assignment is to write a graphing calculator using the Simple Graphics library. I got everything working, except for coloring the lines. The first line should be red, the second should be green and the third one blue, then they repeat. Here is the code I added for the colors:
if count % 3 == 1:
print("red")
setColor = ("red")
elif count % 3 == 2:
print("green")
setColor = ("green")
else:
print("blue")
setColor = ("blue")
Earlier in the code, I set count = 1 and at the end of my drawing loop, I have count = count + 1.
Whenever I try to use the program, all the lines appear black. When I look at the terminal, I see "red", "green" and "blue" all being printed successfully at the right times. Using RGB values to define the color doesn't help either.
Does anyone have any idea of what I could be doing wrong? I can post the entire code for drawing the lines, but I thought people wouldn't want to sift through 30 lines.
setColor = ("color") should just be setColor("color"). setColor is a function, that takes in input and performs an action. If it was a variable, which is just a name for some data that you will provide, your code would be correct. (Variables almost never have verbs in their names.)

How to embed a staircase within an oddball task

At the moment I try to create a visual oddball task with a staircase procedure embedded in it (using Psychopy v1.81.03, builder version). The odds should follow the staircase (gabor patches that change orientation). Standards should be gabor patches oriented vertically.
I started with creating a simple random trial_loop. Within that loop I inserted code components looking like this:
For the "begin of the experiment" I defined an orientation variable (also referring to it in the interface, in which the properties of the gabor patch are defined) and the staircase:
orient = 20
staircase = data.StairHandler(startVal = 20.0,
stepType = 'lin', stepSizes=[8,4,4,2,2,1,1],
maxVal = 90, minVal = 0, nUp=1, nDown=3, nTrials = 50)
For the "begin of the routine" I defined the presentation of the stimuli
and an if-statement that should choose the orientation depending on if it is a standard or an odd.
# ratio of oddball and standard
oddORstand = [1, 1, 1, 1, 1, 1, 1, 1, 1, 2][randint(0,10)]
# choosing orientation and correct answer depending if it's standard or odd
if oddORstand == 1: #standard
orient = 0
corrAns = None
else: #odd
for thisIncrement in staircase:
orient = orient + thisIncrement
corrAns = 'space'
break
For the part that "ends the routine" I defined the response that should change the future orientation of odds depending on if it was a correct answer (detection - spacebar pressed) or not:
if oddORstand == 2: #it was an odd
if key_resp_stand.keys == 'space': #space bar pressed, correct answer
thisResp = 1
staircase.addResponse(thisResp)
elif key_resp_stand.keys != 'space': #space bar was not pressed, wrong answer
thisResp = 0
staircase.addResponse(thisResp)
else:
pass
In general, this works somehow (standards and odds are presented randomly and also the odds change their orientation but not in a manner that would make sense or that was intended).
I could imagine that the response is not correctly detected or added to the staircase. Another possibility might be that the for-loop to set up the orientation of odds is somehow wrong.
But since I never get an error message and I'am also relatively new to psychopy it is a bit tricky for me to figure out the problem.
Is someone out there who can help me with this issue? That would be more than great.
Thank you so much in advance,
Hannes

Categories

Resources