Related
I'm new to python, I have this knapsack problem where there are items and their weight. The user will insert their priority (low-medium-high). And then the GA will then run to find the best backpacking list that maximizes the priority points without exceeding the maximum weight (30kg).
I did most of the genetic operators, except the termination condition (after 20000 generations or when the fitness reaches 1) did not work,and the graph (plot) of the GA's performance is not showing.
The code:
import matplotlib.pyplot as plt
import random
import time
from unittest import result
# Data (search space)
items = {
'Sleeping bag': 10,
'Rope': 3,
'Pocket Knife': 2,
'Torch': 5,
'Water Bottle': 9,
'Glucose': 8,
'First aid supplies': 6,
'Rain jacket': 3,
'Personal Locator Beacon': 2
}
Genome = list[int]
# Number of items
ITEMS_COUNT = len(items)
# # Number of points for the multi point crossover entered by the user. Default is 3
N_POINT = 3
# # Number of individulas in the population filled with some permutation of 0s and 1s entered by the user. Default is 50
POP_SIZE = 20
# # Elitisim for selection. Default is True
ELITISM = True
# # Number of generations entered by the user. Default is 200
GENERATIONS = 200
# # Crossover probability enterd by the user. Default is 0.1
CROSSOVER_PROBABILTY = 0.1
# # Mutate probability entered by the user. Defaulst is 0.05
MUTATION_PROBABITLY = 0.05
# Priorities
itemsPriorities = {'low': 5, 'medium': 10, 'high': 15}
# User input
def user_input():
print('Welcome to Smart Hiker Backpacking!')
print('Input your priority for items based on the priority legend: ')
print('Low \t Medium \t High')
print()
print('Choose your priority for these items below: ')
print('-'*50) # design: ------
for item, _ in items.items(): # Print items
print(item)
print('-'*50) # design: ------
prio_l = []
# Ask user to enter a priority for every item
# Goes through and displays every item in the data (search space)
for item in items:
prio_input = str(input(f"What is your priority for {item}? "))
while prio_input.lower() not in itemsPriorities.keys(): # convert entered data by the user to lower case
# Asks the user again to enter a correct choice (low, medium, high), regardless of the capitalization
prio_input = str(input('Please enter low, medium or high: '))
else:
prio_l.append(itemsPriorities[prio_input.lower()])
return prio_l
priority_list = user_input()
# Print the item name and its entered priority
print('-'*50) # design: ------
for i, j in enumerate(items):
print(j, 'has a priority of: ', priority_list[i])
# Assume the population size is 20
pop_size = 20
# generate initial population
def create_initial_population(amount):
#global pop_size
return [generate_genome() for i in range(0, amount)]
# generate genome
def generate_genome():
return [random.randint(0, 1) for x in range(0, len(items))]
print('-'*50) # design: ------
#print("Population:\n", create_initial_population(POP_SIZE))
# Compute fitness function
def compute_fitness(target):
total_points = 0
total_weight = 0
index = 0
# Sum of priority points and weight
for i in target:
if index >= len(items):
break
if (i == 1):
total_points += priority_list[index]
total_weight += list(items.values())[index]
index += 1
# Cheking to fit
if total_weight > 30:
return 0
else:
return total_points
def get_total_points(pop):
total_points = 0
for target in pop:
total_points += compute_fitness(target)
return total_points
# mutating a point on a solution
def mutate(target):
r = random.randint(0, len(target)-1)
if target[r] == 1:
target[r] = 0
else:
target[r] = 1
# selecting parents by using roulette wheel selection
def roulette_wheel_selection(pop, parent_number):
parents = []
total_points = get_total_points(pop)
current_value = 0
# spining the wheel and select parent based on rate of value and total_points
for spin in range(0, parent_number):
spin_value = random.randint(0, total_points)
for target in pop:
current_value += compute_fitness(target)
if current_value >= spin_value:
# print "SPIN!!! ,%s, TOTAL VALUE / SPIN VALUE : %s/%s, fit: %s" % (str(target),str(total_points), str(spin_value) , fitness(target))
parents.append(target)
pop.remove(target)
total_points = get_total_points(pop)
break
# print("-------------------------------------------------------------------------")
return parents
# n-point crossover by using two solution to generate their child
def crossover(father, mother):
# deciding the lines to split the solution
genes_points = [0]
genes_points += sorted(random.sample(range(2, ITEMS_COUNT), N_POINT))
genes_points += [ITEMS_COUNT]
child = []
# creating a new child by using father and mother data
for count in range(0, N_POINT+1):
start = genes_points[count]
end = genes_points[count+1]
# chosing which part of father or mother
if count % 2 == 0:
child += father[start:end]
else:
child += mother[start:end]
return child
# generating a new generation by mutation and crossover
def creating_new_generation(pop):
# selection with roulette_wheel_selection
new_generation = []
parents = []
if ELITISM:
parents = pop[int(0): int(POP_SIZE/5)]
else:
parents = roulette_wheel_selection(pop, (POP_SIZE/5))
parents_length = len(parents)
new_generation.extend(parents[:])
# mutating selected parents
for p in parents:
if MUTATION_PROBABITLY > random.random():
mutate(p)
children = []
desired_length = POP_SIZE - parents_length
# creating new children by using parents
while len(children) < desired_length:
# crossover cheking
if CROSSOVER_PROBABILTY > random.random():
# selecting two parents randomly
father_and_mother = random.sample(range(0, parents_length-1), 2)
father = parents[father_and_mother[0]]
mother = parents[father_and_mother[1]]
# crossover selected two parents to create a new child
child = crossover(father[:], mother[:])
else:
# or cloning a parent randomly
child = parents[random.randint(0, parents_length-1)][:]
# checking to mutate the new child
if MUTATION_PROBABITLY > random.random():
mutate(child)
children.append(child[:])
new_generation.extend(children[:])
return new_generation
def genome_to_string(genome) -> str:
return "".join(map(str, genome))
def genome_to_items(genome, ITEMS):
result = []
for i, itm in enumerate(ITEMS):
if genome[i] == 1:
result += [itm]
return result
def main():
#start_time = time.time()
population = create_initial_population(POP_SIZE)
max_fit = 0
for generation in range(1, GENERATIONS+1):
plt.plot(generation, max_fit)
plt.ylabel('Fitness')
plt.xlabel('Generations')
plt.show()
#print("Generation %d with %d" % (generation, len(population)))
population = sorted(
population, key=lambda x: compute_fitness(x), reverse=True)
for i in population:
# print "%s, fit: %s" % (str(i), fitness(i))
if compute_fitness(i) > max_fit:
max_fit = compute_fitness(i)
population = creating_new_generation(population)
# for item in items:
# print(item)
#elapsed_time = time.time() - start_time
#print( "Best: %s (%f)" % (genome_to_string(population[0]), compute_fitness(population[0])))
print(
f"The Best items for the customer backpacking:{(genome_to_items(population[0],items.items()))}")
print("Maximum fitness: " + str(max_fit))
#print ("Time : " + str(elapsed_time) + " seconds")
main()
If I change your main loop to this, it seems to work fine:
def main():
population = create_initial_population(POP_SIZE)
fit = []
for generation in range(GENERATIONS):
#print("Generation %d with %d" % (generation+1, len(population)))
population = sorted(
population, key=lambda x: compute_fitness(x), reverse=True)
# First item in population has best fitness.
fit.append( compute_fitness(population[0] ) )
population = creating_new_generation(population)
print(
f"The Best items for the customer backpacking:{(genome_to_items(population[0],items.items()))}")
print("Maximum fitness: " + str(max(fit)))
plt.plot(fit)
plt.ylabel('Fitness')
plt.xlabel('Generations')
plt.show()
I am trying to make a timer that counts down to 0, then starts counting up. I am using the time and keyboard modules.
The keyboard module from PyPi.
Everything works as expected, and I am able to press a button to close the program, but it only works at the beginning of each iteration. Is there a way for it to check for a key press at any point while the loop is running? Do I need to be using a different module?
This is my code:
import time
import keyboard
m = 2
s = 0
count_down = True
while True:
if keyboard.is_pressed('q'):
break
print(f"{m} minutes, {s} seconds")
if count_down:
if s == 0:
m -= 1
s = 60
s -= 1
elif not count_down:
s += 1
if s == 60:
m += 1
s = 0
if m == 0 and s == 0:
count_down = False
time.sleep(1)
Using callback is common approach in such case, here is solution:
import time
import keyboard
m = 2
s = 0
count_down = True
break_loop_flag = False
def handle_q_button():
print('q pressed')
global break_loop_flag
break_loop_flag = True
keyboard.add_hotkey('q', handle_q_button)
while True:
if break_loop_flag:
break
print(f"{m} minutes, {s} seconds")
if count_down:
if s == 0:
m -= 1q
s = 60
s -= 1
elif not count_down:
s += 1
if s == 60:
m += 1
s = 0
if m == 0 and s == 0:
count_down = False
time.sleep(1)
If you want to do any two things in parallel, independently of another, you need to consider using multiprocessing. However, even if you do, your loop will either still need to check if a key has been registered in the other process, or you need to terminate the process running the loop forcefully, which may result in unexpected outcomes.
However, in your case, since there are no side effects like files being written, this would work:
import time
import keyboard
from multiprocessing import Process
def print_loop():
m = 2
s = 0
count_down = True
while True:
print(f"{m} minutes, {s} seconds")
if count_down:
if s == 0:
m -= 1
s = 60
s -= 1
elif not count_down:
s += 1
if s == 60:
m += 1
s = 0
if m == 0 and s == 0:
count_down = False
time.sleep(1)
def main():
p = Process(target=print_loop)
p.start()
# this loop runs truly in parallel with the print loop, constantly checking
while True:
if keyboard.is_pressed('q'):
break
# force the print loop to stop immediately, without finishing the current iteration
p.kill()
if __name__ == '__main__':
main()
I'm trying to simulate different tasks running in parallel in Python, and each parallel process is run at different frequencies (e.g. 200 Hz, 100 Hz and 50 Hz). I used code from this question to make a Timer class to run these processes in "Real-Time", but the processes de-synchronize over time (e.i., three 200 Hz tasks can sometimes run in between two 100 Hz tasks).
To synchronize my processes I make tick counters in their shared memory. Every iteration of the 200 Hz process increments a counter, then waits for it to be reset to 0 when the counter reaches 2, while every iteration of 100 Hz process waits for that counter to reach 2 before resetting it. Same thing for the 50 Hz process, but with another counter. I use a while/pass method for the waiting.
Here is the code :
from multiprocessing import Process, Event, Value
import time
# Add Timer class for multiprocessing
class Timer(Process):
def __init__(self, interval, iteration, function, args=[], kwargs={}):
super(Timer, self).__init__()
self.interval = interval
self.iteration = iteration
self.iterationLeft = self.iteration
self.function = function
self.args = args
self.kwargs = kwargs
self.finished = Event()
def cancel(self):
"""Stop the timer if it hasn't finished yet"""
self.finished.set()
def run(self):
startTimeProcess = time.perf_counter()
while self.iterationLeft > 0:
startTimePeriod = time.perf_counter()
self.function(*self.args, **self.kwargs)
# print(self.interval-(time.clock() - startTimePeriod))
self.finished.wait(self.interval-(time.perf_counter() - startTimePeriod))
self.iterationLeft -= 1
print(f'Process finished in {round(time.perf_counter()-startTimeProcess, 5)} seconds')
def func0(id, freq, tick_p1):
# Wait for 2 runs of Process 1 (tick_p1)
while tick_p1.value < 2:
pass
tick_p1.value = 0 # Reset tick_p1
# Add fake computational time depending on the frequency of the process
print(f'id: {id} at {freq} Hz')
if freq == 400:
time.sleep(0.002)
elif freq == 200:
time.sleep(0.003)
elif freq == 100:
time.sleep(0.007)
elif freq == 50:
time.sleep(0.015)
def func1(id, freq, tick_p1, tick_p2):
# Wait for tick_p1 to have been reset by Process0
while tick_p1.value >= 2:
pass
# Wait for 2 runs of Process 2 (tick_p2)
while tick_p2.value < 2:
pass
tick_p2.value = 0 # Reset tick_p2
# Add fake computational time depending on the frequency of the process
print(f'id: {id} at {freq} Hz')
if freq == 400:
time.sleep(0.002)
elif freq == 200:
time.sleep(0.003)
elif freq == 100:
time.sleep(0.007)
elif freq == 50:
time.sleep(0.015)
# Increment tick_p1
tick_p1.value += 1
def func2(id, freq, tick_p2):
# Wait for tick_p2 to have been reset by Process1
while tick_p2.value >= 2:
pass
# Add fake computational time depending on the frequency of the process
print(f'id: {id} at {freq} Hz')
if freq == 400:
time.sleep(0.002)
elif freq == 200:
time.sleep(0.003)
elif freq == 100:
time.sleep(0.007)
elif freq == 50:
time.sleep(0.015)
# Increment tick_p2
tick_p2.value += 1
if __name__ == '__main__':
freqs = [50,100,200]
# freqs = [0.25,0.5,1]
Tf = 10
tick_p1 = Value('i', 1)
tick_p2 = Value('i', 1)
processes = []
p0 = Timer(interval=1/freqs[0], iteration=round(Tf*freqs[0]), function = func0, args=(0,freqs[0], tick_p1))
p1 = Timer(interval=1/freqs[1], iteration=round(Tf*freqs[1]), function = func1, args=(1,freqs[1], tick_p1, tick_p2))
p2 = Timer(interval=1/freqs[2], iteration=round(Tf*freqs[2]), function = func2, args=(2,freqs[2], tick_p2))
processes.append(p0)
processes.append(p1)
processes.append(p2)
start = time.perf_counter()
for process in processes:
process.start()
for process in processes:
process.join()
finish = time.perf_counter()
print(f'Finished in {round(finish-start, 5)} seconds')
As you can see, I've added sleep time within the processes, to simulate computational time. When I remove the print commands in the processes, the script requires 10.2 seconds of runtime to simulate 10 seconds of "real-time" calculations (2% increase, which is acceptable).
My question is, is this the best way to achieve what I'm trying to do? Is there a better/faster way?
Thanks!
I figured out a cleaner way to do this, but I'm still open to other suggestions.
Basically, instead of waiting for the moment to execute the next iteration, I've created a scheduler that flags when to run a cycle on each process (using shared Values).
There is a fast processes (lets say p2 running at 400 Hz) and all other processes must be a slower multiple of the frequency (lets say p1 and p0 200 and 100 Hz).
Instead of waiting for the right moment to raise execution flag (with wait() or sleep()), the scheduler loops with a while loop and checks if a period of p2 has ended. If the condition is met, it raised p2Flag and restart the period. Each process has its own flag, and the slower processes' flags get raised according to a counter which is incremented every period of p2. If 2 timesteps of p2 have run since the last time p1 was called, this scheduler will "wait" for p1 to be completed before raising p2's and p1's flag.
It's a bit complicated, but this ensures slower machines will obtain the same results as machines who can run this in "real-time".
from multiprocessing import Process, Value
import time
def func0(id, freq, endFlag, p0Flag, runIdx, Ts):
while (endFlag.value == 0):
if (p0Flag.value == 1):
t = round(runIdx.value*Ts, 4)
# Add fake computational time depending on the frequency of the process
# print(f'id: {id} at {freq} Hz at {t}s')
if freq == 400:
time.sleep(0.002)
elif freq == 200:
time.sleep(0.003)
elif freq == 100:
time.sleep(0.007)
elif freq == 50:
time.sleep(0.015)
# Lower flag to confirm completion of cycle
p0Flag.value = 0
def func1(id, freq, endFlag, p1Flag, runIdx, Ts):
while (endFlag.value == 0):
if (p1Flag.value == 1):
t = round(runIdx.value*Ts, 4)
# Add fake computational time depending on the frequency of the process
# print(f'id: {id} at {freq} Hz at {t}s')
if freq == 400:
time.sleep(0.002)
elif freq == 200:
time.sleep(0.003)
elif freq == 100:
time.sleep(0.007)
elif freq == 50:
time.sleep(0.015)
# Lower flag to confirm completion of cycle
p1Flag.value = 0
def func2(id, freq, endFlag, p2Flag, runIdx, Ts):
while (endFlag.value == 0):
if (p2Flag.value == 1):
t = round(runIdx.value*Ts, 4)
# Add fake computational time depending on the frequency of the process
# print(f'id: {id} at {freq} Hz at {t}s')
if freq == 500:
time.sleep(0.0015)
elif freq == 400:
time.sleep(0.002)
elif freq == 200:
time.sleep(0.003)
elif freq == 100:
time.sleep(0.007)
elif freq == 50:
time.sleep(0.015)
# Update time for next iteration
runIdx.value += 1
# Lower flag to confirm completion of cycle
p2Flag.value = 0
if __name__ == '__main__':
# Set frequencies of processes
# Last value of freqs is the fastest one, for process p2
freqs = [50,100,200] # Hz
freqs = [100,200,400] # Hz
# freqs = [0.25,0.5,1] # Hz
Tf = 10
Ts = round(1/freqs[-1], 4)
# Create shared values for time index (runIdx)
# Various flags to trigger the execution of the code in each process (p0Flag, ...)
# A flag to en all processes
runIdx = Value('I',0)
p0Flag = Value('b', 0)
p1Flag = Value('b', 0)
p2Flag = Value('b', 0)
endFlag = Value('b', 0)
# How many times the fastest process has to run before flagging the slower processes
p0_counter_exe = freqs[-1]/freqs[0]
p1_counter_exe = freqs[-1]/freqs[1]
if (not(freqs[-1] % freqs[0] == 0) or not(freqs[-1] % freqs[1] == 0)):
raise Exception("Update rates for processes must be a multiple of the dynamic's update rate.")
if (freqs[-1] < freqs[0]) or (freqs[-1] < freqs[1]):
raise Exception("Dynamics update rate must be the fastest.")
# p2 is at fastest frequency, p1 and p0 at lower frequencies
p0 = Process(target=func0, args=(0, freqs[0], endFlag, p0Flag, runIdx, Ts))
p1 = Process(target=func1, args=(1, freqs[1], endFlag, p1Flag, runIdx, Ts))
p2 = Process(target=func2, args=(2, freqs[2], endFlag, p2Flag, runIdx, Ts))
processes = []
processes.append(p0)
processes.append(p1)
processes.append(p2)
for process in processes:
process.start()
time.sleep(0.5)
# Start subprocesse's counters to execute directly at the first timestep
p0_counter = p0_counter_exe
p1_counter = p1_counter_exe
# Scheduler
#------------
startTime = time.perf_counter()
periodEnd = time.perf_counter()
while (runIdx.value*Ts < Tf):
periodTime = time.perf_counter()-periodEnd
do_p2 = False
# Wait for new timestep AND completion of p2
if (periodTime >= Ts and p2Flag.value == 0):
# If p0 or p1 are expected to finish before the new timestep, wait for their completion
# Depending on the situation, if slower processes have finished their cycle, make do_p2 True
if (p1_counter == p1_counter_exe) and (p0_counter == p0_counter_exe):
if (p1Flag.value == 0) and (p0Flag.value == 0):
do_p2 = True
elif (p1_counter == p1_counter_exe):
if (p1Flag.value == 0):
do_p2 = True
elif (p0_counter == p0_counter_exe):
if (p0Flag.value == 0):
do_p2 = True
else:
do_p2 = 1
# If do_p2 is True, raise p2Flag for the p2 process
if (do_p2):
periodEnd = time.perf_counter()
p2Flag.value = 1
# If it's time to start a cycle for the slower processes, raise their flag and reset their counter
if (p1_counter == p1_counter_exe):
p1Flag.value = 1
p1_counter = 0
if (p0_counter == p0_counter_exe):
p0Flag.value = 1
p0_counter = 0
# Increment slower processes counter
p1_counter += 1
p0_counter += 1
# Close all processes
endFlag.value = 1
for process in processes:
process.join()
print(f'Finished in {round(time.perf_counter()-startTime, 5)} seconds')
print(Ts*runIdx.value)
I have the following code which turns an outlet on/off every 3 seconds.
start_time = time.time()
counter = 0
agent = snmpy4.Agent("192.168.9.50")
while True:
if (counter % 2 == 0):
agent.set("1.3.6.1.4.1.13742.6.4.1.2.1.2.1.1",1)
else:
agent.set("1.3.6.1.4.1.13742.6.4.1.2.1.2.1.1", 0)
time.sleep(3- ((time.time()-start_time) % 3))
counter = counter + 1
Is there a way I can have the loop terminate at any given point if something is entered, (space) for example... while letting the code above run in the mean time
You can put the loop in a thread and use the main thread to wait on the keyboard. If its okay for "something to be entered" can be a line with line feed (e.g., type a command and enter), then this will do
import time
import threading
import sys
def agent_setter(event):
start_time = time.time()
counter = 0
#agent = snmpy4.Agent("192.168.9.50")
while True:
if (counter % 2 == 0):
print('agent.set("1.3.6.1.4.1.13742.6.4.1.2.1.2.1.1",1)')
else:
print('agent.set("1.3.6.1.4.1.13742.6.4.1.2.1.2.1.1", 0)')
if event.wait(3- ((time.time()-start_time) % 3)):
print('got keyboard')
event.clear()
counter = counter + 1
agent_event = threading.Event()
agent_thread = threading.Thread(target=agent_setter, args=(agent_event,))
agent_thread.start()
for line in sys.stdin:
agent_event.set()
I'm writing a photobooth program in Python on my Raspberry Pi 2 and it worked if I just want to take one picture or use auto focus once. I'm trying to write a function "scheduler" that waits 4 seconds then runs auto-focus, then waits 4 seconds to take picture 1, waits another 4 seconds for picture 2 and waits 4 seconds for picture 3 while updating a status bar in PyGTK. But when the "scheduler" function is called it goes through and starts all the while loops at the same time.
I tried putting the while loops in separate functions and running them as threads and using threadx.start(), threadx.join() commands under each thread call. I suspect the way gobject.timeout_add() function is preventing blocking, which I need to keep the GUI updated and the live preview running, but I also can't figure out how to get blocking when I need it. I also started scheduler as a thread and used time.sleep(1) in each of the while loops and it acts behaves how I want it to except the GUI disappears after the first image gets processed and I can't find any error message to explain it.
I've been working on this for weeks and would happily pay someone to help me get this finished via email. I live in a rural area and have had a very hard time finding someone locally to help. I can paypal... please contact me at derosia at the popular google email service. If you have a camera supported by gphoto2 and a usb tether that would be a bonus.
class Photobooth(gtk.Window):
def set_statusBar(self, status):
self.statusBar.label.set_text(str(status))
def focus_counter2(self, counter):
if counter > 3:
self.set_statusBar("Get into position!")
elif counter > 0:
self.set_statusBar("Focusing: " + str(counter-1))
else:
self.set_statusBar("Focusing: " + str(counter-1))
self.focus_function() #runs the function for auto focus
def countdown_function(self, counter, image_name):
if counter > 1:
self.set_statusBar(str(counter-1))
elif counter > 0:
self.set_statusBar("Keep Smiling!")
else:
self.photo_cb(image_name) #runs the function to take an image
def scheduler(self, widget, data = None):
global ftp_path
global image_names
global countdown_timer
image_names = []
counter = countdown_timer
while counter > 0:
gobject.timeout_add(counter * 1000, self.focus_counter2, countdown_timer-counter)
counter -= 1
counter = countdown_timer
while counter >= 0:
image_name = datetime.datetime.now().strftime("%Y_%m-%d_%H-%M-%S")
gobject.timeout_add(counter * 1000, self.countdown_function, countdown_timer-counter, image_name)
counter -= 1
image_names.append(image_name + ".jpg")
counter = countdown_timer
while counter >= 0:
image_name = datetime.datetime.now().strftime("%Y_%m-%d_%H-%M-%S")
gobject.timeout_add(counter * 1000, self.countdown_function, countdown_timer-counter, image_name)
counter -= 1
image_names.append(image_name + ".jpg")
counter = countdown_timer
while counter >= 0:
image_name = datetime.datetime.now().strftime("%Y_%m-%d_%H-%M-%S")
gobject.timeout_add(counter * 1000, self.countdown_function, countdown_timer-counter, image_name)
counter -= 1
image_names.append(image_name + ".jpg")
def __init__(self):
super(PictureBox, self).__init__()
startB_image = gtk.image_new_from_stock(gtk.STOCK_YES, gtk.ICON_SIZE_SMALL_TOOLBAR)
startB = gtk.Button()
startB.set_image(startB_image)
startB.set_tooltip_text("Start countdown")
startB.connect('clicked', self.scheduler, None)
Thanks to andlabs I solved this the way he suggested:
Call a function and have each function call the next one when they finished what they were doing. Then to make sure it looped through the proper number of times I just passed along a counter to each function that got iterated at the end of each loop, image_number. It seems to work.
class Photobooth(gtk.Window):
def set_statusBar(self, status):
self.statusBar.label.set_text(str(status))
def focus_counter1(self, widget, data=None):
global countdown_timer
counter = countdown_timer
while counter > 0:
gobject.timeout_add(counter * 1000, self.focus_counter2,
countdown_timer-counter)
counter -= 1
def focus_counter2(self, counter):
if counter > 3:
self.set_statusBar("Get into position!")
elif counter > 0:
self.set_statusBar("Focusing: " + str(counter))
else:
self.set_statusBar("Focusing: " + str(counter))
self.focus_function()
gobject.timeout_add(1000, self.countdown_clicked, 1)
def countdown_clicked(self, image_number):
global countdown_timer
counter = countdown_timer
while counter >= 0:
gobject.timeout_add(counter * 1000, self.countdown_function,
countdown_timer-counter, image_number)
counter -= 1
def countdown_function(self, counter, image_number):
global images_per_sequence
if counter > 1:
self.set_statusBar(str(counter-1))
elif counter > 0:
self.set_statusBar("Keep Smiling!")
else:
image_name = datetime.datetime.now()
self.photo_cb(image_name.strftime("%Y_%m-%d_%H-%M-%S"))
if image_number < images_per_sequence:
gobject.timeout_add(1000, self.countdown_clicked,
image_number + 1)
def __init__(self):
super(PictureBox, self).__init__()
startB_image = gtk.image_new_from_stock(gtk.STOCK_YES,
gtk.ICON_SIZE_SMALL_TOOLBAR)
startB = gtk.Button()
startB.set_image(startB_image)
startB.set_tooltip_text("Start countdown")
startB.connect('clicked', self.focus_counter1, None)