condition parameter adjustment - python

I try to use 'IF' in python in order to achieve the algorithm that can automatically ajust the value of a parameter in 'IF' according to some stock trasactions.
if self.sellcount==0 and int(time.time())-self.programstarttime>600:
if cur_sum/total_sum>0.15:
Other Code
else:
if cur_sum/total_sum>0.35:
Other Code
I try to achieve that if my algorithm do not sell any stock for 10 minutes, the algorithm can automatically change the condition from 0.35 to 0.15. However, the code above will change from 0.15 to 0.35 after selling stocks for one time. I want the code to keep 0.15 after selling stocks for one time.

I'd like to start with a disclaimer to be careful, stock trading is not this easy and you can lose a lot of money with a simple algorithm (just as you can with a complex one)
However, this is also a nice example to understand how to deal with running a program over time in Python and understanding conditional logic.
There are a few basic constructs you'll want to know for this. The first concept is that to keep track of time constantly in your program, you likely want to put your code in an infinite loop. That will keep your programming doing what you want until you are done. This can be done like this:
while True:
Now that you have this setup, we just need to keep track of time. This can be done easily by setting a variable and incrementing it by how long you wait between iterations. However, we still need to track time. Python has a nice sleep function implemented in the time module. This function causes your program to pause for a number of seconds that you desire and then resume going through the rest of your code.
from time import sleep
last_sold_stock_time = 0
wait_time = 1
while True:
# <Condition Code goes here>
# This is in seconds
sleep(wait_time)
# Keep track of how much time has passed.
last_sold_stock_time += wait_time
Now, you just need to change your condition value based on the time. The full code will probably end up looking something like this:
from time import sleep
# The number of seconds since last bought a stock, assumes start is 0
last_sold_stock_time = 0
# This is in seconds
wait_time = 1
# ten minutes in seconds
ten_minutes = 600
while True:
# Figure out these values however you do
cur_sum = 0
total_sum = 1
if last_sold_stock_time <= ten_minutes:
condition_value = 0.35
else:
condition_value = 0.15
if cur_sum/total_sum > condition_value:
# Do something
pass
sleep(wait_time)
last_sold_stock_time += wait_time

Related

How to accurately sample in python

At work, I have a need: to do sampling every 0.08 seconds in 10 seconds.
I use while loop but it fails.
import time
start_t =time.time()
while time.time() -start_t <=10:
if float(time.time() -start_t) % float(0.08) == 0:
"""do sample record""
finally, I got no data at all, I think the if float(time.time() -start_t) % float(0.08) == 0: does not work.
I am confused how to set the condition to enter the sampling code.
The easiest way is to use time.sleep:
from time import sleep
for i in range(125):
"""do sample record"""
sleep(0.08)
You probably get no data because you collect the time only at discrete moments. In these moments, they will never be perfect multiples of 0.08.
Q : "How to accurately sample in python"
At work ( Chongqing ),I have a need: to do sampling every 0.08 seconds in 10 seconds.
Given the python is to be used, the such precise sampling will need a pair of signal.signal()-handlers on the unix-systems,
import signal
#------------------------------------------------------------------
# DEFINE HANDLER, responsible for a NON-BLOCKING data-acquisition
#------------------------------------------------------------------
def aSIG_HANDLER( aSigNUM, aPythonStackFRAME ):
... collect data ...
return
#------------------------------------------------------------------
# SET THE SIGNAL->HANDLER MAPPING
#------------------------------------------------------------------
signal.signal( signal.SIGALM, aSIG_HANDLER )
#------------------------------------------------------------------
# SET THE INTERVAL OF SIGNAL-ACTIVATIONS
#------------------------------------------------------------------
signal.setitimer( signal.ITIMER_REAL, seconds = 0, # NOW WAIT ZERO-SECONDS
interval = 0.08 # FIRE EACH 80 [ms]
)
#------------------------------------------------------------------
# ... more or less accurately wait for 10 seconds, doing NOP-s ...
#------------------------------------------------------------------
#----------------------------------------------------------------
# AFTER 10 [s] turn off the signal.ITIMER_REAL activated launcher
#----------------------------------------------------------------
signal.setitimer( signal.ITIMER_REAL, seconds = 0, # NOW WAIT ZERO-SECONDS
interval = 0.0 # STOP SENDING SIGALM-s
)
or,for a Windows-based systems,there is a chance to tweak ( and fine-tune up to a self-correcting, i.e. non-drifting ) Tkinter-based sampler as shown in this answer.
class App():
def __init__( self ):
self.root = tk.Tk()
self.label = tk.Label( text = "init" )
self.label.pack()
self.sampler_get_one() # inital call to set a scheduled sampler
self.root.lower() # hide the Tk-window from GUI-layout
self.root.mainloop()
def sampler_get_one( self ):
# \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
#
# DEMO to show real plasticity of the Tkinter scheduler timing(s)
#
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
... review a drift of the activation + adapt the actual delay for a next .after()
# SET .after() vv-----------# re-calculate this value to adapt/avoid drifting
self.root.after( 80, # re-instate a next scheduled call,
self.sampler_get_one
) # .after a given ( self-corrected ) delay in [ms]
#-------------------------------#-NOW--------------------------------------------
... acquire ... data ... # best in a non-blocking manner & leave ASAP
You use float number divide by float number, and time.time() will return a long decimal number so you get no data because your result always 0.00001234 or something like that. I think you should use round to get 2 decimal number
temp = time.time()-start_t
if round(temp,2) % 0.08 == 0:
"""do sample record"""
However, this script will return about 27000 result in 10 second. Because you will have 0.08, 0.081,0.082,etc and they all do your recording work.
So I think you should work with Maximilian Janisch solution (using sleep function) is better. I just want to explain why you reach no solution.
Hope this helpful!
EPILOGUE :
With all due respect, the proposed code is awfully dangerous & mis-leading.Just test how naive it gets : 8.00 % 0.08 yields 0.07999999999999984 that is by no means == 0,while the if-condition ought be served & sample taken, if it were not for the (known) trap in real-numbers IEEE-754 handling.So as to see the scope of the disaster, try :sum( [ round( i * 0.08, 2 ) % 0.08 == 0 for i in range( 126 ) ] )+ compare it with 125-samples the task was defined above to acquire.Get 8 samples instead of 125 # regular, 12.5 [Hz] samplingis nowhere near a solution! – user3666197 22 hours ago
#user3666197 wow, a very clear explanation, I think I should delete this answer to avoid misleading in the future. Thank you! – Toby 5 hours ago
Better do not remove the Answer, as it documents what shall never be done,which is of a specific value to the Community- best to mention the rationale, not to use this kind of approaches in any real-life system.The overall lesson is positive- all learned a next step towards better system designs. I wish you all the best, man! – user3666197 4 mins ago
this will probably never exactly be true as checking for equality with floats like this will need to be very precise.
try doing something like:
start_t =time.time()
looped_t = start_t
while time.time() - start_t <= 10:
if time.time() - looped_t >= 0.08:
looped_t = time.time()
"""do sample record""
The sleep answer from Maximillian is fine as well, except if your sampling takes a significant amount of time (several hundreds of a second) then you will not stay near the 10 second requirement.
It also depends on what you prioritize as this method will at most provide 124 samples instead of the exact 125 you would expect (and do get with the sleep function).

How to count "times per second" in a correct way?

Goal: I would like to see how many times python is able to print something per 1 second.
For educational purposes I'm trying to make a script that shows how many times per every second a random module will appear in a loop. How to do it in a fastest pythonic way?
At first, to count seconds I wrote this code:
import time
sec = 0
while True:
print(sec)
time.sleep(1)
sec += 1
But this one seems slower than a real seconds.
So I decided to use local seconds. Also, before continue my script I wanted to count how many times python will print 'you fool' manually, so I wrote following code:
import time
def LocalSeconds():
local_seconds = time.gmtime()[5:-3]
local_seconds = int(local_seconds[0])
return local_seconds
while True:
print(LocalSeconds(), 'you fool')
Output:
first second - 14 times per second;
next second - 13 times;
next second - 12 times, etc. Why it goes slower?
Where I end / stuck right now:
import time, random
def RandomNumbers():
return random.randint(3,100)
def LocalSeconds():
local_seconds = time.gmtime()[5:-3]
local_seconds = int(local_seconds[0])
return local_seconds
def LocalSecondsWithPing():
local_seconds_ping = time.gmtime()[5:-3]
local_seconds_ping = int(local_seconds[0:1])
return local_seconds_ping
record_seconds = []
record_seconds_with_ping = []
while True:
record_seconds.append(LocalSeconds())
record_seconds_with_ping.append(LocalSecondsWithPing())
if record_seconds == record_seconds_with_ping:
RandomNumbers()
del record_seconds_with_ping[0]
del record_seconds[-1]
Also, I guess I need to use "for" loop, not "while"? How to do this script?
Counting a single second won't give you a good result. The number of prints in a single second may vary depending on things like other threads currently running on your system (for the OS or other programs) and may be influenced by other unknown factor.
Consider the followind code:
import calendar
import time
NumOfSeconds=100 #Number of seconds we average over
msg='Display this message' #Message to be displayed
count=0 #Number of time message will end up being displayed
#Time since the epoch in seconds + time of seconds in which we count
EndTime=calendar.timegm(time.gmtime()) + NumOfSeconds
while calendar.timegm(time.gmtime())<EndTime: #While we are not at the end point yet
print(msg) #Print message
count=count+1 #Count message printed
print(float(count)/NumOfSeconds) #Average number of prints per second
Here calendar.timegm(time.gmtime()) gives us the time in seconds since the epoch (if you don't know what that is, read this. But basically it's just a fixed point in time most computer system now days use as a reference point.
So we set the EndTime to that point + the number of seconds we want to average over. Then, in a loop, we print the message we want to test and count the number of times we do that, between every iteration checking that we are not past the end time.
Finally we print the average number of times per seconds that we printed the message. This helps with the fact that we may end up start counting near the end of a whole second since the epoch, in which case we won't actually have a whole second to print messages, but just a fraction of that. If we make sure NumOfSeconds is large enough, that error addition will be small (for example, for NumOfSeconds=100 that error is ~1%).
We should note that the actual number would also depend on the fact that we are constantly testing the current time and counting the number of prints, however, while I haven't tested that here, it is usually the case that printing to the screen takes significantly longer time than those operations.

how to detect change in hour of system time

I am trying to make a program in Python that beeps every hour. and no of beeps should be equal to no of hours. such as for 12 o'clock it should beep 12 times.
but I have no idea how to detect change in hour.
def bep(h):
for i in range(h):
winsound.Beep(2000,800)
sleep(2)
the above code beeps for h no of times and
def hour():
return hour=int(time.ctime(time.time()).split()[3].split(':')[0])
it gives the hour.
but how to detect that hour has changed.
whether should I check every regular time interval and use previous hour and current hour to detect changes? I think this idea is not effective. because of time delay of interval time i.e.
check current time every 5 second and compare two successive check to detect change in hours.
is there any method to accomplish it directly.
At its simplest:
import datetime
import time
current = 0
while True:
time.sleep(5)
if datetime.datetime.now().hour != current:
current = datetime.datetime.now().hour
print "beep" , str(current)
Note you can test the code by using .minute rather than .hour Which will allow you to see if it fits your purposes.
You will have to replace the print "beep", str(current) with a call to your function bep(current)
Also you might want to consider adding a little extra code to your bep(h) function.
if h>12: h=h-12
if h == 0: h = 12
To ensure that for example: at 16:00 you only hear 4 beeps rather than 16 and at midnight, you hear 12 beeps, rather than none.

Having a certain piece of code run for a specified amount of time

I'm working on a galactica type of game using pygame and livewires. However, in this game, instead of enemy's, there are balloons that you fire at. Every 25 mouse clicks, I have the balloons move down a row using the dy property set to a value of 1. If a balloon reaches the bottom, the game is over. However, I'm having some trouble figuring out how to get this to run only for, say, 1 second, or 2 seconds. Because I don't have a way to "time" the results, the dy value just indefinitely gets set to 1. Therefore, after the first 25 clicks, the row just keeps moving down. This is ok, but like I said, it's not my intended result.
Here is the code I have so far for this action:
if games.mouse.is_pressed(0):
new_missile = missile(self.left + 6, self.top)
games.screen.add(new_missile)
MISSILE_WAIT = 0 #25
CLICKS += 1
if CLICKS == 25:
SPEED = 1
CLICKS = 0
CLICKS, and MISSILE_WAIT are global variables that are created and set to an initial value of 0 before this block of code. What I'm trying to figure out is the algorithim to put underneath the if CLICKS statement. I've looked through the python documentation on the time module, but just can't seem to find anything that would suit this purpose. Also, I don't think using a while loop would work here, because the computer checks those results instantly, while I need an actual timer.
I'm not sure if I got your question but what I can suggest is that:
class Foo():
def __init__(self):
self.start_time = time.time()
self.time_delay = 25 # seconds
def my_balloon_func(self):
if(time.time() - self.start_time) > self.time_delay:
self.start_time = time.time()
else:
# do something

What's the proper way to write a game loop in Python?

I'm trying to write a python game loop that hopefully takes into account FPS. What is the correct way to call the loop? Some of the possibilities I've considered are below. I'm trying not to use a library like pygame.
1.
while True:
mainLoop()
2.
def mainLoop():
# run some game code
time.sleep(Interval)
mainLoop()
3.
def mainLoop():
# run some game code
threading.timer(Interval, mainLoop).start()
4.
Use sched.scheduler?
If I understood correctly you want to base your game logic on a time delta.
Try getting a time delta between every frame and then have your objects move with respect to that time delta.
import time
while True:
# dt is the time delta in seconds (float).
currentTime = time.time()
dt = currentTime - lastFrameTime
lastFrameTime = currentTime
game_logic(dt)
def game_logic(dt):
# Where speed might be a vector. E.g speed.x = 1 means
# you will move by 1 unit per second on x's direction.
plane.position += speed * dt;
If you also want to limit your frames per second, an easy way would be sleeping the appropriate amount of time after every update.
FPS = 60
while True:
sleepTime = 1./FPS - (currentTime - lastFrameTime)
if sleepTime > 0:
time.sleep(sleepTime)
Be aware thought that this will only work if your hardware is more than fast enough for your game. For more information about game loops check this.
PS) Sorry for the Javaish variable names... Just took a break from some Java coding.

Categories

Resources