I have the this code:
import numpy
import random
import pylab
from ps3b import *
def AvgWithDrug(numViruses, maxPop, maxBirthProb, clearProb, resistances, mutProb, numTrials, delay):
viruses = []
timeSteps = delay + 300
print 'timeSteps = ', timeSteps
for i in range(numViruses):
viruses += [ResistantVirus(maxBirthProb, clearProb, resistances, mutProb)]
avg = [0] * timeSteps
print 'len avg[] =', len(avg)
hola = []
last = 0
for j in range(numTrials):
patient = TreatedPatient(viruses, maxPop)
for i in range(timeSteps):
if i == 150:
patient.addPrescription('guttagonol')
if i == 150 + delay:
patient.addPrescription('grimpex')
avg[i] += patient.update()
new = avg[timeSteps - 1]
print new - last
hola += [new - last]
last = new
for i in range(timeSteps):
avg[i] = avg[i]/ float(numTrials)
print avg[i]
print 'len avg[] =', len(avg)
Of course you cannot run it without knowing how to attach my class definitions.
But the issue when I run it is that last statement is like it is inside the above for loop. print avg[i] should be executed timeSteps times, and last print 'len avg[] =', len(avg) should be executed once.
It doesn't happen; the output shows me print avg[i], print 'len avg[] =', len(avg) over and over again through the timeSteps.
You've mixed tabs and spaces. Most of your code is indented with spaces, but a few lines have tabs, including the line that seems to be indented too far. Python treats a tab like Notepad does, as enough spaces to reach the next 8-space indentation level. Run your code with the -tt option to get Python to notify you of things like this, turn on "show whitespace" in your editor if it has that option, and change those tabs to spaces.
Related
Well, I'm quite a beginner and need some help and advice. Sometime ago i watched this video about 100 prisoners question and wanted to write a proof program to see if the ratio really approaches to ~30%. But i got ~12%. I couldnt really find out where I did mistakes. Here is my code:
import random
from statistics import mean
prisoners = []
box_dict = {}
saved_prisoners = []
counter = 0
average = []
for i in range(1, 101):
prisoners.append(i)
for i in range(1000):
def control_list_generation():
for i in range(100):
x = random.sample(prisoners, 1)
y = x[0]
box_dict[i] = y
control_list_generation()
def open_box():
global saved_prisoners
global counter
counter = 0
for prisoner in range(100):
counter = prisoner
for turn in range(50):
if box_dict.get(counter) == (prisoner + 1):
saved_prisoners.append(1)
break
else:
counter = box_dict.get(counter) - 1
continue
open_box()
average.append(len(saved_prisoners))
saved_prisoners.clear()
print(mean(average))
P.S. range on the 13th line can be changed
Your code has a lot of superfluous lines. Just by editing out anything unneeded, you can end up with:
import random
from statistics import mean
prisoners = list(range(1, 101))
box_dict = {}
saved_prisoners = []
counter = 0
average = []
for i in range(1000):
for i in range(100):
x = random.sample(prisoners, 1)
y = x[0]
box_dict[i] = y
counter = 0
for prisoner in range(100):
counter = prisoner
for turn in range(50):
if box_dict.get(counter) == (prisoner + 1):
saved_prisoners.append(1)
break
else:
counter = box_dict.get(counter) - 1
continue
average.append(len(saved_prisoners))
saved_prisoners.clear()
print(mean(average))
However, you just use the dict more or less as a new list (the indices amount to the same as just shuffling the prisoners in a list). And when constructing it, you're accidentally duplicating prisoner tickets by sampling from the same prisoners over and over. (as user #MichaelButscher correctly points out in the comments)
If you fix those issues, your code still doesn't quite work because you have some further mistakes and moving around of numbers in your box checking.
Here's a solution that follows the pattern of your code, but shows the problem correctly:
import random
n_prisoners = 100
prisoners = list(range(n_prisoners))
boxes = []
failures = 0
attempts = 1000
for i in range(attempts):
boxes = list(prisoners)
random.shuffle(boxes)
for prisoner in prisoners:
box_nr = prisoner
for turn in range(n_prisoners // 2):
if boxes[box_nr] == prisoner:
break
box_nr = boxes[box_nr]
else:
failures += 1
break
print(f'{failures / attempts * 100}% of attempts failed')
Example output:
70.3% of attempts failed
As a general tip: don't get too hung up on numbering stuff from 1 instead of 0. That caused several coding mistakes in your code, because you kept having to correct for 'off by one' problems. Simply numbering the prisoners from 0 to 99 is far simpler, as it allows you to use the prisoner's number as an index. In case you need to print their number and need that to start at 1 - that would be the time to offset by one, not everywhere in your logic.
Write a function create_box that takes three inputs: height
(rows), width (columns), and a character char and creates a
height * width box using the character char.
This is my code:
def create_box(height, width, char):
for i in range (height):
for j in range(width):
z = char * j + "\n"
return z
The problem with this code is it returns only one line of output. I want to know how is it possible to return the complete box? Can we place the return statement in such a way that it returns after completing all the iterations of first for loop?
I also tried this:
def create_box(height, width, char):
z = ""
for i in range (height):
for j in range(width):
z += char * width + "\n"
return z
ma = create_box(3, 5, "!")
print(ma)
The output is:
!!!!!
!!!!!
!!!!!
!!!!!
!!!!!
You've almost done it correctly with your second approach: This is the working code.
def create_box(height, width, char):
z = ""
for i in range (height):
for j in range(width):
z += char # Width number of chars
z += '\n' # Next row
return z
ma = create_box(3, 5, "!")
print(ma)
All you did was mess up the indentation of your return statement, and add to the string wrongly. If you don't get the logic here, post a comment and I'll explain it fully.
Outputs:
>>> print(create_box(1, 1, '-'))
-
>>> print(create_box(3, 2, '* '))
* *
* *
* *
# Etc etc
In response to your comment:
The reason your first code didn't work was that the approach was wrong, take a look at this:
z = 0
for i in range(5):
z += i
print(z)
# You expected this to output 5, it doesn't
The second attempt was wrong on two counts:
Your return statement was wrongly indented, making it so that the function stopped executing after it completed the first iteration of the outer loop. See below:
def hello():
print("This gets printed")
return
print("This is never executed")
hello()
# Run it and see for yourself!
The z variable: You had z randomly going up, all the second for loop needed to do was add one char to z every iteration.
Anything else you need clarification on?
Let's say I have a counter that counts from 0 to 100000. I don't want all the numbers showed, I just want to see the number we are at end the % of completion.
I know that if I want to rewrite over the line, I must add \r at the beginning. However, if I want to do this on two lines, how am I supposed to do that ?
1
0.001%
then
2
0.002%
Also, let's say I want to add new lines for the numbers, but always keep the percentage at the bottom like this:
1
2
3
4
5
6
7
8
0.008%
Do you have any idea on how to achieve that?
Here is my code so far (doesn't work, obviously):
from sys import stdout
for i in range(100000):
stdout.write(str(i) + '\r\n')
stdout.write('%.2f' % (i / 100000 * 100) + '%\r')
stdout.flush()
stdout.write('\n')
Thank you !
you can use curses module:
import curses
import time
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
n = 100000
num_lines = 10
lst = list(range(n))
for t in [lst[i:i + num_lines] for i in range(0, len(lst), num_lines)]:
final_line = f'{t[-1] / n * 100:.4f}%'
out = '\n'.join(map(str, [*t, final_line]))
stdscr.addstr(0, 0, out)
stdscr.refresh()
time.sleep(0.005) # you can comment but will be too fast
curses.echo()
curses.nocbreak()
curses.endwin()
This question already has answers here:
Rewrite multiple lines in the console
(7 answers)
Closed 5 years ago.
I have a question regarding the python programming, let's say i have a loop, so within the loop, i want to stdout.write 3 variables in different lines.
For example:
while (True):
a += 0
b += 5
c += 10
sys.stdout.write("\routput1 = %d" % a)
sys.stdout.write("\routput2 = %d" % b)
sys.stdout.write("\routput3 = %d" % c)
So in the terminal should be like:
output1 = .........
output2 = .........
output3 = .........
Each output just remain in their lines and keep refreshing. Thank you!
For multiple line printing, each console window on Windows is a number of lines, with number of columns... usually 25 lines and 80 columns as an old standard.
You can move a cursor to an (y, x) position, and print a string on screen.
y = line
x = column
Example code:
import ctypes
from ctypes import c_long, c_wchar_p, c_ulong, c_void_p
handle = ctypes.windll.kernel32.GetStdHandle(c_long(-11))
def move_console_cursor(y, x):
value = (x + (y << 16))
ctypes.windll.kernel32.SetConsoleCursorPosition(handle, c_ulong(value))
def print_string_at_cursor(string):
ctypes.windll.kernel32.WriteConsoleW (handle, c_wchar_p(string), c_ulong(len(string)), c_void_p(), None)
You then can print multiple lines over eachother by moving the cursor to the appropriate position and then print a string with the functions given.
A 3 line example: Easy would be to do a os.system('CLS') to clear the screen, and then you can move cursor to 1,1 2,1 3,1 and repeat until you have done all your processing. At the end, don't forget to move your cursor to 4,1. You can of course pick any location of your console window.
For single line on Windows you can do a sys.stdout.write() and then write cursor movements '\b' to move the cursor back to the beginning of the line.
Example of a copy file function with % progress indicator on the same line, using this method:
import os
import sys
def copy_progress(source_file, dest):
source_size = os.stat(source_file).st_size
copied = 0
source = open(source_file, 'rb')
target = open(dest, 'wb')
print ('Copy Source: ' + source_file)
print ('Copy Target: ' + dest)
print ('Progress:')
while True:
chunk = source.read(512)
if not chunk:
break
target.write(chunk)
copied += len(chunk)
progress = round(copied * 100 / source_size)
my_progress = str(progress).ljust(5)
sys.stdout.write (my_progress + '%\b\b\b\b\b\b')
sys.stdout.flush()
sys.stdout.flush()
source.close()
target.close()
this is the question i am trying to solve
i have tried everything to get the spaces to appear between the hashtags but have failed. i don't know what else to do
this is what i have done so far, i found a few ways to get only 1 space between the hashtags, but to have them repeat every time is what i have not been able to do
star = 6
for r in range(star):
for c in range(r - 5):
print ' ',
print '##',
print
this is the output i get
any help is appreciated.
def hashes(n):
for i in range(n):
print '#' + ' '*i + '#'
Testing
>>> hashes(1)
##
>>> hashes(4)
##
# #
# #
# #
Obviously, there are more succinct ways of doing this, but the original question called for nested loops:
import sys
inner = 1
for x in range(6):
sys.stdout.write('#')
for y in range(inner):
if y == inner - 1:
sys.stdout.write('#')
else:
sys.stdout.write(' ')
sys.stdout.write('\n')
inner += 1
Output:
$ python loops.py
##
# #
# #
# #
# #
# #