Function that substracts a certain number every second on Python - python

I have been wondering if there is a way to create a function that subtracts one number from another but only at a given amount of time. I have read the time library, but I am still trying to figure it out. For example:
def TimeFunction:
t = 60
#What should I need to put here so for every second that passes, it subtracts 1?

This is what you are literally asking for:
import time
def TimeFunction():
t = 60
while True:
time.sleep(1)
t -= 1
Although this is not very satisfying, because your program blocks on sleep() and nothing else would be able to see the value of t.
Do you want to modify your question now and ask for something slightly different?

Related

Best way in python to check if a loop is not executed

The title might be misleading, so here is a better explanation.
Consider the following code:
def minimum_working_environment(r):
trial=np.arange(0,6)[::-1]
for i in range(len(trial)):
if r>trial[i]:
return i
return len(trial)
We see that if r is smaller than the smallest element of trial, the if clause inside the loop is never executed. Therefore, the function never returns anything in the loop and returns something in the last line. If the if clause inside the loop is executed, return terminates the code, so the last line is never executed.
I want to implement something similar, but without return, i.e.,
def minimum_working_environment(self,r):
self.trial=np.arange(0,6)[::-1]
for i in range(len(self.trial)):
if r>trial[i]:
self.some_aspect=i
break
self.some_aspect=len(self.trial)
Here, break disrupts the loop but the function is not terminated.
The solutions I can think of are:
Replace break with return 0 and not check the return value of the function.
Use a flag variable.
Expand the self.trial array with a very small negative number, like -1e99.
First method looks good, I will probably implement it if I don't get any answer. The second one is very boring. The third one is not just boring but also might cause performance problems.
My questions are:
Is there a reserved word like return that would work in the way that I want, i.e., terminate the function?
If not, what is the best solution to this?
Thanks!
You can check that a for loop did not run into a break with else, which seems to be what you're after.
import numpy as np
def minimum_working_environment(r):
trial = np.arange(0, 6)[::-1]
for i in range(len(trial)):
if r > trial[i]:
return i
return len(trial)
def alternative(r):
trial = np.arange(0, 6)[::-1]
for i in range(len(trial)):
if r > trial[i]:
break
else:
i = len(trial)
return i
print(minimum_working_environment(3))
print(minimum_working_environment(-3))
print(alternative(3))
print(alternative(-3))
Result:
3
6
3
6
This works because the loop controlling variable i will still have the last value it had in the loop after the break and the else will only be executed if the break never executes.
However, if you just want to terminate a function, you should use return. The example I provided is mainly useful if you do indeed need to know if a loop completed fully (i.e. without breaking) or if it terminated early. It works for your example, which I assume was exactly that, just an example.

Time to excecute function goes up instead of down instead of up as x increases - Range()

My bad if this is a bit nooby or I don't understand how this works. I'm trying to get the time of range(1,x) using the code below.
Code
import timeit
def main(x):
return range(1,x)
def timeThem(x):
start = timeit.default_timer()
main(x)
stop = timeit.default_timer()
return stop - start
for i in range(5):
print(timeThem(i))
Now I would expect since x is getting larger in range(1,x) the time it would take to execute this would be longer. What i'd guess it would look something like this.
Expected Output
.01 .02 .03 .04 .05
But no, my time output gets shorter for some reason. As shown below I get something totally different than what I had imagined.
Received Output
8.219999999975469e-07
6.740000000060586e-07
1.0670000000004287e-06
4.939999999967193e-07
4.420000000032731e-07
What am I doing wrong here? Or do I just not understand how this really works?
From the range documentation:
Return an object that produces a sequence of integers from start (inclusive) to stop (exclusive) by step.
range do not produce the actual sequence so it can run in constant time. Note that iterating over the results is done in linear time.
Furthermore, your values are too small to see any significant difference in the timing even if range would run in linear time. Consequently, you are measuring noise.
your main function only returns a generator
def main(x):
return range(1,x)
Basically, a generator is not executed right away but an iterator with two values and no evaluation of it yet. So it does not matter whether you give x=1, x=100 or x=1000000. From a performance view Its basically returns a tuple like
def main(x):
return (1,x)
This is due to the nature of a generator that it's just get evaluated if you iterate over it. E.g. list(range(0, <infity>) ) would brake your memory but for i in range(0,<infity>): print(i) would just take forever to compute.
So range(x, 1000 ) did just create one object - it did not evaluate it
please be aware that python has some other coding standards than other languages like java or javascript where timeThem is a proper name, but in python, we follow pep8 that says one should use snake-case like time_them.
Personally, I would recommend you to use something like time_function to be even more explicit about what your function is supposed to do.

Countdown Timer that can be extended by user input?

I am trying to make a little game.
I need a timer, that starts counting down in the background when the game begins (it shows the lifespan of a bonfire).
There is no need to print the remaining duration (fire_time) every second, but the user should be able to input a command (like fire) to get the remaining seconds.
The user should also be able to input words that add different amounts of seconds to the timer (like "paper", "wood", etc.)
I've tried to create a timer in a thread that is counting down with the following code:
for seconds in range(fire_time, 0, -1):
fire_timer = Timer(0, fire_time_calc, [fire_time])
fire_timer.start()
#print(f"'Fire_time' aus for-loop = {fire_time}")
time.sleep(1)
fire_time -= 1
and I've got a function that is called, that prints the time (fire_time_calc).
Currently the function is only to show how the countdown is proceeding, but I don't know if I really need it.
Currently the timer is working fine because it counts down to zero.
The problem is, that no user input is allowed until it reaches zero.
The variable fire_time needs to be updated and accessible outside of the for-loop to add time to the countdown...
Anybody got an idea how to solve this?

trying to count how many times a script inside a function is used

I am trying to use a counter how many times an object moves. There is two functions, the first one is here, the second one is here.
Here's the question:
Create a new subroutine CalculateDistance, which works out the distance between the cell currently occupied by M and the cell currently occupied by *.
Basically, I have to display the amount of moves it takes for M to reach *. I thought the most logical way of doing this would be to call MakeMonsterMove inside the new subroutine CalculateDistance as the exam paper says that is what we have to do. Then, using this algorithm:
MonsterMoves = 0
while loop
call MakeMonsterMove
MonsterMoves = MonsterMoves+1
print(MonsterMoves+1)
My logic is that each time the monster moves using the signalled subroutine, the counter will add one each time. However, whilst playing the game, the counter is always 1.Even when the M moves, it neither increases or decreases.
I'm using Python 3.
Any help would be appreciated :)

How to make a recursive program run for a long time without getting RunTimeError in Python

This code is the recursive factorial function.
The problem is that if I want to calculate a very large number, it generates this error:
RuntimeError : maximum recursion depth exceeded
import time
def factorial (n) :
if n == 0:
return 1
else:
return n * (factorial (n -1 ) )
print " The factorial of the number is: " , factorial (1500)
time.sleep (3600)
The goal is to do with the recursive function is a factor which can calculate maximum one hour.
This is a really bad idea. Python is not at all well-suited for recursing that many times. I'd strongly recommend you switch this to a loop which checks a timer and stops when it reaches the limit.
But, if you're seriously interested in increasing the recursion limit in cython (the default depth is 1000), there's a sys setting for that, sys.setrecursionlimit. Note as it says in the documentation that "the highest possible limit is platform-dependent" - meaning there's no way to know when your program will fail. Nor is there any way you, I or cython could ever tell whether your program will recurse for something as irrelevant to the actual execution of your code as "an hour." (Just for fun, I tried this with a method that passes an int counting how many times its already recursed, and I got to 9755 before IDLE totally restarted itself.)
Here's an example of a way I think you should do this:
# be sure to import time
start_time = time.time()
counter = 1
# will execute for an hour
while time.time() < start_time + 3600:
factorial(counter) # presumably you'd want to do something with the return value here
counter += 1
You should also keep in mind that regardless of whether you use iteration or recursion, (unless you're using a separate thread) you're still going to be blocking the entire program for the entirety of the hour.
Don't do that. There is an upper limit on how deep your recursion can get. Instead, do something like this:
def factorial(n):
result = 1
for i in range(1, n+1):
result *= i
return result
Any recursive function can be rewritten to an iterative function. If your code is fancier than this, show us the actual code and we'll help you rewrite it.
Few things to note here:
You can increase recursion stack with:
import sys
sys.setrecursionlimit(someNumber) # may be 20000 or bigger.
Which will basically just increase your limit for recursion. Note that in order for it to run one hour, this number should be so unreasonably big, that it is mostly impossible. This is one of the problems with recursion and this is why people think about iterative programs.
So basically what you want is practically impossible and you would rather make it with a loop/while approach.
Moreover your sleep function does not do what you want. Sleep just forces you to wait additional time (frozing your program)
It is a guard against a stack overflow. You can change the recursion limit with sys.setrecursionlimit(newLimit)where newLimit is an integer.
Python isn't a functional language. Rewriting the algorithm iteratively, if possible, is generally a better idea.

Categories