Skip to content

Instantly share code, notes, and snippets.

@natanael-araujo
Created June 27, 2012 20:38
Show Gist options
  • Save natanael-araujo/3006727 to your computer and use it in GitHub Desktop.
Save natanael-araujo/3006727 to your computer and use it in GitHub Desktop.
Exercício com Threads
#!/usr/bin/env python
# encoding: utf-8
# Natanael de Araújo Silva
# Sistemas de Informação - 8º período
# Programação Paralela e Distribuída
import sys, random, threading
from datetime import datetime
from time import sleep
from os import system
class Race(object):
def __init__(self, distance, number_of_swimmers=8):
self.distance = distance
self.swimmers = []
self.initialize_swimmers(number_of_swimmers)
def initialize_swimmers(self, quantity):
self.swimmers = [Swimmer(self, n + 1) for n in xrange(quantity)]
def start(self):
map(lambda s: s.start(), self.swimmers)
def finished(self):
return False not in map(lambda s: s.finished(), self.swimmers)
def rank(self):
rank = self.swimmers
rank.sort(key=lambda s: s.final_time)
return rank[0:3]
class Swimmer(threading.Thread):
def __init__(self, race, number):
super(Swimmer, self).__init__()
self.daemon = True
self.distance = 0
self.race = race
self.number = number
self.initial_time = None
self.final_time = None
def run(self):
self.initial_time = datetime.now()
while not self.finished(): self.swim()
self.final_time = datetime.now() - self.initial_time
def finished(self):
return self.distance >= self.race.distance
def swim(self):
sleep(random.uniform(0.2, 0.8))
self.distance += 1
class Monitor(object):
def __init__(self, race):
self.race = race
self.lane_divider = " " + "|" + "-" * 53 + "|"
self.lane = " " * 50
def start(self):
try:
self.race.start()
while not self.race.finished(): self.draw_pool()
self.draw_pool()
self.draw_rank()
except KeyboardInterrupt:
sys.exit("\nBye")
def draw_pool(self):
system("clear")
self.draw_edge()
for swimmer in self.race.swimmers:
self.draw_lane(swimmer)
self.draw_edge()
sleep(0.2)
def draw_lane(self, swimmer):
pool_distance = int(str(swimmer.distance)[-2:])
if pool_distance <= 50:
print "[%d]" % swimmer.number + "|" +\
self.lane[0:pool_distance] + '>–O' + \
self.lane[pool_distance:] + "|[%d]" % swimmer.number
else:
pool_distance -= 50
print "[%d]" % swimmer.number + "|" +\
self.lane[:-pool_distance] + 'O–<' +\
self.lane[-pool_distance:] + "|[%d]" % swimmer.number
if self.race.swimmers.index(swimmer) < len(self.race.swimmers) - 1:
print self.lane_divider
def draw_edge(self):
print " |" + "≠" * 53 + "|"
def draw_rank(self):
print "\n=============== RANK ==============="
for winner in self.race.rank():
print "%dº | Swimmer %d | Time: %s min" % \
(self.race.rank().index(winner) + 1,
winner.number,
str(winner.final_time)[2:])
def main():
try:
race_distance = int(sys.argv[1])
if not race_distance in [50, 100, 200, 400]: raise ValueError
except IndexError:
print "Passe como parâmetro a modalidade da prova (50/100/200/400)"
except ValueError:
print "Parâmetro inválido"
else:
print "START: %d m\n" % race_distance
race = Race(race_distance)
Monitor(race).start()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment