the entire counter list of methods in side counter class do not work. I want setcap to set of cap, and check cap to see if each counter have reached their limit as hr min sec are what a clock should know i would like to initialize them inside the clock.
import time
class counter():
count = 0
cap = 0
def _init_(self):pass
def reset(self):
self.count = 0
def increment(self):
self.count += 1
def setcap(self,x):
print x
self.cap = x
def checkcap(self):
if self.cap > self.count:
return False
else:
return True
class clock():
_hr = counter()
_min = counter()
_sec = counter()
def _init_(self):
self._hr.setcap(23)
self._min.setcap(59)
self._sec.setcap(59)
def manualreset(self):
self._hr.reset()
self._min.reset()
self_sec.reset()
def tick(self):
if self._sec.checkcap():
self._sec.reset()
self._min.increment()
if self._min.checkcap():
self._min.reset()
self._hr.increment()
if self._hr.checkcap():
self._hr.reset()
else:
self._sec.increment()
newClock = clock()
raw_input("Press enter to start clock")
while newClock._hr != 24:
newClock.tick()
print str(newClock._hr.count).zfill(2) + str(newClock._min.count).zfill(2) + str(newClock._sec.count).zfill(2)
One of the problems in your code is that your init functions are init.
Try using
def __init__(self):
pass
This should solve one of your problems
Related
I want to append a score to my "last_Score" list at the end of the game but it adds 60 items per second. I only want to have one item per game_over. Any ideas?
def __init__(self, **kwargs):
super(Game, self).__init__(**kwargs)
self.start_sound.play()
self.init_vertical_line()
self.init_horizontal_line()
self.init_quad()
self.init_hero()
self.start_quads()
self.quad_generation()
if self.is_desktop():
self.keyboard = Window.request_keyboard(self.keyboard_hidden, self)
self.keyboard.bind(on_key_down=self.on_keyboard_down)
self.keyboard.bind(on_key_up=self.on_keyboard_up)
Clock.schedule_interval(self.update, 1/60)
def update(self, dt):
time_factor = dt*60
self.update_vertical_lines()
self.update_horizontal_line()
self.quad_update()
self.quad_generation()
self.update_hero()
self.score_board()
def score_board(self):
if self.game_over:
self.end_score = self.score
self.last_Score.append((self.end_score))
if len(self.last_Score) > 10:
del self.last_Score[:-2]
print(self.last_Score)
I did it! My code down here.
def score_board(self):
if self.game_over:
self.end_score = self.score
self.last_Score.append((self.end_score))
if len(self.last_Score) > self.game_number:
del self.last_Score[-1]
try:
self.last_Score_Label = "Your last score is" + str(self.last_Score[-2])
except:
self.last_Score_Label = "Your last score is " + str(self.last_Score[-1])
print(self.last_Score)
A heavy-handed way to ensure score_board is only executed once:
Set self.update_score = True in __init__.
Redefine score_board as
def score_board(self):
if self.game_over:
self.update_score = False
self.end_score = self.score
self.last_Score.append((self.end_score))
if len(self.last_Score) > 10:
del self.last_Score[:-2]
print(self.last_Score)
Reset self.update_score = True when appropriate (when the game restarts?).
I'm trying to make a workout app, so I have to count each push-up or display a countdown for side plank. To do that I tried to use GObject.timeout_add but it appears it doesn't work like I thought it would.
In the current situation, all exercises of a session are run simultaneously, instead of one at a time, in the proper order.
I am certainly missing something, and through my web searching, I still haven't found it.
Here is my code :
#!/usr/bin/python
"""
Work out app to keep track of your progression through the session
"""
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GObject
from Programms import *
from time import sleep
def time_hours(t):
return t // 3600
def time_minutes(t):
return (t % 3600) // 60
def time_seconds(t):
return int((t % 3600) % 60)
def time_format(t):
hours = double_digit(time_hours(t))
minutes = double_digit(time_minutes(t))
seconds = double_digit(time_seconds(t))
return "{}:{}:{}".format(hours, minutes, seconds)
def double_digit(t):
if t == 0:
return "00"
elif t < 10:
return "0{}".format(t)
return t
class StartingLine:
"""
Gtk
"""
def __init__(self):
# main window
self.window = Gtk.Window()
self.window.set_title("Work out !")
self.window.set_size_request(200, 200)
self.window.connect('destroy', lambda x: Gtk.main_quit())
# start button
self.button = Gtk.Button("Start")
self.button.connect('clicked', self.start_work_out)
self.window.add(self.button)
self.window.show_all()
def start_work_out(self, widget):
self.window.hide()
work = Two
duration = work.duration
for exo in work.exercises:
Instructor(exo, duration)
class Instructor:
"""
Gtk
"""
def __init__(self, exo, duration):
# main window
self.window = Gtk.Window()
self.window.set_title("Work out !")
self.window.set_size_request(200, 200)
self.window.connect("destroy", lambda x: Gtk.main_quit())
# timer
self.current_time = 0
self.counter = 0
self.timer_label = Gtk.Label(time_format(self.counter))
# exercise
self.current_exercise = Gtk.Label(exo.name)
# overall progression
self.bar = Gtk.ProgressBar.new()
# hierarchy
grid = Gtk.Grid()
grid.attach(self.timer_label, 1, 0, 1, 1)
grid.attach(self.current_exercise, 1, 1, 1, 1)
grid.attach(self.bar, 1, 2, 1, 1)
self.window.add(grid)
# display
self.window.show_all()
if exo.type == ExoType.Reps:
print('exercise : ', exo.name)
self.counter = 0
self.timer_label.set_label(str(self.counter))
rep_id = GObject.timeout_add(1000*exo.in_between, self.display_rep, exo, duration)
print("rep ID : ", rep_id)
elif exo.type == ExoType.Timer:
self.counter = exo.number
self.timer_label.set_label(time_format(self.counter))
time_id = GObject.timeout_add(1000*exo.in_between, self.display_timer, exo, duration)
print("time ID : ", time_id)
def display_rep(self, exo, duration):
print("current time : ", self.current_time)
print("current exercise : ", exo.name)
print("rep : ", self.counter)
self.counter += 1
self.current_time += exo.in_between
self.timer_label.set_label(str(self.counter)) # update counter
self.current_exercise.set_label(exo.name) # update exercise name
self.bar.set_fraction(self.current_time/duration) # update progression bar
return self.counter < exo.number
def display_timer(self, exo, duration):
print("current time : ", self.current_time)
print("current exercise : ", exo.name)
print("timer : ", self.counter)
self.counter -= 1
self.current_time += exo.in_between
self.timer_label.set_label(time_format(self.counter)) # update counter
self.current_exercise.set_label(exo.name) # update name
self.bar.set_fraction(self.current_time/duration) # update progression bar
return self.counter > 0
if __name__ == "__main__":
StartingLine()
Gtk.main()
In this code I have used two types, which are :
#!/usr/bin/python
"""
define class exercise and class session
"""
class Exercise:
def __init__(self, name, typo, unilateral, number, preparation=0, in_between=1):
"""
:param name: name of the exercise
:param typo: either timer or reps
:param number: either a time in seconds or a a number of reps
:param preparation: time allocated to prepare the exercise, to put yourself in position
:param in_between: time between reps. 1s by default.
"""
self.name = name
self.type = typo
self.unilateral = unilateral
self.number = number
self.prep = preparation
self.in_between = in_between
class ExoType(enumerate):
Reps = 0
Timer = 1
class Session:
def __init__(self, name, exercises):
self.name = name
self.exercises = exercises
self.duration = time_length(exercises)
def time_length(exercises):
t = 0
for exo in exercises:
if exo.type == ExoType.Timer:
t += exo.number
elif exo.type == ExoType.Reps:
t += exo.number*exo.in_between
else:
print("Error : Session duration")
return t
First time I ask a question here, please tell me if I'm doing wrong.
rep_id = GObject.timeout_add(1000*exo.in_between, self.display_rep, exo, duration)
When you timeout_add you tell Mainloop to call function every n seconds.
for exo in work.exercises:
Instructor(exo, duration)
Here you add every exercise to mainloop, which leads to simultaneous run, because you create mainloop once.
There are several solutions and in my opinion none of them includes main_iteration_do.
Reorganise things so that 1 exercise runs it's own mainloop.
Emit a signal when one exercise is finished and in it's handler start another exercise.
How to reset counter (global variable) when one of the conditions changes. Basically, increase the counter by 1 until "type_name" is "Bar" if it changes to something else set the counter to 0. How can this be achieved for multiple type_names'. Thank you.
type_name = "bar"
counter = 0
class Foo(object):
"""
if type is different in the argument, reset counter to 0.
Otherwise, increment the counter by 1.
"""
def __init__(self, type_name):
self.type_name = type_name
self.counter = counter
self.reset()
def increament_counter(self):
self.counter +=1
def reset(self):
if self.type_name != type_name:
self.counter = 0
b = Foo("bar")
b.increament_counter()
b.increament_counter()
print b.counter
print "==============================="
c = Foo("taste")
c.reset()
print c.counter
c.increament_counter()
print c.counter
print "--------------------------"
d = Foo("bar")
d.increament_counter()
d.increament_counter()
print d.counter
print "--------------------------"
e = Foo("car")
e.increament_counter()
e.increament_counter()
print e.counter
What you are doing here is that you're not modifying the global variable, but you're modifying the counter in the class (self.counter)
What you need to do is, in your reset function, change the global count, and not the one in that's a property of the class object.
def reset(self):
global counter
if self.type_name != type_name:
counter = 0
Thank you. Due to space limitation I am adding updated code here with one more use case.
type_name = "bar"
counter = 1
class Foo(object):
"""
if type is different in the argument, reset counter to 0.
Otherwise increament counter by 1.
"""
def __init__(self, type_name):
self.type_name = type_name
self.counter = counter
self.reset()
def reset(self):
global counter
if self.type_name != type_name:
counter = 1
else:
counter += 1
c = Foo("taste")
print c.counter
print "--------------------------"
d = Foo("bar")
print d.counter
print "--------------------------"
e = Foo("taste")
print e.counter
print "--------------------------"
new_instances = []
for i in range(0, 10):
new_instances.append(Foo("bar"))
print new_instances
print new_instances[0].counter
print new_instances[8].counter
I'm new to OOP and am practicing putting together a little bit more complex programs using various classes and implementing principles like Inheritance. I've created a Ping-Pong simulation that has a Player class which contains the probability that the player will win their serve. Then I have a PingPong class which is a subclass of the super class RacquetSports. Each instance is a single game, with the ability to change server, and record who won, and whether or not it was a shut-out. Finally, I have a SimStats class whose purpose is to record the stats across "n" number of games.
My problem is that it seems like my play_game function is not correctly firing, when I place a print statement in there it never triggers. My current result when running the whole program is that Player1 has 10 wins no shutouts, and Player2 has zero of both.
Finally, any suggestions on better OO practice would also be appreciated. Here is my player class:
from random import random
class Player(object):
def __init__(self, prob_win):
self.prob = prob_win
self.points = 0
def wins_serve(self):
return self.prob >= random()
def add_point(self):
self.points += 1
def get_score(self):
return self.points
My RacquetSports class:
from abc import ABCMeta, abstractmethod
from player import Player
class RacquetSport(object):
__metaclass__ = ABCMeta
def __init__(self, prob1, prob2):
self.player1 = Player(prob1)
self.player2 = Player(prob2)
self.server = self.player1
def play_game(self):
while not self.game_over():
self.sim_point()
#abstractmethod
def type(self):
pass
def chg_server(self):
if self.server == self.player1:
self.server = self.player2
else:
self.server = self.player1
def sim_point(self):
if self.server.wins_serve():
self.server.add_point()
else:
self.chg_server()
#abstractmethod
def game_over(self):
pass
def get_scores(self):
return self.player1.get_score(), \
self.player2.get_score()
def return_stats(self):
p1_score, p2_score = self.get_scores()
print(p1_score, p2_score)
won = 'p1'
if p2_score > p1_score:
won = 'p2'
return won, self.__shutout(p1_score, p2_score)
#staticmethod
#abstractmethod
def __shutout(score1, score2):
pass
My PingPong and SimStats classes, as well as my calling code:
from racquet import RacquetSport
class PingPong(RacquetSport):
def type(self):
return 'Ping Pong'
def game_over(self):
return self.player1.get_score == 11 or \
self.player2.get_score == 11
#staticmethod
def __shutout(score1, score2):
return abs(score1 - score2) == 11
class SimStats(object):
def __init__(self):
# First field is games won, second is shutouts.
self.gms_won_p1 = [0] * 2
self.gms_won_p2 = [0] * 2
def update(self, game):
won, shutout = game.return_stats()
if won == 'p1':
self.gms_won_p1[0] += 1
if shutout:
self.gms_won_p1[1] += 1
else:
self.gms_won_p2[0] += 1
if shutout:
self.gms_won_p2[1] += 1
def print_results(self):
tot_games = self.gms_won_p1 + self.gms_won_p2
print('Wins for Player 1 = {} Shutouts = {}\n'
'Wins for Player 2 = {} Shutouts = {}'.format(*tot_games))
if __name__ == '__main__':
stats = SimStats()
for x in range(1, 11):
game = PingPong(.5, .5)
stats.update(game)
stats.print_results()
Your first problem is that you never call play_game. My guess is that you intend it to work like this:
if __name__ == '__main__':
stats = SimStats()
for x in range(1, 11):
game = PingPong(.5, .5)
game.play_game()
stats.update(game)
stats.print_results()
Next, you have a bug that will cause the entire game to last forever. Take a look at these lines:
def game_over(self):
return self.player1.get_score == 11 or \
self.player2.get_score == 11
get_score is a function, so you need to call it:
def game_over(self):
return self.player1.get_score() == 11 or \
self.player2.get_score() == 11
My basic idea was to create a linked list, and as each new value comes in, add 1/N times the new value and subtract 1/N times the first value, then move the pointer to first along by one and free the memory that had been associated with first.
This won't ultimately be implemented in Python but just to get the process clear in my head, I tried to write it in Python, but my implementation is flawed. Do I need a doubly linked list for this? Is there an alternative approach (not linked-list based) that would be better?
Here's my attempt so far:
class Link:
def __init__(self,val):
self.next = None
self.value = val
class LinkedList:
def __init__(self,maxlength):
self.current_link = None
self.maxlength = maxlength
self.sum = 0.
self.average = None
self.length = 0
self._first_link = None
def add_link(self,val):
new_link = Link(val)
new_link.next = self.current_link
self.current_link = new_link
if self._first_link is None:
self._first_link = self.current_link
self.sum += val
if self.length < self.maxlength:
self.length += 1
else:
self.sum -= self._first_link.value
self._first_link = self._first_link.next # this line is flawed
self.average = self.sum/self.length
def get_first(self):
return self._first_link.value
# Main
ll = LinkedList(5)
for ii in xrange(10):
ll.add_link(ii)
print ii,ll.get_first(),ll.average
The problem is that _first_link gets set to a value that doesn’t have a next. That is, _first_link gets set to the first item that's added, but its next is None, so I don't see how to move it along by 1 as I want to. This is what makes me wonder if a doubly linked list is needed.
I'd appreciate any advice.
I think the simplest implementation is to use a circular linked list (a.k.a. a ring):
class Link(object):
def __init__(self, value=0.0):
self.next = None
self.value = value
class LinkedRing(object):
def __init__(self, length):
self.sum = 0.0
self.length = length
self.current = Link()
# Initialize all the nodes:
last = self.current
for i in xrange(length-1): # one link is already created
last.next = Link()
last = last.next
last.next = self.current # close the ring
def add_val(self, val):
self.sum -= current.value
self.sum += val
self.current.value = val
self.current = self.current.next
def average(self):
return self.sum / self.length
# Test example:
rolling_sum = LinkedRing(5)
while True:
x = float(raw_input())
rolling_sum.add_val(x)
print(">> Average: %f" % rolling_sum.average())
You can implement this using collections.deque and the numerically stable math for maintaining running averages:
import collections
class AveragingBuffer(object):
def __init__(self, maxlen):
assert( maxlen>1)
self.q=collections.deque(maxlen=maxlen)
self.xbar=0.0
def append(self, x):
if len(self.q)==self.q.maxlen:
# remove first item, update running average
d=self.q.popleft()
self.xbar=self.xbar+(self.xbar-d)/float(len(self.q))
# append new item, update running average
self.q.append(x)
self.xbar=self.xbar+(x-self.xbar)/float(len(self.q))
if __name__=="__main__":
import scipy
ab=AveragingBuffer(10)
for i in xrange(32):
ab.append(scipy.rand())
print ab.xbar, scipy.average(ab.q), len(ab.q)
Okay, I thought of a solution that works in O[1] time. I'm still curious if anyone has a linked-list-based solution, but this solution avoids the LL entirely:
class Recent:
def __init__(self,maxlength):
self.maxlength = maxlength
self.length = 0
self.values = [0 for ii in xrange(maxlength)]
self.index = 0
self.total = 0.
self.average = 0.
def add_val(self,val):
last = self.values[self.index%self.maxlength]
self.values[self.index%self.maxlength] = val
self.total += val
self.total -= last
if self.length < self.maxlength:
self.length += 1
self.average = self.total / self.length
self.index += 1
def print_vals(self):
print ""
for ii in xrange(self.length):
print ii,self.values[ii%self.maxlength]
print "average:",self.average
# Example to show it works
rr = Recent(5)
for ii in xrange(3):
rr.add_val(ii)
rr.print_vals()
for ii in xrange(13):
rr.add_val(ii)
rr.print_vals()