Turn led on in function with different args. Python - python

I can’t seem to wrap my head around how to do this. I tried searching but it just returns how to turn on a led with a raspberry pi. So here I am. I am trying to make a function so that I can check multiple values and if they match turn a led on. I guess my major issue is when it is true the led turns on, but if the next function shares the same led it will turn it off. If that makes sense.
#
def turnon(led,x)
if x == updating_x:
turn led # from led, on
else:
turn led # from led, off
while True:
#led 1
turnon(1,20)
#led 1
turnon(1,50)
#led 2
turnon(2,10)
So say updating_x=20 so the led #1 would turn on but then the next function that has the same LED would turn it off. I thought about changing it to this
if x == updating_x:
turn led # from led, on
time.sleep()
turn led off
else:
pass
But it is somewhat time critical and I will want the multiple leds to turn on together and not just one after the other. I don’t want to get caught just sleeping if the value change true for another led.
FYI, the plan is 60ish leds with around 70 different check values
Any ideas on the right way to do this? and Thanks!
Edit:
Sorry I will try and explain it better. So with the example I gave, I want led 1 to turn on if the update_x == 20 or 50. (if update_x = 20 now) In the loop, it runs the first function which is true so the led turns on. But the second function will be false so it turns the led off, although it is still true for the first function. The problem is that I want to keep the led on until the first function returns false.
Ignore the second bit with the time.sleep in it, just an idea but won't work for what I want.
writing this I had an idea of having the x variables I want to work in a list and using that list in the function parameters, if that works. In the end there will be around 60 leds with about 5 values to turn each one on, 60 lists sounds like a pain.

Related

Using recursion in pygame

I'm new to python and programming in general and am working on a final project for a python centric class. One of the requirements that I cant seem to figure out how to make work is to integrate recursion into our code in order to show a working knowledge. I've worked up a simple "bullet hell" style game using pygame.
My goal is that when contact is made between a bullet and an enemy, that a series of bullet sets will be launched from the player position as a sort of short-term modifier.
This code runs in the main loop whenever a bullet hits an enemy:
for i in reversed(range(len(bullets))):
for j in reversed(range(len(enemies))):
if bullets[i].collided(enemies[j].rect):
del enemies[j]
del bullets[I]
s.global_score += 100
more_bullets(10)
#print("Hit!")
#print(s.global_score)
break
The "more_bullets" function is the focus of my recursion, and calls this:
def more_bullets(n):
if(n > 0):
spawnx = sq.rect.x+10 + sq.rect.width/2 - 10
b = Square(s.red, spawnx,sq.rect.y, 10,30)
b.direction = 'N'
b.player_speed = 10
bullets.append(b)
spawnx = sq.rect.x-10 + sq.rect.width/2 - 10
b = Square(s.red, spawnx,sq.rect.y, 10,30)
b.direction = 'N'
b.player_speed = 10
bullets.append(b)
pygame.display.update()
more_bullets(n-1)
print(f"Fired x {n}")
The outcome currently is that my debug does print 10 times making me think that the recursion is functioning correctly, however only one set of bullets is firing when the collision occurs. I'm thinking that all 10 bullets are firing faster than I can register it and just stacking on the screen.
Is there an easy-to-use function that might slow down the firing of the bullets? or have messed up something more fundamentally here?
I'm thinking that all 10 bullets are firing faster than I can register it and just stacking on the screen.
You're correct.
I don't believe there's an "easy way" to do what you're asking the way you think. The recursion is immediate, meaning that the function runs 10 times right away when it's called. For it to send out a burst of staggered bullets, you'd need some kind of timer or queue or something along those lines that runs alongside your main loop, and recursion isn't really a natural fit for that. The same will go for any kind of game logic function that plays out over a period of time.
This isn't what's being asked, but here's an idea of what you could do, even though it's kind of a redundant use of recursion: add a parameter to that function that dictates the angle the bullet is being shot. Then, add a little bit to that parameter on every recursive call. That way an arc of bullets will be shot at the same time.

Python: For Loop to change 1 property on multiple objects

The Python code below works perfectly to light 3 LEDs sequentially on a Rasberry Pico; however, I want to use a for loop with part of the object name plus the value of the for loop iterator. If LEDs were added to the board, all that would be needed is a change of the for range(1,x).
Something like the followning does not seem work (Python feels it is getting a value with no properites):
for loop_value in range(1,4):
#turn LED on, wait, turn LED off
LED_external_[loop_value].value(1)
utime.sleep(1)
LED_external_[loop_value].value(0)
Thanks so much for any input. I feel the function is a convoluted workaround. The for loop would be so much better !!!
########## start (works perfectly, Python coded in Thonny IDE) #######
from machine import Pin
import utime
# assign pin to green LED and initialize to off state
LED_external_1 = machine.Pin(14, machine.Pin.OUT)
LED_external_1.value(0)
# assign pin to yellow LED and initialize to off state
LED_external_2 = machine.Pin(15, machine.Pin.OUT)
LED_external_2.value(0)
# assign pin to red LED and initialize to off state
LED_external_3 = machine.Pin(11, machine.Pin.OUT)
LED_external_3.value(0)
def on_off(LED_Obj_Name):
#turn LED on, wait, turn LED off
LED_Obj_Name.value(1)
utime.sleep(1)
LED_Obj_Name.value(0)
while True:
on_off(LED_external_1)
on_off(LED_external_2)
on_off(LED_external_3)
############################# end ####################################
LED_external_[loop_value].value(1) here you're treating LED_external_ as a list. What you can do is add all LEDs to a list and iterate that list.
LED_list = [LED_external_1, LED_external_2, LED_external_3]
for item in LED_list:
#turn LED on, wait, turn LED off
item.value(1)
utime.sleep(1)
item.value(0)

How to use the same key to flip multiple times in PsychoPy?

I’m trying to use the same key to flip after multiple successive stimuli in PsychoPy but it keeps flipping successive screens as well then.
What I came up with was the following slight modification of one of the examples in the manual:
from psychopy import visual, core, event
win = visual.Window(monitor="testMonitor", units="deg")
stim1 = visual.TextStim(win, text="Stim 1", pos=(0,0))
stim2 = visual.TextStim(win, text="Stim 2", pos=(0,0))
stim3 = visual.TextStim(win, text="Stim 3", pos=(0,0))
while len(event.getKeys(['space'])) <= 0:
stim1.draw()
win.flip()
event.clearEvents()
print(event.getKeys()) # test if key buffer is really empty
win.flip()
# while len(event.getKeys(['return'])) <= 0:
# stim2.draw()
# win.flip()
# event.clearEvents()
# win.flip()
while len(event.getKeys(['space'])) <= 0:
stim3.draw()
win.flip()
event.clearEvents()
win.flip()
win.close()
core.quit()
However if I hit space on the first screen, it doesn’t just flip this screen. Instead it will flash stim3 for a split second and then immediately terminate. If on the other hand I use a different key for the second stimulus (replace 'space' with 'return' in the loop condition), that works fine.
My first suspicion was that event.clearEvents() somehow failed to clear the event buffer, so the space event from the first stimulus remained saved and also flipped the second stimulus. However in that case the stim3 shouldn’t be shown at all because the loop condition would immediately fail. Also, if I print out event.getKeys() at the indicated position above, it appears to be empty. Moreover, if I use a different key between the two space-triggered stimuli (remove comments from the stim2 section), suddenly all keys work just fine.
Does anybody have an idea what I’m doing wrong?
(Btw if you’re wondering: I modified the manual example by changing the loop where the program waits for input from a while True loop into while len(event.getKeys(['space'])) <= 0 which eliminates the need of using the exact same condition to break. I tested it with the original idiom just to be sure and the behaviour is the exact same as with my version.)
After some more testing found that deleting the win.flip()'s after each event.clearEvent() fixes the issue. I’m not quite sure why the additional flips (which I thought were necessary to clear the screen before drawing the new stimulus) would cause such a behaviour though. Can somebody explain?

Python Inputs module - detect axis of gamepad joystick with lenience?

To simplify this problem, let's say I simply want to be able to detect whether my gamepad's right thumbstick is being pushed up (but not horizontally, within some lenience), pushed to the right (but not up, within some lenience) or being pushed to the left (but not up, within some lenience).
Unfortunately, the lenience is required, but I haven't found a way to do it yet. Thusfar I have been using the inputs library:
https://pypi.org/project/inputs/
But it's not super well documented and as far as I can tell it doesn't let you compare an exact angle of the thumbstick at any one time.
Using their own example code, I have this snippet of a function:
def get_true_game_input():
inputArray = [0,0,0,0,0,0,0,0,0,0,0,0,0,0]
# All the different buttons that are important to be detected, including whether the thumbstick has been moved left, right, or up
events = get_gamepad()
for event in events:
if event.code == "ABS_RY":
if event.state >= 8000:
print("top Guard!")
inputArray[5] = 1
elif event.code == "ABS_RX":
if event.state >= 8000:
inputArray[6] = 1
print("right guard!")
elif event.state <= -8000:
inputArray[4] = 1
print("left guard!")
Which works up until one moves the stick, for example, upwards, then ever so slightly to the left or right, whereupon it will detect that instead.
The problem is that, with the way Inputs seems to work, events is always either empty, or of size 1. So it will either detect a horizontal movement or a vertical movement, and one will overwrite the other.
Is there some way to solve this? I am also open to rebuilding this using a different library, but cannot find any other. I am using a dualshock 4 controller using the DS4 Tool.
Any help or advice would be greatly appreciated. Thank you.

Why is turtle lightening pixels?

My program for creating a Mandelbrot set has a bug: whenever the pen changes colors, and every 42nd pixel after that, is lighter. This is, rather coincidentally, a mandelbug (yes, I just learned that term), as it is inconsistent for many pixels near an "edge" (it might actually be blurred between the color it's supposed to be and the color the last, or next, pixel is supposed to be), but it's always the 42nd pixel after that one until the next color change. I am using OSX 10.6.8, PYTHON 2.7. When I wrote this program at school, it worked perfectly (Windows), and then I sent it to myself, and worked on it a little more (mostly just making the sample size and therefore image larger), and ran it, I got this bug. EDIT: My bad, I forgot to mention that this only happens with my Mandelbrot program, the few other turtle programs I have at home are fine.
Parts of screenshots (so that you don't have to wait forever while the program runs to see what I'm talking about):
From my first version from home:
From the current version (sideways):
Heres the code:
import turtle
import math
turtle.speed(0)
def benoit(onelen):
turtle.left(90)
for x in range(-2*onelen, onelen):
turtle.up()
turtle.goto(x, int(-1.5*onelen)-1)
turtle.down()
for y in range(int(-1.5*onelen)-1, int(1.5*onelen)-1):
z = complex(0,0)
c = complex(x*1.0/onelen,y*1.0/onelen)
for k in range(20):
z = z*z+c
if abs(z) > 2:
g = .2 + .8*(20-k)/20
break
if k == 19:
g = 0
turtle.pencolor(0,g,0)
turtle.forward(1)
benoit(250)
x = raw_input("Press Enter to Exityadayadayada")
EDIT: A fix has been suggested by DSM, who likes this bug. However, I have no experience editing Python source code, and all the underscores are making me nervous. Can someone tell me specifically what to edit and/or how?
Wow. I think this is one of my favourite bugs ever, and believe it or not, the fact that the number happens to be 42 is actually relevant! Well, peripherally, anyhow..
In turtle.py:
def _goto(self, end):
"""Move the pen to the point end, thereby drawing a line
if pen is down. All other methodes for turtle movement depend
on this one.
[...]
###### vererbung!!!!!!!!!!!!!!!!!!!!!!
self._position = end
if self._creatingPoly:
self._poly.append(end)
if len(self.currentLine) > 42: # 42! answer to the ultimate question
# of life, the universe and everything
self._newLine()
self._update() #count=True)
So the problem comes about when it decides to break a line, apparently for performance reasons:
def _newLine(self, usePos=True):
"""Closes current line item and starts a new one.
Remark: if current line became too long, animation
performance (via _drawline) slowed down considerably.
"""
I was able to "fix" the bug by bumping up the linenumber limit and/or scattering self._pencolor references in places that didn't have any. But you're not crazy, anyway, and it's not really anything that you're doing. :-)
Can i offer a suggestion?
i tried your code and it was taking forever to run which you are aware of but what you may not be aware of is the tracer function... i simply put at the beginning of your code:
wn=turtle.Screen()
wn.tracer(10000)
that also eliminates the need for the speed(0) function :)
Try that and run it again, i did and it rendered the whole image in 62 seconds, i timed it by importing the time module by putting this code at the beginning:
import time
st=time.time()
and this code at the end:
print time.time()-st
Well done by the way, Ive just made my own thats a lot slower and lower quality then yours but was using an array of the square shape and stamping to each location i wanted in the array lol, but will be trying to improve it in the future as i only found out turtle existed less then a week ago.
One last thing, if you type:
from turtle import *
instead of "import turtle" you dont need to put turtle at the beginning of every function call :) same thing goes for every other module.
Ive included the pic of your fractal that took 62 seconds to render on my machine thats not even that powerfulYour code run on my weak machine.
I hope all this helps you greatly. also youll notice i dont have that light line problem, not sure if you fixed that issue in the original code up top?

Categories

Resources