Python task. Converting for to while - python

I just began programming and one of the tasks i got was making code that gives out prizes depending on the laps done. I began completing the exercise without realizing that i should be using a while loop in it, so here it is and i don't know how to make it work with a while loop.
to = int(input("Laps: "))
start = 1
prize = 0
for i in range(start, to+1):
if i % 2 == 0:
prize = prize + i
print("Prize: " + str(prize))

This should do it:
to = int(input("Laps: "))
i = 1
prize = 0
while i < (to+1):
if i % 2 == 0:
prize = prize + i
i = i + 1
print("Prize: " + str(prize))
It is essentially the same as your for loop. The main difference is that in a while loop you have to update the progress of your loop yourself, which is what the statement i = i + 1 is for.

Related

Is there a better approach to the proof code of "100 prisoners" question?

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.

while loop in line 36 won't exit despite fulfilling condition

The outer while loop should exit when current_digit and powers[digit_of_powers] both equal 26 but the while-loop doesn't exit as it should.
As a proof of what I'm claiming, see for yourself, the last line never executes. The program is stuck in the stopped while loop.
I'm new to programming so I may do daft mistakes
#enter a number in base 10 and find how it's written in choosen base... or at least thats what it should do
import math
def find_powers(num, base, start_num): #stackoverflow experts, this function is not important for my problem
power = 1 # power starts as a '1' each iteration
while start_num + power <= num:
power *= base
if start_num != num:
power /= base
powers.append(round(math.log(power, base)))
find_powers(num, base, start_num + power)
num = 7892 #enter choosen number in base 10 here
base = 10 #enter choosen base here. I put ten because its much easier to check the program with a base I'm familiar with
powers = []
find_powers(num, base, 0)
print(powers)
print('')
check = 0 #this script is not necessary, it's just a way for me to check if it can find the input of the def find_powers function from its output.
for i in powers: # It if it does then the function still work
check += base**i
print(check)
print('')
string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
digits = []
# Two things to check here
# 1. if powers[i] misses a digit or not.
# If it does, digits.append(0)
# 2. How many times the same power comes (it'll always be in row)
digit_of_powers = 0
while digit_of_powers != len(powers):
digit_of_powers += 1
print('digits_of_powers = ' + str(digit_of_powers))
current_digit = powers[digit_of_powers]
print('current_digit = ' + str(current_digit))
print('powers[digit_of_powers] = ' + str(powers[digit_of_powers]))
print('')
digit_thatll_go_in_digits = 1
while current_digit == powers[digit_of_powers]:
digit_thatll_go_in_digits += 1
digit_of_powers += 1
print('digit_thatll_go_in_digits = ' + str(digit_thatll_go_in_digits))
print('digits_of_powers = ' + str(digit_of_powers))
print(digits)
print('while ' + str(digit_of_powers) + ' != ' + str(len(powers)))
print('while ' + str(current_digit) + ' == ' + str(powers[digit_of_powers]))
print('')
digits.append(digit_thatll_go_in_digits)
print('fin du while')
print('')
print('this last line never executes for some reason')
You are increasing (conditionally) digit_of_powers twice, but condition is exact value while digit_of_powers != len(powers): (not equal)
It means that your code can jump over this condition and run further.
For example, if len(powers) == 10, digit_of_powers + 1 + 1 will increase from 9 to 11 and can be never the same.
Try this:
while digit_of_powers <= len(powers): (if it starts with 1)
or
while digit_of_powers < len(powers): (if it starts with 0)

Is the win_turns in my code even counting through the loop at this point? I dont believe my code is running either but I am not getting any errors

The intention of this code is to run in a loop until a specified amount of turns or until I roll snake eyes(both die are = 1). I am not entirely sure what specifically is not working in my code so far.
import random
def play_game(rolls, win_turns):
win_turns = 0
rolls = []
i = 2
for _ in range(2):
roll = random.randint(1, i)
rolls.append(roll)
win_turns= win_turns + 1
i = i + 2
if roll in rolls == 2:
return win_turns
You have a number of problems here. Your "loop" only picks the two dice -- you don't loop until a loss. The "roll in rolls == 2" doesn't mean anything. This basically does what you ask:
import random
def play_game(turns):
win_turns = 0
for _ in range(turns):
die = random.randint(1,6), random.randint(1,6)
print("Roll:", die )
if sum(die) == 2:
break
win_turns += 1
return win_turns
print("Wins:", play_game(10))

Why does this code work apart from the 1st 11th 13th 14th?

print('This is a binary search!')
list1 = [1,3,6,9,12,23,67,68,69,71,74,86,95,100]
find = int(input('Which item would you like to find?'))
found = 0
def half(value):
if value % 2 == 1:
value = (float(value) / 2) + 0.5
return int(value)
else:
return int(value / 2)
length = len(list1)
cal = half(length)
pal = 0
while found == 0:
fund = int(list1[int(cal)])
if int(fund) == find:
print(str(cal + 1) + ' is the reference!')
found = 1
if fund > find:
cal = half(cal)
if fund < find:
cal = half(cal) + cal
Why does this not work for only certain values in the list, I am trying to create a binary search program.
print('This is a binary search!')
list1 = [1,3,6,9,12,23,67,68,69,71,74,86,95,100]
find = int(input('Which item would you like to find?'))
#This shows that the program has not found the number.
found = 0
#This function finds half of the value.
def half(value):
return value // 2
#This fidns the length of the list.
length = len(list1)
#This is the starting middle value.
cal = half(length)
#This is the lower bound.
pal = 0
#This is the upper bound.
sal = len(list1)
#This makes a limit for if the item is not in the list.
gal = 2*(len(list1))
#This keeps track of how many times the while loop is triggered.
mal = 0
#This makes it keep trying.
while found == 0:
#This clocks the amount of times the while loop is triggered.
mal = mal + 1
#This retrieves the value from the list.
fund = int(list1[int(cal)])
#If fund is find then it has found the element.
if int(fund) == find:
#This print the place in the list.clear
print(str(cal + 1) + ' is the reference!')
#This ends the while loop.
found = 1
#This checks if it is lower than the guess.
if fund > find:
#It brings down the upper bound.
sal = cal
#This checks if it is higher than the guess.
if fund < find:
#This brings up the lower bound.
pal = cal
#This adjusts cal.
cal = half(sal + pal)
#This stops the program after a number of attempts.
if mal > gal:
#This tells the user that it is not in the list.
print('Your number is not in the list!')
#This ends the while loop.
found = 1
WOO

Monty hall simulation returning 50% odds?

from random import randint
numberOfDoors = 3
success = 0
attempts = 0
while True:
try:
doors = [0] * numberOfDoors
doors[randint(0, numberOfDoors - 1)] = 1
chosen = randint(0, numberOfDoors - 1)
while numberOfDoors > 2:
notIn = -1
while notIn == -1:
index = randint(0, numberOfDoors - 1)
if doors[index] == 0 and index != chosen:
notIn = index
if notIn < chosen:
chosen -= 1
del doors[notIn]
numberOfDoors -= 1
# doors is 2, so not chosen (0 or 1) will return the opposite (1 or 0)
success += doors[not chosen]
attempts += 1
if attempts % 1000000 == 0:
print float(success) / float(attempts)
except KeyboardInterrupt:
print float(success) / float(attempts)
break
My results are almost exactly 50% after a few hours of simulation - am I doing something specifically wrong?
Theoretically the door you choose is between 1/3 odds and 2/3 odds, so you should get higher than 50 at the very least.
This answer seems to do the same thing as me (ignoring that he doesn't do anything about monty's choice - I wanted to illustrate the concept).
You're forgetting to reset numberOfDoors (number of doors still closed, right?) back to 3. Since every iteration of the first while True: represents a new game show run, the show starts with all three doors initially closed.
...
while True:
numberOfDoors = 3
try:
doors = [0] * numberOfDoors
doors[randint(0, numberOfDoors - 1)] = 1
...
Next time, try adding print statements to help you debug. In this case, adding print doors right after you assign a car shows that doors has only two elements after the first iteration.
I wrote a Monty Hall simulation problem myself a while ago. Maybe it will help you with your code - in particular the comments may be useful:
from __future__ import division
import random
results = [] # a list containing the results of the simulations, either 'w' or 'l', win or lose
count = 0
while count <200: #number of simulations to perform
l = []
prize = random.randint(1, 3) #choose the prize door
initialchoice = random.randint(1, 3) #make an initial choice (the door the contestant chooses)
exposed = random.randint(1, 3) #choose the exposed door (the door the host chooses)
while exposed == initialchoice or exposed == prize: #make sure exposed is not same as prize or the initial choice
exposed = random.randint(1, 3)
if initialchoice != prize:
results.append('l') #if the initial choice was incorrect, append 'l'
else:
results.append('w') #if the initial choice was correct, append 'w'
count += 1
print 'prize door:', prize, 'initial choice:',initialchoice, 'exposed door:',exposed #print the results of the simulation
print
w = 0
for i in results:
if i == 'w':
w += 1
print w/len(results) #fraction of times sticking with the original door was successful

Categories

Resources