I have reviewed the answers to similar questions and have tried various recommended iterations but am not having any luck. I am getting this error "UnboundLocalError: local variable 'rundate1' referenced before assignment" on the line "return pick.CalendarFrame(rundate1)". My code is
def GetCalendar():
os.system("Pick.py")
def rundate1():
result = tkinter.messagebox.askyesno(title="Rundate", message="back 7 days?")
#result = tkinter.messagebox.askyesno()
if result == True:
rundate1 = date.today() - timedelta(7)
print("rundate 1 = ", rundate1)
return rundate1
else:
GetCalendar()
return pick.CalendarFrame(rundate1)
print("rundate 1 = ", rundate1)
return rundate1
rundate = rundate1()
print("rundate = ", rundate)
The first part of the if statement works fine, I click yes and get the return data. When "no" is clicked my calendar dialog pops up and I can pick my dates but then it all falls apart. The app "Pick.py" works great on it's own. The submit for the CalendarFrame is
def submit():
start = self.result1.strftime("%m/%d/%Y")
end = self.result2.strftime("%m/%d/%Y")
rundate1 = start, end
return rundate1
print(rundate1)
Help would be very nuch appreciated
Related
I'm trying to use this python library https://github.com/pimoroni/keybow-python to control a raspberry pi (initiate events, e.g. launch a script or shutdown the pi).
This works will so far. I'm struggling to detect a long press. The API linked above allows 'catching' the event of pressing the button or releasing it. Not sure how I go about measuring the time between one and the other... I tried this:
`
def time_string_to_decimals(time_string):
fields = time_string.split(":")
hours = fields[0] if len(fields) > 0 else 0.0
minutes = fields[1] if len(fields) > 1 else 0.0
seconds = fields[2] if len(fields) > 2 else 0.0
return float(hours) + (float(minutes) / 60.0) + (float(seconds) / pow(60.0, 2))
while True:
t = datetime.now().strftime('%H:%M:%S')
now = time_string_to_decimals(t)
#keybow.on()
def handle_key(index, state):
key0Up = 0
key0Down = 0
if index == 0 and state:
key0Down = now
print ("down: " + str(now))
if index == 0 and not state:
key0Up = now
downtime = key0Up - key0Down
print ("down: " + str(now))
print ("up: " + str(now))
print ("downtime: " + str(downtime))
if downtime >= 0.001:
print ("shutdown!")
if index == 3 and not state:
print ("Hello!")
if index == 6 and not state:
print ("World!")
`
... the print commands are just to follow what's going on. The problem is that the key0Down also get's set to the current time when the button is released. I'm stumped. Can anyone point me in the right direction?
Thanks!
Best regards,
Andrew
See above... I keep getting the same 'timestamp' for the key Down und key Up event...
It sounds like your issue is that when the #keybow.on decorator attaches the callback it has a static value for now that doesn't get updated by the while loop which will be in a different scope. Repeatedly declaring the callback during the while loop looks wrong also.
I don't have this hardware so it is not possible for me to test this. However, looking through the repository you linked to I would be tempted to do the following...
As you need to share the key events timings between functions I would put them into a class and have class variables for the key0up and key0down values.
I have also gone for different event handlers for the different keys to simplify the complex chain of if statements.
I was not sure if the keybow on decorator would do the right thing if used inside a class, so I have attached callbacks to keys without using a decorator.
import keybow
import time
class MyKeys:
key0Up = 0
key0Down = 0
def handle_key0(self, index, state):
if state:
self.key0Down = time.time()
print("down: ", self.key0Down)
elif not state:
self.key0Up = time.time()
downtime = self.key0Up - self.key0Down
print("down: ", self.key0Down)
print("up: ", self.key0Up)
print("downtime: ", downtime)
if downtime >= 1: # Greater than 1 second
print("shutdown!")
def handle_key3(self, index, state):
if not state:
print("Hello!")
def handle_key6(self, index, state):
if not state:
print("World!")
def main():
my_keys = MyKeys()
keybow.on(0, my_keys.handle_key0)
keybow.on(3, my_keys.handle_key3)
keybow.on(6, my_keys.handle_key6)
while True:
keybow.show()
time.sleep(1.0 / 60.0)
if __name__ == '__main__':
main()
So in my tkinter python program I am calling on a command when a button is clicked. When that happens it runs a function but in the function I have it set a label to something on the first time the button is clicked and after that it should only update the said label. Basically after the attempt it changes the attempt to 1 ensuring the if statement will see that and not allow it to pass. However it keeps resetting and I don't know how to stop it. When you click the button no matter first or third the button resets and proof of that occurs because the h gets printed. It's as if the function restarts but it shouldn't since it's a loop for the GUI.
def fight(): #Sees which one is stronger if user is stronger he gets win if no he gets loss also displays enemy stats and removes used characters after round is finished
try:
attempt=0
namel = ""
namer=""
left = lbox.curselection()[0]
right = rbox.curselection()[0]
totalleft = 0
totalright = 0
if left == 0:
namel = "Rash"
totalleft = Rash.total
elif left==1:
namel = "Untss"
totalleft = Untss.total
elif left==2:
namel = "Illora"
totalleft = 60+35+80
if right == 0:
namer = "Zys"
totalright = Zys.total
elif right==1:
namer = "Eentha"
totalright = Eentha.total
elif right==2:
namer = "Dant"
totalright = Dant.total
lbox.delete(lbox.curselection()[0])
rbox.delete(rbox.curselection()[0])
print(namel)
print(namer)
if attempt == 0:
wins.set("Wins")
loss.set("Loss")
print("h")
attempt=1
if (totalleft>totalright):
wins.set(wins.get()+"\n"+namel)
loss.set(loss.get()+"\n"+namer)
else:
wins.set(wins.get()+"\n"+namer)
loss.set(loss.get()+"\n"+namel)
except IndexError:
pass
Also for those of you who saw my previous question I still need help with that I just also want to fix this bug too.
At beginning of function fight you set attempt = 0 so you reset it.
Besides attempt is local variable. It is created when you execute function fight and it is deleted when you leave function fight. You have to use global variable (or global IntVar)
attempt = 0
def fight():
global attempt
BTW: of you use only values 0/1 in attempt then you can use True/False.
attempt = False
def fight():
global attempt
...
if not attempt:
attempt = True
So I am just learning Python and am working on an online exercises to get use to the language and software itself. Right now I am working on making one function (getData()) run and then the results from that function to run into another function (getStats()) that is all with a main(). Each one works individually but I am having a problem with the main(). I can get my first getData() to run and make my list but I can't get that list to run directly into getStats(). It actually runs the getData() again and then comes back with an error message when I put in an input . Does anyone have any suggestions for me to not get that error message and then to actually run my getStats()?
def getData():
import math
pop = []
while True:
user = raw_input("Please enter a population number (-1 to quit): ")
pop.append(user)
if user == '-1':
break
if user <= '0':
print "Population not valid, please input a value higher then 0"
new_pop = map(int, pop)
pop2 = filter(lambda x:x >=1, new_pop)
print "Your population list is: ", pop2
return
def getStats():
i = ""
asc = sorted(i)
print "The collected data in the asecending order", asc
dec = sorted(i, reverse = True)
print "The collected data in the descending order", dec
maxi = max(i)
print "The maximum of the collected data is", maxi
mini = min(i)
print "The minimum of the collected data is",mini
def getMean(i):
aver = round(sum(i), 2)/round(len(i), 2)
print "The average of the collected data is %.2f" % aver
getMean(i)
def getStdev(i):
aver = sum(i)/len(i)
var = sum(pow(user-aver,2) for user in i)/len(i)
stdev = math.sqrt(var)
print "The standard deviation of the collected data is %.2f" % stdev
return
def main():
getData()
getStats(getData())
main()
The variables inside each function cannot be accessed by other functions variable/function scope.
One way to use them is to have the function return those values. Here is a simplified example:
def get_data():
data = raw_input('Ask for data')
return data
def get_stats(data):
sorted_data = sorted(data)
print 'Sorted:', sorted_data
data = get_data() # get_data will point 'data' to the value returned
get_stats(data) # call get_stats, and pass 'data' as an argument
Some other thoughts:
You don't really need the main() function. It's not doing anything.
What is more common, is adding a conditional statement to only run this if you are running the file itself, but not when it's imported as a module:
if __name__ == '__main__':
data = get_data()
get_stats(data)
Check out PEP 008
Usually your imports should be at the beginning of the file (Imports)
Function names are camel_case
I'm trying to make a program that is effectively an alarm clock. It's more complicated than it might seem that it needs to be, but there are reasons for that, that I won't go into here. The issue I'm having, though, is that I create an Alarm object inside a nested function, but whatever I do, I can't get that object to be accessed outside of that function... I've attached the abridged code below. Any of the calls to "check" or "set" etc. outside of setAlarm can never find the "alarm" variable. Please let me know what I'm doing wrong — I tried declaring the variable as global, as you'll see, but it still doesn't work out...
Thanks!
class Alarm(threading.Thread):
def __init__(self, datetime, grace, close):
super(Alarm, self).__init__()
self.datetime = datetime
self.grace = grace
self.close = close
self.keep_running = True
def run(self):
try:
while self.keep_running:
now = datetime.datetime.now()
if now > self.datetime + datetime.timedelta(minutes=self.grace):
print "Oh no! It's %02d:%02d, which is %d minutes past your alarm time of %02d:%02d!" % (now.hour,now.minute,self.grace,self.datetime.hour,self.datetime.minute)
print "ALARM NOW!\a\a\a\a\a\a\a\a\a\a"
break
time.sleep(10)
except:
return
def just_die(self):
self.keep_running = False
def setAlarm():
print "What time would you like to set the alarm for? (in 00:00 military time please)"
wakeup = raw_input()
wakeuphour = int(wakeup[:2])
wakeupmin = int(wakeup[3:])
now = datetime.datetime.now()
if now.hour > wakeuphour or (now.hour == wakeuphour and now.minute > wakeupmin):
alarmday = now + datetime.timedelta(days=1)
alarmtime = datetime.datetime(alarmday.year,alarmday.month,alarmday.day,wakeuphour,wakeupmin)
else:
alarmtime = datetime.datetime(now.year,now.month,now.day,wakeuphour,wakeupmin)
close = 15
grace = 5
alarm = Alarm(alarmtime, grace, close)
if alarmtime.day != now.day:
print "Your alarm is set for %02d:%02d tomorrow." % (alarmtime.hour,alarmtime.minute)
else:
print "Your alarm is set for %02d:%02d today." % (alarmtime.hour, alarmtime.minute)
def runAlarm():
setAlarm()
alarm.start()
while True:
print "You can say 'stop', 'check', 'change', 'set', or 'quit'"
text = str(raw_input())
if text == "stop":
if alarm != 0:
alarm.just_die()
alarm = 0
print "Okay, I've cancelled the alarm."
else:
print "There was no alarm to stop..."
elif text == "check":
if alarm == 0:
print "Sorry, you don't have any alarm set. To create an alarm, type 'set'"
else:
pass
elif text == "change":
pass
elif text == "set":
alarm = 0
setAlarm()
alarm.start()
elif text == "quit":
print "Sure thing. Bye bye!"
break
else:
print "Sorry, I didn't understand that. Please try again."
You've created alarm as a local variable. Variables defined in a function are local by default, and local means exactly what it sounds like—it only exists inside that function.
You could fix this by explicitly making it a global variable. That's not a great idea, but it's the smallest change. Just add the statement global alarm to the top of both setAlarm and every function that wants to access it.
A better solution is to return alarm from setAlarm. Then, in the code that calls it, just store the return value. For example:
def setAlarm():
# your existing code
return alarm
def runAlarm():
alarm = setAlarm()
# your existing code
Now, runAlarm has its own local reference to the same object, also named alarm, so it can use that.
i have this code:
class Check(webapp.RequestHandler):
def get(self):
user = users.get_current_user()
be = "SELECT * FROM Benutzer ORDER BY date "
c = db.GqlQuery(be)
for x in c:
if x.benutzer == user:
s=1
break
else:
s=2
if s is 0:
self.redirect('/')
to check whether the user is registered or not.
but it gives me an error:
Traceback (most recent call last):
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/__init__.py", line 511, in __call__
handler.get(*groups)
File "/Users/zainab_alhaidary/Desktop/الحمد لله/check.py", line 23, in get
if s is 0:
UnboundLocalError: local variable 's' referenced before assignment
what should i do???
Define s before to assign it a value (also, change the test on s):
user = users.get_current_user()
be = "SELECT * FROM Benutzer ORDER BY date "
c = db.GqlQuery(be)
s=0 # <- init s here
for x in c:
if x.benutzer == user:
s=1
break
else:
s=2
if s == 0: # <- change test on s
self.redirect('/')
Why exactly are you loading all users, then looping through them, just to find one? Use a where clause:
be = "SELECT * FROM Benutzer WHERE benutzer=:1"
c = db.GqlQuery(be, user)
user_from_db = c.get()
if user_from_db is not None: # found someone
dostuff()
else:
self.redirect('/')
You're using 's' before you assign something to it. Add an 's = 0' in the appropriate location.
You want to set s to 0 before the for loop starts. If the query returns zero items, your for loop doesn't loop even once, so s is undefined.
Also, you should use if s == 0: instead of if s is 0:. In CPython, they are both equivalent, but you shouldn't rely on the fact. See: the documentation for PyInt_FromLong and "is" operator behaves unexpectedly with integers.
Your problem is that if c is an empty list then the code in the for loop is never run and s never gets set, hence the error:
UnboundLocalError: local variable 's' referenced before assignment
What the error is telling you that you're referencing - i.e. using - s before it has any value - i.e. before a value has been assigned to it.
To fix this you just ensure s always is assigned a value:
s = 0
for x in c:
if x.benutzer == user:
s = 1
break
else:
s = 2
In the case that c is empty the if statement in the loop never gets executed
you should set s=0 before the for loop
I don't know why you are doing this, but if I understand your code correctly, you have s=1 when x.benutzer == user, and s=2 otherwise (shouldn't this be s=0 if you are going to check against 0?).
for x in c:
if x.benutzer == user:
s=1
break
else:
s=2
if s is 0:
self.redirect('/')
Anyway, here's my solution:
if not any(x.benutzer == user for x in c):
self.redirect('/')