A little misunderstanding timers in python - python

can somebody tell me how to use this class timers from python in my code more than one time.
import MOD
class timer:
def __init__(self, seconds):
self.start(seconds)
def start(self, seconds):
self.startTime = MOD.secCounter()
self.expirationTime = self.startTime + seconds
if seconds != 0:
self.running = 1
self.expired = 0
else:
self.running = 0
self.expired = 0
def stop(self):
self.running = 0
self.expired = 0
def isexpired(self):
if self.running == 1:
timeNow = MOD.secCounter()
if timeNow > self.expirationTime:
self.running = 0
self.expired = 1
else:
self.expired = 0
return self.expired
def isrunning(self):
if self.running == 1:
timeNow = MOD.secCounter()
if timeNow > self.expirationTime:
self.running = 0
self.expired = 1
else:
self.expired = 0
return self.running
def change(self, seconds):
self.expirationTime = self.startTime + seconds
def count(self):
if self.running == 1:
timeNow = MOD.secCounter()
return (timeNow - self.startTime)
else:
return -1
they write this comment:
The following is a simple example about how to use this class:
import timers
timerA = timers.timer(0)
timerA.start(15)
while 1:
if timerA.isexpired():
print 'timerA expired'
break
but I don't know how to use it more than one time in my code, because I need to use more than one timer in my code,
should I write
timerB = timers.timer(1)
timerB.start(1800)
while 1:
if timerB.isexpired():
print 'timerA expired'
break
any help, please

Close - the argument to timers.timer is the number of seconds that the timer should time for at first. But every time you call timers.timer(), you'll get a new timer instance.
So your code could look more like:
timerB = timers.timer(1800)
while 1:
if timerB.isexpired():
print 'timerA expired'
break
Except that this is misleading - timerA and timerB are separate timers, so timerB.isexpired() won't tell you anything about timerA. Maybe you meant it to read "timerB expired"?
And I would also advise against polling timerB.isexpired() so rapidly. Maybe sleep for a second after each check?

Related

How can I share a variable from a thread to my main in python?

I'm trying to share two variables for a comparation in a conditional in my main, but I am getting errors whenever I set the variables as global, saying that the variable was started before global statement.
Here is a peek to the code:
#thread timer for minute
class myMin(Thread):
def run(self):
global now
global timestart
n=1
while True:
n=1
timestart = time.time()
now = time.time()
while now-timestart <= 10:
now = time.time()
print('banana')
n=0
#thread timer for the hour
class myHour(Thread):
def run(self):
global now2
global timestart2
m=1
while True:
m=1
timestart2=time.time()
now2 = time.time()
while now2-timestart2 <= 20:
now2 = time.time()
print('uvas')
m =0
mymin=myMin()
myhour=myHour()
#thread execution
mymin.start()
myhour.start()
#Main program counting
while True:
time.sleep(0.5)
global m
global n
count = count+1
countperhour=countperhour+1
countpermin=countpermin+1
if m == 0:
copm = countpermin
countpermin=0
if n == 0:
coph=countperhour
countpermin=0
You shouldn't be declaring global m, n inside your loop.
There are other improvements that can be done to your code but below one runs
from threading import Thread
import time
#thread timer for minute
class myMin(Thread):
def run(self):
global now
global timestart
n=1
while True:
n=1
timestart = time.time()
now = time.time()
while now-timestart <= 10:
now = time.time()
print('banana')
n=0
#thread timer for the hour
class myHour(Thread):
def run(self):
global now2
global timestart2
m=1
while True:
m=1
timestart2=time.time()
now2 = time.time()
while now2-timestart2 <= 20:
now2 = time.time()
print('uvas')
m =0
count = 0
countperhour = 0
countpermin = 0
global m
global n
m, n = 0,0
mymin=myMin()
myhour=myHour()
#thread execution
mymin.start()
myhour.start()
#Main program counting
while True:
time.sleep(0.5)
count = count+1
countperhour=countperhour+1
countpermin=countpermin+1
if m == 0:
copm = countpermin
countpermin=0
if n == 0:
coph=countperhour
countpermin=0

Python - Keyboard module - Threading problem

Hi everyone,
I am working on an app and trying to create a corrector and I am using keyboard module for the correction.
I have created two classes, one keyboard monitor, which reads pressed events and displays them to screen, and one which suppresses them.
What I want to achieve is while the app corrects user input, every text that is typed by the user is suppressed and saved in a variable, for later use.
I am struggling on the synchronization of all this.
import keyboard
import threading
import time
lock_for_listening_to_keyboard = threading.Lock()
#########################################################
def delete_and_write(times_to_delete, word_to_write):
global lock_for_listening_to_keyboard
time.sleep(2)
print("OK")
# for i in range(50):
# keyboard.write('*')
# for i in range(times_to_delete+1):
# keyboard.press_and_release('backspace')
# for i,char in enumerate(word_to_write):
# keyboard.write(char.upper())
# for i in range(40):
# keyboard.write('*')
# keyboard.write(' ')
#########################################################
class keyboard_not_suppressed_monitor(threading.Thread):
def __init__(self, threadID, keyboardSupress):
threading.Thread.__init__(self)
self.threadID = threadID
self.fstring = ""
self.counter_for_key_presses = 0
self.suppressed = False
def run(self):
while(True):
event = keyboard.read_event(suppress=self.suppressed)
if (event.event_type == keyboard.KEY_DOWN):
# print("Key pressed = {} + suppress = {}".format(event.name, self.suppressed))
if (event.name == "space"):
suppressed_monitoring = keyboard_suppressed_monitor(2, self.fstring, self.counter_for_key_presses, None)
suppressed_monitoring.start()
suppressed_monitoring.join()
print("RETURNED TO MAIN MONITOR")
self.counter_for_key_presses = 0
self.fstring = ""
elif (event.name in "abcdefghijklmnopqrstuvwxyz"):
self.fstring = ''.join([self.fstring, event.name])
self.counter_for_key_presses += 1
class keyboard_suppressed_monitor(threading.Thread):
def __init__(self, threadID, fstring, counter_for_key_presses, keyboardSupress):
threading.Thread.__init__(self)
self.threadID = threadID
self.fstring = fstring
self.counter_for_key_presses = counter_for_key_presses
self.suppressed = True
self.done = False
self.temp = ""
def stop(self):
self._is_running = False
def run(self):
self.temp = self.fstring
self.fstring = ""
thread_delete_and_rewrite = threading.Thread(
target = delete_and_write, args=(self.counter_for_key_presses, self.temp))
thread_delete_and_rewrite.start()
# thread_delete_and_rewrite.join() # join is not here
print("RETURNED FROM THE REWRITER")
while(True):
print("STATE OF THREAD IS : {}".format(thread_delete_and_rewrite.is_alive())) print("IN THE WHILE TRUE")
event = keyboard.read_event(suppress=self.suppressed)
if (event.event_type == keyboard.KEY_DOWN):
print("KEYS PRESSED WHILE SUPPRESSED = {}".format(event.name))
if (event.name == "space"):
print("THE STRING ENTERED ")
self.temp = self.fstring
self.fstring = ""
thread_delete_and_rewrite = threading.Thread(
target = delete_and_write, args=(self.counter_for_key_presses, self.temp))
thread_delete_and_rewrite.start()
self.counter_for_key_presses = 0
self.fstring = ""
elif (event.name in "abcdefghijklmnopqrstuvwxyz"):
self.fstring = ''.join([self.fstring, event.name])
self.counter_for_key_presses += 1
# thread_delete_and_rewrite.join() # join is not here
print("SUPPRESSED ENDED")
self._is_running = False
if __name__ == "__main__":
kb = keyboard_not_suppressed_monitor(1, None)
kb.start()
kb.join()
I am trying to return the control when the function of correction is done, but can't make it work.
Any help is appreciated.
* UPDATE 1*
I made one class for all and works almost perfect.
I have one little problem that when the second while loop ends it requires a key press to exit. Is there a solution to this.
import keyboard
import threading
import time
lock_for_listening_to_keyboard = threading.Lock()
global running_suppressed_monitor
running_suppressed_monitor = False
#########################################################
def delete_and_write(times_to_delete, word_to_write):
global running_suppress_monitor
print("---Deleting & Rewrite Started---")
time.sleep(2)
running_suppressed_monitor = False
print("---Deleting & Rewrite Ended---")
# for i in range(times_to_delete+1):
# keyboard.press_and_release('backspace')
# for i,char in enumerate(word_to_write):
# keyboard.write(char.upper())
# keyboard.write(' ')
def write_the_suppressed_string(string):
keyboard.write(string)
#########################################################
class keyboard_monitor(threading.Thread):
def __init__(self,thread_name, threadID, word_typed, keyboard_suppress, counter_for_key_pressed):
threading.Thread.__init__(self)
self.name = thread_name
self.threaID = threadID
self.fstring = word_typed
self.counter_for_key_presses = counter_for_key_pressed
self.suppressed = keyboard_suppress
self.temp = ""
def stop(self):
self._is_running = False
def run(self):
if (self.suppressed is False):
while(True):
event = keyboard.read_event(suppress = self.suppressed)
if (event.event_type == keyboard.KEY_DOWN):
if (event.name == "space"):
suppressed_monitor = keyboard_monitor("suppressed_monitor", 2, self.fstring, True, self.counter_for_key_presses)
suppressed_monitor.start()
suppressed_monitor.join()
print("RETURNED TO MAIN MONITOR")
self.counter_for_key_presses = 0
self.fstring = ""
elif (event.name in "abcdefghijklmnopqrstuvwxyz"):
self.fstring = ''.join([self.fstring, event.name])
self.counter_for_key_presses += 1
elif (self.suppressed is True):
self.temp = self.fstring
self.fstring = ""
thread_delete_and_rewrite = threading.Thread(
target = delete_and_write, args=(self.counter_for_key_presses, self.temp))
thread_delete_and_rewrite.start()
running_suppressed_monitor = True
# while(thread_delete_and_rewrite.is_alive()):
while(running_suppressed_monitor):
event = keyboard.read_event(suppress=self.suppressed)
if (event.event_type == keyboard.KEY_DOWN):
print("KEYS PRESSED WHILE SUPPRESSED = {}".format(event.name))
if (event.name == "space"):
self.temp = self.fstring
self.fstring = ""
thread_delete_and_rewrite = threading.Thread(
target = delete_and_write, args=(self.counter_for_key_presses, self.temp))
thread_delete_and_rewrite.start()
# thread_delete_and_rewrite.join()
self.counter_for_key_presses = 0
self.fstring = ""
elif (event.name in "abcdefghijklmnopqrstuvwxyz"):
self.fstring = ''.join([self.fstring, event.name])
self.counter_for_key_presses += 1
# NO thread_delete_and_rewrite.join()
# NO thread_delete_and_rewrite.join()
if (thread_delete_and_rewrite.is_alive() is False):
break
thread_delete_and_rewrite.join()
print("SELF.FSTRING = {}".format(self.fstring))
print("BEFORE END OF SUPPRESSED MONITOR")
if (self.fstring != ""):
thread_write = threading.Thread(
target = write_the_suppressed_string, args=(self.fstring, ))
thread_write.start()
thread_write.join()
print("SUPPRESSED ENDED")
self._is_running = False
if __name__ == "__main__":
kb_not_suppressed = keyboard_monitor("not_suppressed_monitor", 1, "", False, 0)
kb_not_suppressed.start()
kb_not_suppressed.join()

Don't understand this timed while loop attribute error

So I have been trying to make a while loop that will run for 10 minutes. But is keeps erroring out on the line with the while loop. It says 'str' object has no attribute 'time'.
I have discovered that if i remove the lines with now.strftime() in them that the code runs but I don't know why it runs without those lines or how to fix it.
I did also try to do something using the datetime module instead of importing the time module but this also fails.
import math
from datetime import datetime
import time
test_num = 1
largest_loop = 0
delay = 60 * 10
end_time = time.time() + delay
def even_number(value):
if value == 2:
return True
def divide_five(value):
if value == 5:
return True
def is_square(value):
if math.sqrt(value).is_integer():
return False
def multiple_of(value):
if value == 2:
return True
def is_happy():
global check
if check == 1:
return True
while time.time() <= end_time:
test_num += 1
check = test_num
now = datetime.now()
loop_counter = 0
record_loop = 6
date = now.strftime("%m/%d/%Y")
time = now.strftime("%H:%M:%S")
if even_number(test_num) == True:
if divide_five(test_num) == True:
if is_square(test_num) == True:
for _ in range(record_loop + 4):
loop_counter += 1
if is_happy() == True:
if multiple_of(test_num) == True:
#print(test_num)
record_loop = loop_counter
break
else:
pass
else:
pass
else:
pass
else:
pass
else:
pass
As #CoryKramer pointed out, you named a variable time, which is also the name of the module you are importing. All I really did was change the time variable to something like currTime. Try the code below (runs for me):
import math
from datetime import datetime
import time
test_num = 1
largest_loop = 0
delay = 60 * 10
end_time = time.time() + delay
def even_number(value):
if value == 2:
return True
def divide_five(value):
if value == 5:
return True
def is_square(value):
if math.sqrt(value).is_integer():
return False
def multiple_of(value):
if value == 2:
return True
def is_happy():
global check
if check == 1:
return True
while time.time() <= end_time:
test_num += 1
check = test_num
now = datetime.now()
loop_counter = 0
record_loop = 6
date = now.strftime("%m/%d/%Y")
currTime = now.strftime("%H:%M:%S")
if even_number(test_num) == True:
if divide_five(test_num) == True:
if is_square(test_num) == True:
for _ in range(record_loop + 4):
loop_counter += 1
if is_happy() == True:
if multiple_of(test_num) == True:
#print(test_num)
record_loop = loop_counter
break
else:
pass
else:
pass
else:
pass
else:
pass
else:
pass
Additionally, consider reading up on:
How to name a module without conflict with variable name?
https://en.wikipedia.org/wiki/Variable_shadowing
dont name your variable in your while loop time when you import the time library:
time = now.strftime("%H:%M:%S")
in your while loop you want to use the time function of the time library but as soon as you run the while loop once it will try to use time() on the string time you defined in the while loop.
I think the problem is here:
time = now.strftime("%H:%M:%S")
Thus, you converted time into a string variable. Name this variable in a different way!
Apart from this, running for 10 minutes at "full throttle" is a lot! Consider to introduce a "sleep" time at the end of the while loop (just suggesting)

Can't make walking animations in pygame

I was trying to code a game in pygame, but then when I tried to make a walking animation it only displayed one of the sprites.
def go_left(time):
ness_current = 1
global ness
global is_walking_left
ness_list = [ness_walking,ness_standing]
current_time = pygame.time.get_ticks()
go_left.walking_steps = 1
now = 0
cooldown = 1000
flag = 0
ness = ness_list[ness_current]
print current_time - game_loop.animation_timer
if (current_time - game_loop.animation_timer) > 200:
print 'Changing'
if ness_current == 0:
print 'Changing to sprite 1'
now = pygame.time.get_ticks()
ness_current = 1
current_time = now
elif ness_current == 1:
print 'Changing to sprite 0'
if (current_time - game_loop.animation_timer) > 200:
ness_current = 0
current_time = now
else:
'Changing to sprite 0 because of sprite reset'
ness_current = 0
current_time = now
def stop_it():
global ness
ness = pygame.image.load('nessthekid.png').convert()
ness.set_colorkey(WHITE)
car_list = pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
player_list = pygame.sprite.Group()
When I try to use this it only displays one of the sprites not the other for the character. I want it to swich every 1 or 2 seconds to make it look like its walking. Help is appreciated.
First, I highly suggest using a class, to avoid using global variables.
Second, as you set the current time back to now (0), you will make it so current_time - game_loop.animation_timer will always be negative. This will keep the statement from running.
For now, I suggest completely removing the "if (current_time - game_loop.animation_timer) > 200:" from your code.
Here is an example to get you started (obviously you will have to alter it to make it work for you)
class Ness:
def __init__(self):
self.all_images = [ness_walking,ness_standing]
self.current = 0
self.image = self.all_images[self.current]
def walk_left(self):
# Every 200 clicks
if pygame.time.get_ticks() % 200 == 0:
if self.current == 0:
self.current = 1
else:
self.current = 0
self.image = self.all_images[self.current]
As suggested by #Red Twoon put the stuff separated in class is a very good practice. Another thing that you should do is no rely in get_ticks directly but instead use some kind of time independent movement/animation.
You can achieve this using delta times in your game loop.
Game loop.
while(True):
delta = #Get the delta time.
handle_events();
update(delta);
draw(delta);
#Animation stuff.
time_to_animate_frame = 200;
time_since_last_update = 0;
...
time_since_last_update += delta;
if(time_since_last_update > time_to_animate_frame):
time_since_last_update - time_to_animate_frame;
#Do the animation.....

Python Threading Issue when starting multiple threads

I would like to start 4 independent threads which are basically methods of a class.
What am I doing wrong in the code below:
from threading import Thread
import time
import random
class Creature:
def __init__(self, name):
self.name = name
def melee(self, level):
self.melee = level
def shielding(self, level):
self.shielding = level
def health(self, total):
self.health = total
def attack(self, attacker, opponent):
while 0 != 1:
power = random.randint(1, attacker.melee)
resistance = random.randint(1, opponent.shielding)
resultant = power - resistance
if resistance > 0:
opponent.health -= resistance
if opponent.health < 0:
print(opponent.name, " is dead")
print("Opponent's health ", opponent.health)
quit()
else:
print(attacker.name, " delivered an attack of ", resistance)
print("Opponent's health ", opponent.health)
def healing(self, healed):
while 0 != 1:
if healed.health <= 0:
if healed.health < 50:
life = random.randint(1, 50)
healed.health += life
if healed.health > 100:
healed.health = 100
print(healed.name, " has healed and now has a health of ", self.health)
Monster = Creature("Wasp")
Monster.health = 100
Monster.melee = 30
Monster.shielding = 15
Player = Creature("Knight")
Player.health = 100
Player.melee = 25
Player.shielding = 20
t1 = Thread(target=Player.attack(Monster, Player))
t1.start()
t2 = Thread(target=Monster.attack(Player, Monster),)
t2.start()
t3 = Thread(target=Player.healing(Player), args=())
t3.start()
t4 = Thread(target=Monster.healing(Monster), args=())
t4.start()
Somehow I am doing something wrong since only the t1 gets started.
Why does the program start only t1? :-(
Thanks!
The problem(s) in your code are all demonstrable in this one line:
t1 = Thread(target=Player.attack(Monster, Player))
The trouble is that you're calling Player.attack, not passing it to the Thread constructor. Your attack method never returns, so you never get past the attempt to create the first Thread. You'd want to do something like this:
t1 = Thread(target = Player.attack, args = (Monster, Player))

Categories

Resources