My python virus generation code has an issue - python-3.x

I am trying to write a code that will count how many viruses there are after some time. Specifically, the original virus will begin to multiply after 120 sec, then every 60 sec, and it's 'offspring' follow the same pattern. With this, I am trying to find how many viruses there are after 879 seconds. The code below should execute every one second, and count how many times it executes until it reaches 879 seconds, but I keep getting an error. Can anyone help? Thanks
import time
maxtime = 10
Arr = []
def virus():
virus_count = 0
count_time = 0
time.sleep(1)
while True:
virus_count += 1
count_time +=1
if count_time > maxtime:
Arr.append(count)
print('There are', Arr, 'viruses')
while True:
virus()
virus()

You don't have to actually "wait" to simulate this (though I guess you could if you wanted to.
I'm going to keep track of the "age" of each virus in terms of generations. I'll reframe the task as to split viruses only if they are older than 1 generation.
generation_time = 60
max_ticks = 879
geration_count = max_ticks // generation_time
# start with a single baby virus
virus_ages = [0]
for _ in range(geration_count):
## Age each virus by a generation
virus_ages = [v+1 for v in virus_ages]
## viruses older than one spawn a new virus
virus_ages.extend([0 for v in virus_ages if v != 1])
print(len(virus_ages))
This gives me 610 which I hope if the answer you are looking for.

Related

Python 3+ How can i display a countdown timer in terminal with exactly milliseconds

Hello I'm trying to make a countdown timer with exactly milliseconds and print it to terminal.
input : a float value like (9.200)
output : countdown time for 9 seconds 200 milliseconds
like below site tool
https://www.online-stopwatch.com/countdown-timer/
even i could try to print time in milliseconds format but the time is not exactly. Maybe it's a not good question but Is there any way to do it?. Thank you guys so much.
I tried to search about this case but can't match any
Below code is what i got from internet but time is not correct and i need a countdown timer a above site had. Thanks
from __future__ import print_function, division
import time , datetime
counter, timestr = 0, ''
print(time.asctime())
t0 = time.time()
try:
while True:
sectime, ff = divmod(counter,1000)
mintime, ss = divmod(sectime,60)
hh, mm = divmod(mintime, 60)
print(''.join('\b' for c in timestr), end='')
timestr='%02i:%02i:%02i.%2s' % (hh, mm, ss, ff)
print(timestr, end='')
time.sleep(.1)
counter += 1
except KeyboardInterrupt:
t0 = time.time() - t0
print('\nCounter seconds: %.1f, time.time seconds: %.1f'
% (counter/10.0, t0 ))
You haven't mentioned what exactly didn't work for you, but I'll attempt to give a general answer anyway. You could try something like this -
# Saved as timer.py
import sys, time
## Create the variable _TIME from sys.argv or wherever, make sure it is a valid float, > 0, etc etc
## Depends on how you expect input
_TIME = 5 # Just for example, remove this
while _TIME > 0:
m, s = divmod(_TIME, 60)
h, m = divmod(m, 60)
print(f"\r{int(h)}".rjust(3,'0'), f"{int(m)}".rjust(2,'0'),
f"{s:.3f}".rjust(5,'0'), sep=':', end='')
_TIME -= 0.001
time.sleep(0.001)
else:
print("\r Completed ! ")
Then use $ python3 timer.py 5 or something like that in your terminal.
Notes :
This may not be accurate, especially if your print statement is slow in the the terminal. See What is the best way to repeatedly execute a function every x seconds? for several better alternatives since accuracy may be important here.
In some terminals/GUIs, \r may not actually move the cursor back to the start of the line as expected. You might not be able to really do anything about this, that's a problem with the terminal app.
Edit:
Right after I posted this, I saw that you'd updated your question. The code vou've shared definitely has problems - its a lot for me to completely explain here. The most obvious is time.sleep(0.1) waits 100ms, not 1, so your timer won't ever update that often. Try reading other sources on how to accomplish what you want.

Game of life is running slow

I am trying to simulate n-dimensional game of life for first t=6 time steps. My Nim code is a straightforward port from Python and it works correctly but instead of the expected speedup, for n=4, t=6 it takes 2 seconds to run, which is order of magnitude slower than my CPython version. Why is my code so slow? What can I do to speed it up? I am compiling with -d:release and --opt:speed
I represent each point in space with a single 64bit integer.
That is, I map (x_0, x_1, ..., x_{n-1}) to sum x_i * 32^i. I can do that since I know that after 6 time steps each coordinate -15<=x_i<=15 so I have no overflow.
The rules are:
alive - has 2 or 3 alive neigbours: stays alive
- different number of them: becomes alive
dead - has 3 alive neighbours: becomes alive
- else: stays dead
Below is my code. The critical part is the proc nxt which gets set of active cells and outputs set of active cells next time step. This proc is called 6 times. The only thing I'm interested in is the number of alive cells.
I run the code on the following input:
.##...#.
.#.###..
..##.#.#
##...#.#
#..#...#
#..###..
.##.####
..#####.
Code:
import sets, tables, intsets, times, os, math
const DIM = 4
const ROUNDS = 6
const REG_SIZE = 5
const MAX_VAL = 2^(REG_SIZE-1)
var grid = initIntSet()
# Inits neighbours
var neigbours: seq[int]
proc initNeigbours(base,depth: int) =
if depth == 0:
if base != 0:
neigbours.add(base)
else:
initNeigbours(base*2*MAX_VAL-1, depth-1)
initNeigbours(base*2*MAX_VAL+0, depth-1)
initNeigbours(base*2*MAX_VAL+1, depth-1)
initNeigbours(0,DIM)
echo neigbours
# Calculates next iteration:
proc nxt(grid: IntSet): IntSet =
var counting: CountTable[int]
for x in grid:
for dx in neigbours:
counting.inc(x+dx)
for x, count in counting.pairs:
if count == 3 or (count == 2 and x in grid):
result.incl(x)
# Loads input
var row = 0
while true:
var line = stdin.readLine
if line == "":
break
for col in 0..<line.len:
if line[col] == '#':
grid.incl((row-MAX_VAL)*2*MAX_VAL + col-MAX_VAL)
inc row
# Run computation
let time = cpuTime()
for i in 1..ROUNDS:
grid = nxt(grid)
echo "Time taken: ", cpuTime() - time
echo "Result: ", grid.len
discard stdin.readLine
Your code runs in my computer in about 0.02:
Time taken: 0.020875947
Result: 2276
Time taken: 0.01853268
Result: 2276
Time taken: 0.021355269
Result: 2276
I changed the part where the input is read to this:
# Loads input
var row = 0
let input = open("input.txt")
for line in input.lines:
for i, col in line:
if col == '#':
grid.incl((row-MAX_VAL)*2*MAX_VAL + i-MAX_VAL)
inc row
input.close()
But it shouldn't impact the performance, it just looks better to my eyes. I compiled with:
nim c -d:danger script.nim
Using Nim 1.4.2. -d:danger is the flag for maximum speed before entering deeper waters.
But even compiling in debug mode:
$ nim c -r script.nim
Time taken: 0.07699487199999999
Result: 2276
Way faster than 2 seconds. There has to be other problem in your end. Sorry for the non-answer.

Why isn't this function entering the while loop?

def millerRabin(toTest = 3, accuracy = 5):
# Return true if toTest is prime
################################
# Find how many times toTest can be halved
print(toTest)
under = toTest - 1
loopTracker = 0
while under % 2 == 0:
print('Before halving')
# Keep halving, and keep track until hit we can no longer divide in half
under = under // 2
print('After Halving: ', under)
loopTracker += 1
print("looped")
print(loopTracker)
print(millerRabin(toTest = 144000))
The first portion of the Miller-Rabin is to track how many times the number to be tested can be halved. But, I can't figure out why the program is not entering the while loop and outputting some of the print statements.
When you define under, you're subtracting 1. This creates 143999 to test, which is not divisible by 2 evenly. So it fails your while condition and never enters the loop.

while-loop to number 6174

I'am beginner in programming and have struggled for a while with one task.
Want to write a program wich finds out how many iterations is needed to arrive at the number 6174 from the specified number.
For example.: if I take number 2341 and sort it.
1) 4321-1234=3087
2) 8730-378=8352
3) 8532-2358=6174 (in this case it`s needed 3 iterations.)
And I have to use ,,while loop,, that it runs a code until it comes to number 6174 and stops.
I wrote a code:
n =input('write for nummbers ')
n=str(n)
i=0
i+=1 #"i" show how many times iteration happend.
large = "".join(sorted(n, reverse=True))
little = "".join(sorted(n,))
n = int(large) - int(little)
print(n, i)
Can you give mee some hint how I could run it with while loop.
# untested, all bugs are free ;)
n = input('write for nummbers ')
n = int(n) # you need n as a number
i=0
while n != 6174:
i += 1 #"i" show how many times iteration happened.
large = "".join(sorted(str(n), reverse=True))
little = "".join(sorted(str(n),))
n = int(large) - int(little)
print(n, i)

Beginner Python: Where to "while"?

tl;dr: My code "works", in that it gives me the answer I need. I just can't get it to stop running when it reaches that answer. I'm stuck with scrolling back through the output.
I'm a complete novice at programming/Python. In order to hone my skills, I decided to see if I could program my own "solver" for Implied Equity Risk Premium from Prof. Damodaran's Valuation class. Essentially, the code takes some inputs and "guesses and tests" a series of interest rates until it gets a "close" value to the input.
Right now my code spits out an output list, and I can scroll back through it to find the answer. It's correct. However, I cannot for the life of me get the code to "stop" at the correct value with the while function.
I have the following code:
per = int(input("Enter the # of periods forecast ->"))
divbb = float(input("Enter the initial dividend + buyback value ->"))
divgr = float(input("Enter the div + buyback growth rate ->"))
tbondr = float(input("Enter the T-Bond rate ->"))+0.000001
sp = int(input("Enter the S&P value->"))
total=0
pv=0
for i in range(1,10000):
erp = float(i/10000)
a = divbb
b = divgr
pv = 0
temppv = 0
print (sp-total, erp)
for i in range(0, per):
a=a * (1+b)
temppv = a / pow((1+erp),i)
pv=pv+temppv
lastterm=(a*1+tbondr)/((erp-tbondr)*pow(1+erp,per))
total=(pv+lastterm)
From his example, with the inputs:
per = 5
divbb = 69.46
divgr = 0.0527
tbondr = 0.0176
sp = 1430
By scrolling back through the output, I can see my code produces the correct minimum at epr=0.0755.
My question is: where do I stick the while to stop this code at that minimum? I've tried a lot of variations, but can't get it. What I'm looking for is, basically:
while (sp-total) > |1|, keep running the code.
per = 5
divbb = 69.46
divgr = 0.0527
tbondr = 0.0176
sp = 1430
total=0
pv=0
i = 1
while(abs(sp-total)) > 1:
erp = i/10000.
a = divbb
b = divgr
pv = 0
temppv = 0
print (sp-total, erp)
for j in range(0, per):
a=a * (1+b)
temppv = a / pow((1+erp),j)
pv=pv+temppv
lastterm=(a*1+tbondr)/((erp-tbondr)*pow(1+erp,per))
total=(pv+lastterm)
i += 1
should work. Obviously, there are a million ways to do this. But the general gist here is that the while loop will stop as soon as it meets the condition. You could also test every time in the for loop and include a break statement, but because you don't know when it will stop, I think a while loop is better in this case.
Let me give you a quick rundown of two different ways you could solve a problem like this:
Using a while loop:
iterator = start value
while condition(iterator):
do some stuff
increment iterator
Using a for loop:
for i in xrange(startvalue, maxvalue):
do some stuff
if condition:
break
Two more thing: if you're doing large ranges, use the generator xrange. Also, it's probably a bad idea to reuse i inside your for loop.
I recommend CS101 from Udacity.com for learning Python. Also, if you're interested in algorithms, work through the problems at projecteuler.com

Resources