def get_success_rate(statistics: str) -> int:
count = 0
for i in statistics:
if statistics == '':
return 0
if i == '1':
count += 1
res = count / len(statistics) * 100
return round(res)
print(get_success_rate("11100")) # 60
print(get_success_rate("1100")) # 50
print(get_success_rate("000000")) # 0
print(get_success_rate("11111")) # 100
print(get_success_rate("")) # 0
60
50
0
100
Traceback (most recent call last):
File "D:\Program Files\Python\CHERHOBNK\Folder - 1\draft.py", line 807, in <module>
print(get_success_rate("")) # 0
File "D:\Program Files\Python\CHERHOBNK\Folder - 1\draft.py", line 799, in get_success_rate
res = count / len(statistics) * 100
ZeroDivisionError: division by zero
Move the empty string check outside the loop:
def get_success_rate(statistics: str) -> int:
if statistics == '':
return 0
count = 0
for i in statistics:
if i == '1':
count += 1
res = count / len(statistics) * 100
return round(res)
If string is empty the loop will not be executed so the check will actually be skipped.
The logic of your function is not sound. Guessing from the code, you probably want to do the if statistics == '' clause before your iteration, for i in statistics. Then you'll no longer have the division by zero error of your function.
the problem with your current code, is that the iteration doesn't happen when statistics == '', there's nothing to iterate over. And then the call is made to res = count / len(statistics) * 100, and as len("") equals zero, that's giving you the division by zero error
Related
I am trying to solve the problem in the title, and I'm getting an IndexError.
def count_zeros(number:int) -> int:
number = str(number)
i = 0
j = -1
while number[j] == '0'
i += 1
j += -1
return i
This code spits out the IndexError only when the number is 0. I cannot figure out why.
>>>count_zeros(0)
IndexError Traceback (most recent call last)
<ipython-input-45-688099e7700c> in <module>
----> 1 end_zeros(0)
<ipython-input-43-181de92af60c> in end_zeros(number)
4 i = 0
5
----> 6 while number[j] == '0':
7 i += 1
8 j -= 1
IndexError: string index out of range
I would use the modulus here and count the number of zeroes on the right:
def count_zeros(number:int) -> int:
if number == 0:
return 1
else:
count = 0
while True:
if number % 10 != 0 or number == 0:
break
count = count + 1
number = number / 10
return count
This approach is straightforward, and will almost certainly outperform casting the input integer to a string and then checking for trailing zeroes.
As an alternative approach to iteration, using regular expressions proves to be a simple approach.
Since your code converts the number to a string already, it doesn't hurt to pass the string directly to re.search to find the trailing zeros for you effortlessly.
Here is a working example, along with some test cases:
import re
def count_zeros(number: int) -> int:
count = re.search(r'0+$', str(number))
return len(count[0]) if count else 0
print(count_zeros(1))
print(count_zeros(123))
print(count_zeros(0))
print(count_zeros(10))
print(count_zeros(12300))
print(count_zeros(123000))
Output:
0
0
1
1
2
3
How many zeros does a number have at the end
def count_zeros(num: int) -> int:
return len(str(num)) - len(str(num).rstrip('0'))
print(count_zeros(0)) #1
print(count_zeros(1)) #0
print(count_zeros(10)) #1
print(count_zeros(245)) #0
print(count_zeros(101)) #0
print(count_zeros(100100)) #2
For this problem, honestly, the simplest solution is likely going to be to handle the case where number==0 separately, by putting something like this at the top.
if number ==0:
return 1
Your loop with an iterator and a count works, but I would prefer to cast to a list so I don't have to keep track of two variables...assuming performance is not a huge concern here.
So something like:
def count_zeros(number:int) -> int:
if number==0:
return 1
number_list = list(str(number))
is_zero = True
zero_count = 0
while is_zero:
if int(number_list.pop())==0:
zero_count += 1
else:
is_zero = False
return zero_count
def end_zeros(a: int) -> int:
count = 0
list = [int(x) for x in str(a)]
list.reverse()
list.append(1)
for x in list:
if x == 0:
count += 1
else:
return count
Just playing with some basic code (factorials) but cannot quite get my head around how this is achieving the correct result. The result on each loop does not seem to be stored anywhere - so how does the code remember the iterated value? (I know there are modules - this is just a logic exercise)
def factoral2(num):
if num == 0:
return 1
return num * factoral2(num - 1)
Above is the method that I'm not quite sure how works
def factoral(num):
number = []
for i in range(0, num):
number.append(num)
num -= 1
print(number)
product = 1
for x in number:
product *= x
return product
This was my interpretation of its logic, which is obviously a bit more verbose than what's ideal
Both work - just trying to understand the logic of the optimised version
ok, let's run through an example lets say the user inputs 2 -> num=2.
First, we have to build our way down (essentially we need num to equal 0)
first, we call factorial(2), and check the if statement which turns out to be false.
therefor factorial(2) = return num * factorial(num-1) = return 2 * factorial(1)
the above statement needs to compute the value for factorial(1) before it can return a value, so let's go ahead and do that
first, we call factorial(1), and check the if statement which == false
therefor factorial(1) = return num * factorial(num-1) = return 1* factorial(0)
the above statement needs to compute the value for factorial(0) before it can return a value, so let's go ahead and do that also
first, we call factorial(0), and check the if statement which == true
therefor factorial(0) = 1
Now we can start building up
factorial(0) = 1
now just start plugging in values
we said factorial(1) = return 1* factorial(0) = return 1* 1 = return 1
factorial(1) = 1
now we can plug in some more values
we said factorial(2) = return 2* factorial(1) = return 2 * 1 = return 2
factorial(2) = 2
Thanks to Andreas and below_avg_st for your help.
Makes alot more sense now.
As I see it:
Recursive functions generate an infinite loop if a condition to break is not allocated.
(I've re-written the below to state that logic abit more). If X does not equal 0, keep looping through the function while decrementing X.
When the loop does break - (because X = 0) assign a value of 1 - to exit the loop.
def test(x):
if x != 0:
return x * test(x-1)
else:
return 1
test(4)
Thanks to all for your help
It's a recursive function that calls itself, giving num - 1 as argument.
The function supplied:
def factoral2(num):
if num == 0:
return 1
return num * factoral2(num-1)
"gets expanded" into this:
def factoral2(num):
result = 1
while (num != 0):
result *= num
num -= 1
return result
value = factoral2(4) can be illustrated as such:
num = 4
num = 3
num = 2
num = 1
num = 0; return 1
result = 1
result = 2 * 1
result = 3 * 2
result = 4 * 6
value = 24
I'd also like to note out a better non-recursive version of the factorial function, compared to the one you crafted, that unnecessarily creates and fills a list.
def factorial(n):
if n < 0:
raise ValueError("The factorial value may only be calculated on positive integers")
product = 1
for i in range(2, n + 1):
product *= i
return product
– or just a simplified recursive one, using the "ternary operator":
def factorial(n):
if n < 0:
raise ValueError("The factorial value may only be calculated on positive integers")
return 1 if n == 0 else n * factorial(n - 1)
I am trying to write a python function which will give me back the first value of a number k which will function 2 >= function 1
function 1(p) => 1 + 1/1! + 1/2! + 1/p!
function 2(k) => (1 + 1/k)^k
So I input use 2 for example in function 1. It would take estimate e at 2.5 but it would take k being 6 for it to get close which is 2.522.
I want to return the 6.
I get this far but I am not sure where to go from there.
for x in range(p):
factorial(x):
if x == 0:
return 0
else:
return x * factorial(x-1)
result = 1 + 1/factorial(p)
I think you need two separate functions, and no loops are needed.
def factorial(x):
if x in {0, 1}:
return 1 # This needs to be 1, otherwise you multiply everything by 0
else:
return x * factorial(x-1)
def summ(p):
if p == 0:
return 1
elif p == 1:
return 2
else:
return 1/factorial(p) + summ(p-1)
Regarding the rest of the question, I think this will help
def f2(k):
return 1 if k == 0 else (1 + 1/k)**k
max_iter = 10 # TODO: increase
k = 0
delta = 0.000001
while max_iter > 0:
f1_result = summ(k)
f2_result = f2(k)
check = f1_result <= f2_result
print("k={}: {:6.8f} <= {:6.8f} == {}".format(k, f1_result, f2_result, check))
k += 1
max_iter -= 1
# if check:
# break
# TODO: Check if difference is within acceptable delta value
Output
k=0: 1.00000000 <= 1.00000000 == True
k=1: 2.00000000 <= 2.00000000 == True
k=2: 2.50000000 <= 2.25000000 == False
k=3: 2.66666667 <= 2.37037037 == False
k=4: 2.70833333 <= 2.44140625 == False
k=5: 2.71666667 <= 2.48832000 == False
k=6: 2.71805556 <= 2.52162637 == False
k=7: 2.71825397 <= 2.54649970 == False
k=8: 2.71827877 <= 2.56578451 == False
k=9: 2.71828153 <= 2.58117479 == False
From larger numbers, this check still fails at k=996 and throws a recursion error.
k=996: 2.71828183 <= 2.71691848 == False
Traceback (most recent call last):
File "python", line 22, in <module>
File "python", line 13, in summ
File "python", line 5, in factorial
File "python", line 5, in factorial
File "python", line 5, in factorial
[Previous line repeated 992 more times]
RecursionError: maximum recursion depth exceeded
Therefore, it would help if you wrote a factorial function using a loop rather than recursion.
Edit
I think I understand what you are trying to get now
in1 = int(input("value 1:"))
v1 = summ(in1)
v2 = 0
max_iter = 50 # Recursion execution limit
while f2(v2) <= v1 and max_iter > 0:
v2 += 1
max_iter -= 1
print(v2)
Output
value 1: <enter 2>
6
I'm working on a program that finds perfect numbers (i.e., 6, because its factors, 1, 2, and 3, add up to itself). My code is
k=2
mprim = []
mprimk = []
pnum = []
def isprime(n):
"""Returns True if n is prime."""
if n == 2:
return True
if n == 3:
return True
if n % 2 == 0:
return False
if n % 3 == 0:
return False
i = 5
w = 2
while i * i <= n:
if n % i == 0:
return False
i += w
w = 6 - w
return True
def mprime(k):
while k < 50:
check = (2**k)-1
if isprime(check) == True:
mprim.append(check)
mprimk.append(k)
print check
k+=1
else:
k+=1
mprime(k)
def isperf(lst):
for i in lst:
prm = (((2**i)-1)(2**i))/(2)
pnum.append(prm)
isperf(mprimk)
print pnum
The first part, that checks if a number is prime, and produces mercenne primes, is working alright. Its the second part I'm having trouble with. I have read that if 2^k - 1 is prime, then ((2^k - 1)(2^k))/2 is a perfect number, so I am using that formula.
The error it gives is
Traceback (most recent call last):
File "python", line 47, in <module>
File "python", line 44, in isperf
TypeError: 'int' object is not callable
Line 47 is isperf(mprimk) and line 44 is prm = (((2**i)-1)(2**i))/(2). Any assistance would be appreciated.
Thanks!
The error clearly states that you are trying to call an int type, which isn't callable.
In practice it means you trying to do something like 123()
And code responsible for it is ((2**i)-1)(2**i) because you forgot * and it should be (((2**i)-1)*(2**i))/(2)
Here is the question:
Let us calculate sum of digits, as earlier, but multiplying each digit by its position (counting from the left, starting from 1). For example, given the value 1776 we calculate such weighted sum of digits (let us call it "wsd") as:
wsd(1776) = 1 * 1 + 7 * 2 + 7 * 3 + 6 * 4 = 60
Here is my code:
digitlist = []
numlist = []
def splitdigit(number):
numlist = []
digitlist = []
numlist.append(number)
while number >= 1:
number = number/10
numlist.append(number)
del numlist[-1]
for ele in numlist:
digitlist.append(ele%10)
return digitlist
# digit part
# test if the split digit work here:
# print (splitdigit(1234)) it works
times = int(input())
raw = raw_input()
string = raw.split()
nlist = []
outbox = []
rout = 0
res = 0
n = 0
for item in string:
nlist.append(int(item))
# print (nlist) [it worked]
for element in nlist:
# check for split method : checked
# formula to make the digit work: n = len(out) | while(n>1): n=n-1
# rout=out[-n]*n res=res+rout(res=0)
n = len(splitdigit(element))
print (n)
res = 0
while n >= 1:
rout = (splitdigit(element)[(n*(-1))]) * n # I HAVEN"T CHECK THIS FORMULA OUT !!!
res = res + rout
n = n + 1
outbox.append(res)
print (outbox)
print(" ".join(str(x) for x in outbox))
And here is my running error:
> 3
9 15 1776
1
Traceback (most recent call last):
File "13.py", line 39, in <module>
rout = splitdigit(element)[(n*(-1))] * n # I HAVEN"T CHECK THIS FORMULA OUT !!!
IndexError: list index out of range
and I checked it in interactive python. I think I am not asking for a item out of range but it gives me this error. I hope someone can help me out. Thank you, love you all.
You are thinking way too complicated.
def wsd(number):
digits = [int(i) for i in str(number)]
result = 0
for index, value in enumerate(digits):
result += (index + 1) * value
return result
print(wsd(1776))
Output:
60