Problem with simple count variable in Python - python

I made this short code for a school project using a Microbit computer, however, when I press the a button when the count is 1, the count jumps to 16 and I can't figure out why.
count = (1)
while True:
gesture = accelerometer.current_gesture()
display.show(count)
if button_a.is_pressed():
count *= (2)
if button_b.is_pressed():
count += (1)
if gesture == "shake":
count = (1)
any help would be greatly appreciated!

If count does not always increase by 16 on each click, you are likely dealing with button de-bouncing issue. Like others have suggested, you could use sleep(1) to check whether that is case or not, but for more practical solution you could do the following:
# detect click of button
if button.is_pressed():
count += 1
# do nothing while button remains clicked for the duration
while button.is_pressed():
pass

As other contributors commented, more than one button push is being detected for a single button push.
With Micropython, to avoid repeated button presses being detected for a single button press use the code:
if button_a.was_pressed():
instead of:
if button_a.is_pressed():

Related

previous button in tkinter python code implementation problem

I am making a quiz application and I have implemented some buttons like next button in my code but I am unable to implement the prevoius button in my code, I have tried but this is not being that I want, how can I do this ? Please help. The code is below
def next_btn(self):
# Check if the answer is correct
if self.check_ans(self.q_no):
# if the answer is correct it increments the correct by 1
self.correct += 1
# Moves to next Question by incrementing the q_no counter
self.q_no += 1
if self.q_no==self.data_size:
# if it is correct then it displays the score
self.display_result()
# destroys the GUI
root.destroy()
# destroys the GUI
#elif self.q_no-1==self.data_size:
#self.next_button.text="apple"
else:
# shows the next question
self.display_question()
self.display_options()

Kivy eventloop misses changes of StringProperty

I have an app which asks a series of 8 math questions to the user. The user has a keypad with which he can manipulate a label. This label answer_text holds the answer, the user wants to submit. Since I had issues, there are two "mechanisms" which allow the checking of this answer (if it is true, the next qestion should pop up, if it is false, nothing should happen). Consider the following code, where I suppress everything unrelated to this problem.
from functools import partial
class KeyPad():
on_key_pad_pressed(self, btn, text):
cs = App.get_running_app().root.ids.calculation_screen
if text.isdigit():
answer_text.text += text
cs.current_answer = answer_text.text
elif text == 'clear':
answer_text.text = ''
elif text == 'submit':
cs.on_current_answer(self, btn, text)
elif text == 'joker'
Clock.schedule_once(partial(cs.on_current_answer(btn, MathBackEnd().get_true_answer()), 1)
class CalculationScreen(Screen):
current_answer = StringProperty('')
def __init__(self):
pass
def on_current_answer(self, btn, text):
true_answer = MathBackEnd().get_true_answer()
if text == true_answer:
Logger.info('CS: Cool! You got it')
else:
Logger.info('CS: Please try again.')
So there are at least 3 different ways in Kivy to achieve the wiring between the KeyPad (holds the information about the given answer) and the CalculationScreen (assess given answers). Note that the approach in the first if-case (cs.current_answer = answer_text.text) does work, because current_answer is a StringProperty. Therefore, when it changes, its callback on_current_answer will get called.
The submit button and the joker button both work fine. If you click 'submit' your answer gets checked. If you click 'joker' the correct answer gets checked with a one second penalty for pressing 'joker'. However answers should get checked automatically (first if-case in "on_key_pad_pressed") and this works except for one case: if the current true answer is the same as the former true answer. Suppose the first question is "3+4", you enter 7 and the game automatically checks your answer. It is true, so you get the next question "1+6". You enter 7... nothing happens. You click 'clear' to clear the answer_text label and press 7 again... nothing happens. You click 'submit'. The answer gets checked and you get the next question.
So, which of these 3 approaches is superior/inferior? Should I always use schedule_once (seems to be very robust)? Do you see why I get this buggy behavior in the first if case, if two successive (true) answers are equal? During calculation, the eventloop gets congested by a timer (timing the response of the user), which updates every tenth of a second. May this congestion lead to this weird behavior?
Any help is much appreciated!

Psychopy builder expt. - how to add live updating text on screen

I am creating an experiment using Psychopy builder.
The participant is presented with an image containing numbers, e.g. 10 and 20.
They enter what they think is the mean of the numbers, 15 in this case, and then press the spacebar to move on to the next image.
I am trying to have it so there is a display/box on screen that shows them their entry, as with larger numbers in the hundreds of thousands and millions I think they might lose track of what they have pressed.
The ability to change their entry would be excellent also, but really I am most interested in them being able to see it on screen.
In builder I can't find a way to do this, and the ratings scale is not appropriate for huge numbers.
I found these solutions in code to do something that sounds like it:
http://www.psychopy.org/wiki/home.php/Snippets/LiveUpdatingText
However when I try to add them using the code insert function , or just adding them to the compiled script the screen locks up when I try to run the experiment. I am a novice at python, and am not sure where to start fixing this. Is what I'm trying to do possible?
I'm happy to provide some example code from the compiled builder experiment.
Thanks in advance!
Those code snippets are designed for Coder, where you control everything that is happening and when. The same thing can be done in Builder, but you will have to amend the code to fit in with Builder's event loop cycle. i.e. Builder does certain things at the start of an experiment, on every trial, on every screen refresh and so on. So you can't just insert this sort of code without modification, because, for example, it attempts to wait indefinitely for a keypress. Builder meanwhile, is checking the keyboard every screen refresh (typically at 60 Hz), so if you try to wait indefinitely for a keypress in code, you'll be halting Builder from doing everything else it needs to do.
In essence, you just need to break up the code into snippets that go in the appropriate tab in a Builder Code Component (for code to be executed at experiment start, on each frame, and so on), and avoid indefinite functions like event.waitKeys() in favour of instantaneous checking via event.getKeys()
e.g. to adapt the second example from Jonas Lindeløv, in the "Begin Routine" tab, put:
chars = list('0123456789.') # the valid characters
meanText = '' # start with an empty answer on each trial
In the "Each Frame" tab, put something like:
response = event.getKeys() # get a list of keys pressed at this instant
if len(response) > 0: # if there was one,
key = response[0] # just convenient shorthand
if key in chars:
meanText = meanText + response[0]
elif key == 'space':
meanText = meanText + ' '
elif key == 'backspace' and len(meanText) > 0:
meanText = meanText[:-1]
elif key == 'return':
thisExp.addData('Answer', meanText) # save the response
continueRoutine = False # finish this trial
# update the appropriate text stimulus with the current response value:
insertNameOfYourTextStimulusComponent.text = meanText

How to check the state of a robot button using python?

i'm currently developping a program that runs on a robot. The program needs to add positions to a list but you have to push a button to add a new position. This has to be inside a while loop. But when i press the button the function repeats itself multiple times instead of just 1. Here is the part of code:
while not self.done():
if self._io_left_lower.state:
self._gripper_left.open()
elif self._io_left_upper.state:
self._gripper_left.close()
if self._io_right_lower.state:
self._gripper_right.open()
elif self._io_right_upper.state:
self._gripper_right.close()
if self._io_left_nav.button0:
print("repeats")
#self._mapping.append([self._limb_left.joint_angles(), self._gripper_left.position()])
if self._io_right_nav.button0:
self._mapping.append([self._limb_right.joint_angles(), self._gripper_right.position()])
if self._io_left_nav.button1:
self.stop()
As you can see when the self._io_left_nav.button0 is pressed it will now just print 'repeats' several times but it has to to be printed just onces. same for the self._io_right_nav.button0.
If button0 is a physical button and your loop is polling the button state then it is normal that many iterations run in the time your button is being pressed. You have several options to solve this situation, two of them are:
Do not use a loop check the button but hardware interruptions used to keep an updated representation of your state.
If you still want to use your loop, you should detect button state changes instead checking its current state at each iteration. That may require your program to implement a noise filter.
A very simple way to implement the second option is to have a button state variable with a timestamp associated: At each loop iteration, if the difference between the current time and the timestamp is big enought then you should check if the current state is the same than the one stored in the variable. If not then you have detected a change. In any case, at this point you should update your state-timestamp variable.
This is an example:
from time import time
prevState = (False,time())
while not self.done():
current = time()
if self._io_left_nav.button0 and (current-prevState[1])*1000>2: #For example, 2 ms
if self._io_left_nav.button0 != prevState[0]:
print("repeats")
prevState = (self._io_left_nav.button0,time())
I presume that's some kind of flag, that the button was pressed.
If you don't clear the state, the condition in the if statement will evaluate true. Again, and again....

Change Sikuli's sensitivity?

I've been using sikuli for awhile, however I have an issue with it... It's not sensitive enough. I'm trying to match something on the screen that is -EXACT-, and there are a few other items on the screen that look similar enough that sikuli is mistaking them for what I'm actually looking for, so I need to make it look for ONLY this item with no variances at all.
How can I do this?
Oh and to explain my issue a bit further, I am writing a loop for a game, once a progress bar has reached 100% - it needs to allow the loop to finish (And start over again), however the progress bar is just a plain bar - so when sikuli looks for it on the screen, it finds the partially complete bar (Since apparently it matches different lengths/widths/sizes of the image it is looking for), and triggers.
You can do the following in the Sikuli IDE:
Click on the image
In Pattern Settings > Matching Preview, drag the Similarity bar to 1.0 (all the way to the right)
Click OK
If you are using Sikuli IDE click image miniature, for which you want to change sensitivity. You will be presented screenshot of your desktop with and occurrences of pattern(your image). Below there is a slider witch changes sensitivity. While changing it you will notice that highlighted occurrences of the pattern increase or decrease accordingly.
This method assumes that you have your game on screen (so windowed mode, not fullscreen), but even if you don't you still can adjust sensitivity, just you won't see 'live' results of search.
If you call sikuli from Java code, you have to use Pattern(image.png).similar(y.xx)
where the argument of simmilar is something between 0.00 and 1.00.
I haven't used second method so you may need to experiment with it.
Will the following work?
You are looking for the progress to reach 100% then loop again?
f = open("C:\\test.htm",'W')
f.write('<font color="#347C2C">lOOPtEST</font><br />')
f.write('loop iteration' + (str (count)) + '<br />')
count = count + 1
f.close()
COUNT =10
POPUP("LOOPTEST")
//image compare from progress bar
import sikuli.Sikuli *
WebPath =('Z:\\ZZZautomation\\Web\\')
BuildPath = ("Z:\BUILDS\Daily_BUILDS\QA_MainBranch_Install\*.install")
BuildNumber = glob.glob("Z:\BUILDS\Daily_BUILDS\QA_MainBranch_Install\*.install")
for filename in BuildNumber:
SmokeTestInfo = "SmokeTest_Build " + filename[45:50] + " Iteration 44"+".htm"
global Number
Number = filename[45:50]
global SmokeTest
SmokeTest = SmokeTestInfo
global count
count = 0
defMidProgress():
while not exists ("//path to image of progress bar # 50%//",FOREVER)
//or
wait("//path to image of progress bar # 50%//", FOREVER)
//using forevEr means sikuli will checK FOR 50% PROGRESS FOREVER
//the bottom execures once the condition above is met
open(WebPath + SmokeTest,'w')
f.write('<font color="#0000FF">Progress is at 50%</font><br />')
f.close()
// writes entry to html log fie
defFinalProgress():
while not exists ("//path to image of progress bar # 100%//",FOREVER)
//or
wait("//path to image of progress bar # 100%//", FOREVER)
//using forever means sikuli will check FOR 100% PROGRESS FOREVER
//the bottom execures once the condition above is met
open(WebPath + SmokeTest,'a')
f.write('<font color="#0000FF">Progress is at 100%</font><br />')
f.close()
// writes entry to html log fie
def Loop
count =0
def midProgress():
def FinalProgress():
To match an exact image I use:
image1 = ("image1.png")
while not exists (Pattern(image1).exact()):
# Wait until that exact image appears.
wait(1)

Categories

Resources