This little function to rotate a coin isn't working - python

I'm doing a little program. This program works as follows:
1- U put how many coins do u want to have
2- U put all of them 'heads'
3- From the second coin, you start to flip the coins that the index a multiple of 2, when u finish you go back to the start and start again, but this time you'll start from the third coin and flip all that the index is multiple of 3, and continue like that, restart from the fourth coin and flip the multiples of 4 and continue until the end...
Example: 4 coins-->
heads, heads,heads,heads
1° time:
heads,talls,heads,talls,
2° time:
heads,talls,talls,talls,
3° time:
heads, talls,talls,heads.
I think this code is almost reaching it, but this function I built doesn't do the job of flipping the coin and change the 'mode' on the 'moedas' list
Vocab: Heads-cara / Talls - coroa /Coin(s)- moeda(s) /To flip - Virar (portuguese)
I'll apreciate any help to change some error on the rest of the code too.
def Virar(moeda):
if moeda == 'cara':
moeda = 'coroa'
if moeda == 'coroa':
moeda = 'cara'
return moeda
qtde_moedas = int(input('How much coins do u want?'))
moedas=[]
while (len(moedas))<qtde_moedas:
moedas.append('cara')
for divisor in range(2,len(moedas)):
for index_num in range(len(moedas)):
if (index_num+1)%divisor==0:
moedas[index_num] = Virar(moedas[index_num])
else:
pass

Say you pass 'cara' to your function Virar; first it changes moeda to 'coroa', because it was 'cara'. And then, it checks whether moeda is 'coroa', which is True now, so it turns it back to 'cara'! So Viara never flips the coin as you wish. Instead, try using elif or else:
def Virar(moeda):
if moeda == 'cara':
moeda = 'coroa'
else:
moeda = 'cara'
return moeda
A shorter version, if you are interested, would be the following:
def virar(moeda):
return 'coroa' if moeda == 'cara' else 'cara'
qtde_moedas = int(input("How many coins do you want? "))
moedas = ['cara'] * qtde_moedas
for divisor in range(2, qtde_moedas + 1):
for i in range(divisor - 1, qtde_moedas, divisor):
moedas[i] = virar(moedas[i])
print(moedas)

Related

How to return numbers all on the same line from a function?

I have a function that converts an integer to binary.
def conversion(num):
if num >= 1:
conversion(num // 2)
i = str(num % 2)
return i
num = int(input('Enter number'))
print(conversion(num))
This returns 1 which is only the first value in the actual answer
The code below gets me the answer I am looking for (101) but I want to be able to return that value instead of having the function perform the print
def conversion(num):
if num >= 1:
conversion(num // 2)
i = str(num % 2)
print(i,end=' ')
return
num = int(input('Enter number'))
conversion(num)
The only reason this prints the answer all on one line is because of the end=' '
How do I actually store the value as 101 all on one line and return it as i?
You can notice that you have called the function inside it. That concept's name is recursion. And every time the recursing is performed, you should save the result of that recursing step or do something with the result...
Your second funtion did that, it print out the results of every step you divide the number by two, so on the output you can see them in order.
In your first one, you forget to use the result so try to move conversion(num // 2) to the place it should be in.
And I'm sure you realize that PRINTING the answer is very different from RETURNING the answer. What you need to do is build up the components in a list, then join the list into a string:
def conversion(num):
answer = []
while num > 0:
answer.insert(0, str(num%2))
num = num // 2
return ''.join(answer)
num = int(input('Enter number'))
print(conversion(num))
Note that I use "insert" to add the digits in the proper order, since the higher bits have to go in the left side.

Having problem with adding iteration into recursion

I was trying to solve a dp problem (checking if given amount can be broken down with given coins with different values, assuming there are infinite number of coins available for each valued coins)
def istrue(coins, amount):
if (amount - coins[0] > 0):
holder = False
while (holder == False and len(coins) != 0):
holder = holder or istrue(coins, amount - coins[0])
if(len(coins) != 0):
coins.pop(0)
return holder
elif (amount - coins[0] < 0):
return False
else:
return True
And was not sure what would be an appropriate way of iterating through the given coins.
Currently, I am having trouble inside the while loop. (If the amount left to break down is bigger than current value of a coin, it moves onto the next coin) But the amount to be break down also goes back a step because I used pop..
Any hints for fixing this? example) coins: [7,3]. amount: 20. -> as it reaches 6 (20-7-7), the index for coins array moves on but also the amount gets backed up a step because I pop()ed it.
You can loop over your coins instead of doing a recursion:
def istrue(coins, amount):
coins.sort(reverse=True)
_, remainder = divmod(amount, coins[0])
coins.pop(0)
for coin in coins:
_, remainder = divmod(remainder, coin)
return not remainder

I'm trying to print the largest number from the inputs that the user gives, but it's printing the wrong number

Basically, I'm trying to build a code to get the largest number from the user's inputs. This is my 1st time using a for loop and I'm pretty new to python. This is my code:
session_live = True
numbers = []
a = 0
def largest_num(arr, n):
#Create a variable to hold the max number
max = arr[0]
#Using for loop for 1st time to check for largest number
for i in range(1, n):
if arr[i] > max:
max = arr[i]
#Returning max's value using return
return max
while session_live:
print("Tell us a number")
num = int(input())
numbers.insert(a, num)
a += 1
print("Continue? (Y/N)")
confirm = input()
if confirm == "Y":
pass
elif confirm == "N":
session_live = False
#Now I'm running the function
arr = numbers
n = len(arr)
ans = largest_num(arr, n)
print("Largest number is", ans)
else:
print(":/")
session_live = False
When I try running my code this is what happens:
Tell us a number
9
Continue? (Y/N)
Y
Tell us a number
8
Continue? (Y/N)
Y
Tell us a number
10
Continue? (Y/N)
N
Largest number is 9
Any fixes?
The error in your largest_num function is that it returns in the first iteration -- hence it will only return the larger of the first two numbers.
Using the builtin max() function makes life quite a bit easier; any time you reimplement a function that already exists, you're creating work for yourself and (as you've just discovered) it's another place for bugs to creep into your program.
Here's the same program using max() instead of largest_num(), and removing a few unnecessary variables:
numbers = []
while True:
print("Tell us a number")
numbers.append(int(input()))
print("Continue? (Y/N)")
confirm = input()
if confirm == "Y":
continue
if confirm == "N":
print(f"Largest number is {max(numbers)}")
else:
print(":/")
break
So, first things first,
the use of max can be avoided, as it is a reserved keyword in python
And coming to your fix, you are comparing it with the value only once in the loop, and you are returning the number, the indentation is the key here. You will have to wait for the loop to complete its job then return the value.
There are many inbuilt methods to do the job, Here is your implementation (a bit modified)
session_live = True
numbers = []
a = 0
def largest_num(arr, n):
#Create a variable to hold the max number
max_number = arr[0]
#Using for loop for 1st time to check for largest number
for i in range(1, n):
if arr[i] > max_number:
max_number = arr[i]
# --- The indentation matters
#Returning max's value using return
return max_number
while session_live:
print("Tell us a number")
num = int(input())
numbers.insert(a, num)
a += 1
print("Continue? (Y/N)")
confirm = input()
if confirm == "Y":
pass
elif confirm == "N":
session_live = False
#Now I'm running the function
arr = numbers
n = len(arr)
ans = largest_num(arr, n)
print("Largest number is", ans)
else:
print(":/")
session_live = False
I made it without using the built-in function 'max'.
It is a way to update the 'maxNum' variable with the largest number by comparing through the for statement.
numbers = []
while True:
print("Tell us a number")
numbers.append(int(input()))
print("Continue? (Y/N)")
confirm = input()
if confirm == "Y":
continue
if confirm == "N":
maxNum = numbers[0]
for i in numbers:
if i > maxNum:
maxNum = i
print("Largest number is", maxNum)
else:
print(":/")
break

How to find min/ max value and create a list (python)

Please ignore my un-used import!
I tried to create a list to find min and max of "pa_walk" but I just could figure how to do it, everytime I tried it said error.
import random
from math import sqrt
from math import hypot
import statistics
random.seed(20190101)
def takeOnePaStep():
direction = random.randint(0,3)
if direction == 0:
return (0,1)
elif direction == 1:
return (1,0)
elif direction == 2:
return (0,-1)
elif direction == 3:
return (-1,0)
def randomWalkPa(steps):
pa = [0,0]
for _ in range (steps):
nextStep = takeOnePaStep()
pa[0] += nextStep[0]
pa[1] += nextStep[1]
pasDistance = hypot(pa[0],pa[1])
return pasDistance
# paMean = statistic.mean(distance)
steps = int(input("Please enter the number of steps: "))
tries = int(input("How many times should I perform the experiment? "))
for _ in range(tries):
pa_walk= randomWalkPa(steps)
print(pa_walk)
I gues it is because your function randomWalkPa(steps) returns a float of the distance, that's why you first need to create a list (in the example below I just made pa_walk a list. In your for-loop just .append the distance for every try to that list. Finally you can call the built-in functions max()and min() to get the maximum and minimum distance. I unindented the print commands for the min and max call to just get the results once
pa_walk = []
for _ in range(tries):
pa_walk.append(randomWalkPa(steps))
print(f"The Maximum Distance reached was: {max(pa_walk)}, in trial: {pa_walk.index(max(pa_walk))}")
print(f"The Minimum Distance reached was: {min(pa_walk)}, in trial: {pa_walk.index(min(pa_walk))}")
After recommendation in the comments here is the full code (I changed nothing but the last 5 rows)
import random
from math import sqrt
from math import hypot
import statistics
random.seed(20190101)
def takeOnePaStep():
direction = random.randint(0,3)
if direction == 0:
return (0,1)
elif direction == 1:
return (1,0)
elif direction == 2:
return (0,-1)
elif direction == 3:
return (-1,0)
def randomWalkPa(steps):
pa = [0,0]
for _ in range (steps):
nextStep = takeOnePaStep()
pa[0] += nextStep[0]
pa[1] += nextStep[1]
pasDistance = hypot(pa[0],pa[1])
return pasDistance
# paMean = statistic.mean(distance)
steps = int(input("Please enter the number of steps: "))
tries = int(input("How many times should I perform the experiment? "))
pa_walk = []
for _ in range(tries):
pa_walk.append(randomWalkPa(steps))
print(f"The Maximum Distance reached was: {max(pa_walk)}, in trial: {pa_walk.index(max(pa_walk))}")
print(f"The Minimum Distance reached was: {min(pa_walk)}, in trial: {pa_walk.index(min(pa_walk))}")
Edit:
A minor thing to note, in python it is convention to use underscores rather than camelcase. This means the function randomWalkPa() would be better called random_walk_pa(). This is not necessary to make the code work and totally up to you

Python is not recognizing my variables, but instead replacing them with zero

Here is my code:
change = 0
count = 0
value = 0
answer = 0
def numberTest():
if change == 0:
skip()
else:
value = change
def skip():
count + 1
number = value
# Check if the input is valid
if value != number:
print('PLEASE ENTER A VALID NUMBER!!!')
else:
Even = number % 2
if Even == 0:
print('Substituting even number in: x / 2')
print('%s/2=' % number)
answer = number / 2
else:
print('Substituting odd number in: 3x + 1')
print('3' + number + ' + 1=')
answer = number * 3
answer = answer + 1
answer = str(answer)
print(''+ answer +'')
if answer == 1:
finalValue()
else:
check()
def check():
value = answer
skip()
def loop():
value = int(input('Input a number: '))
change = value
skip()
loop()
def finalValue():
print('The number (' + change + ') returned as 1.')
print('A total of (' + count + ') commands were executed.')
change = change + 1
count = 0
print('')
print('')
print('')
numberTest()
Whenever I start the code, I am asked to enter a number (as expected), but then this happens:
Input a number: 1
Substituting even number in: x / 2
0/2=
0.0
I really do not understand why the program is not working as I expected, but there is one part of the code that I am suspicious of:
value = int(input('Input a number: '))
I also wrote this myself, and I am new to Python, I have only previously worked with batch, so transitioning was quite easy, though I am not very familiar with some of the commands...
EDIT
What I was expecting the program to do was ask for a number, store that number, then run it through a series of tests, but when the number gets to the actual tests, it substitutes "x" for "0", even if I type in a number such as "54656". Maybe, when it asks for the number, when I input the number, it just doesn't store it right, or something is wrong with my code...
You are trying to change global variables without declaring them:
a = 'bad'
def bad_fn():
a = 'good'
bad_fn()
print('bad_fn() is'+a)
def good_fn():
global a
a = 'good'
good_fn()
print('good_fn() is'+a)
results in
bad_fn() is bad
good_fn() is good
In general, using global variables in bad practice. Passing parameters explicitly makes debugging and code reuse much less of a headache. Here is rewritten version of your code which should be easier to understand:
# Test the Collatz conjecture:
# http://en.wikipedia.org/wiki/Collatz_conjecture
import profile
# Python 2/3 compatibility shim
import sys
if sys.hexversion >= 0x3000000:
# Python 3.x
inp = input
rng = range
else:
# Python 2.x
inp = raw_input
rng = xrange
# cache of already-seen values
seen = set([1])
def test(n):
visited = set()
while True:
if n in seen: # Ran into an already-seen chain that goes to 1
seen.update(visited)
return len(visited)
elif n in visited: # Closed loop! this should never happen
print('Loop found at n = {}'.format(n))
return None
else:
visited.add(n)
if n % 2: # n is odd?
n = 3*n + 1
else:
n //= 2
def do_profile(upto=1000000):
prof = profile.Profile()
prof.run('for n in rng(2, {}): test(n)'.format(upto))
prof.print_stats()
def main():
while True:
try:
n = int(inp('Enter a number to test (or x to exit): '))
except ValueError:
break
res = test(n)
if res is None:
print("Well, that's odd...")
else:
print("Chain terminated after {} values were tested".format(res))
if __name__=="__main__":
main()
It took 17.7s on my machine to run do_profile(1000000). It looked at a total of 2,168,611 numbers, the highest of which was 56,991,483,520. No loops were found.
Edit: I have added an inp() shim function; the code should now run in both Python 2 or Python 3.
Edit2: moved the profiling code into the main code listing and added range/xrange to the Python 2/3 shims.
If you want to change a global variable, you need to declare it preceded by global in your function, ie:
value = 0
def changeValue():
global value
value += 1
If you do not need to change the variable, global is not required.

Categories