How can I retain zero in python for calculation? - python

So I supposed to verify if the input number is a UPC number or not. I have to allowed leading zeros and accounted it in the calculation.
Here is my current code, it works for all number except number has leading zeros:
Condition for UPC code valid:
Calculate the sum of multiplying odd digit index by 3 and even digit index by 1 of the input number.
Calculate the sum we just did modulo 10, get result digit.
If the resulting digit is between 1 and 9 then subtract result digit from 10. If the result digit is 0, add 0 to the to the base number to get the completed number.
def UPC_code(num):
sum_digit = 0
index = 0
num_temp = str(num)[:-1]
len_nt = len(num_temp)
for digit in num_temp:
if (index + 1) % 2 != 0: # If number position is odd
sum_digit += int(digit) * 3 # Sum = digit * 3
if index < len_nt: # Increase index till end
index += 1
elif (index + 1) % 2 == 0: # If number position is even
sum_digit += int(digit) * 1 # Sum = digit * 1
if index < len_nt:
index += 1
# print(sum_digit)
res_digit = sum_digit % 10
if 1 <= res_digit <= 9:
res_digit = 10 - res_digit # Res digit meet condition = 10 - res digit
if res_digit == num % 10:
return True
elif res_digit != num % 10:
return False
else:
print("Something went wrong")
# End UPC_code()
Call UPC_code()
import code_check.py as cc
num = str(input())
num_int = int(num)
if cc.UPC_code(num_int) is True and num_int != 0:
print(num, "valid UPC code.")
else:
print("Not valid")
Expected input:
042100005264
Expected output:
042100005264 valid UPC code
Actual output:
Not valid

it works for all number except number has leading zeros
As you have doubtless discovered, python does not allow you to write 0700. Historically that would have meant 0o700, or 448, which is likely not what you want anyhow...
In this case the solution is simple. If you need to handle numbers like 00007878979345, handle strings.
Thus refactor your code to take a string. As a bonus, int("000008") is 8, so when you need the number as a number you don't even have to do anything.

Related

Python: .count() doesn't count

I'm writing a simple program that takes user input and prints the number of even, odd and zeros.
The program doesn't yield any errors but it seems to skip line 5 and 15
I want to count and display the zeroes in the numbers list
numbers = input("Numbers seperated by space:").split()
print("Numbers:" + str(numbers))
zero = numbers.count(0)
even = 0
odd = 0
for i in numbers:
if int(i) % 2 == 0:
even += 1
else:
odd += 1
even = even - zero
print("Even:" + str(even))
print("Odd:" + str(odd))
print("Zero:" + str(zero))
Youre code isnt working because inputs in Python are strings. So when you enter a number like 5, Python turns it into "5". So to make your code work change .count(0) to .count("0")
numbers = input("Numbers seperated by space:").split()
print("Numbers:" + str(numbers))
zero = numbers.count("0")
even = 0
odd = 0
for i in numbers:
if int(i) % 2 == 0:
even += 1
else:
odd += 1
even = even - zero
print("Even:" + str(even))
print("Odd:" + str(odd))
print("Zero:" + str(zero))
Output:
Numbers seperated by space:
5 0 0 2
Numbers:['5', '0', '0', '2']
Even:1
Odd:1
Zero:2
If you are sure that only numbers are the input you could also do
numbers = [int(elem) for elem in input("Numbers seperated by space:").split()]
zero = numbers.count(0)
When counting evens, zeros may get added so I would check for this condition first
numbers = input("Numbers separated by space:").split()
print("Numbers:" + str(numbers))
zero = 0
even = 0
odd = 0
for i in numbers:
if int(i) == 0:
zero += 1
elif int(i) % 2 == 0:
even += 1
else:
odd += 1
# using f-string to format output instead
print(f"Even: {even}")
print(f"Odd: {odd}")
print(f"Zero: {zero}")
numbers = input("Numbers separated by space:").split()
zero = numbers.count("0")
even = 0
odd = 0
for i in numbers:
if int(i) % 2 == 0 and i != '0':
even +=1
elif int(i) %2 !=0 and i != '0':
odd +=1
print("Even:" + str(even))
print("Odd:" + str(odd))
print("Zero:" + str(zero))

Python - print only the highest number of collatz

def collatz(number):
if number % 2 == 0:
print(number // 2)
return number // 2
elif number % 2 == 1:
result = 3 * number + 1
print(result)
return result
#4. zolang n ongelijk is aan 0, niet stoppen.
n = input("invoer: ")
while n != 1:
n = collatz(int(n))
I've got this code, but I only want to print the highest number in place of the whole queue of collatz sequence.
How could I do that?
Your code can be refactored to print the maximum number from the Collatz Sequence as follows:
def collatz(number):
if number % 2 == 0:
return number // 2
else:
return (3 * number) + 1
# Refactored this part because Collatz Conjecture is defined for positive
# numbers only
try:
n = int(input('invoer: '))
if n <= 0:
raise ValueError
except ValueError:
print('Enter a valid positive integer')
# Set a variable to store maximum value
max_num = 0
while n != 1:
# If the current number is bigger than existing maximum number, update it
max_num = max(n, max_num)
n = collatz(int(n))
print('Maximum number is {}'.format(max_num))
Note that I have updated some of your original code so that only positive integer is a valid input. This is because Collatz Conjecture states that the sequence starts with a positive integer.
Also, in the if-else construct, you do not need to write the condition for odd numbers explicitly because if the integer is not even then it must be odd.
Just have a max variable which you update with n, if n is larger than that variable's value:
def collatz(number):
if number % 2 == 0:
return number // 2
elif number % 2 == 1:
return 3 * number + 1
n = input('invoer: ')
m = 0
while n != 1:
if n > m: m = n
n = collatz(int(n))
print('the max was:', m)
With the input 5 gives 16, since 16 is the max of [5, 16, 8, 4, 2, 1].

Luhn's Algorithm Pseudocode to code

Hey guys I'm fairly new to the programming world. For a school practice question I was given the following text and I'm suppose to convert this into code. I've spent hours on it and still can't seem to figure it out but I'm determine to learn this. I'm currently getting the error
line 7, in <module> if i % 2 == 0: TypeError: not all arguments converted during string formatting
What does this mean? I'm still learning loops and I'm not sure if it's in the correct format or not. Thanks for your time.
# GET user's credit card number
# SET total to 0
# LOOP backwards from the last digit to the first one at a time
# IF the position of the current digit is even THEN
# DOUBLE the value of the current digit
# IF the doubled value is more than 9 THEN
# SUM the digits of the doubled value
# ENDIF
# SUM the calculated value and the total
# ELSE
# SUM the current digit and the total
# ENDIF
# END loop
# IF total % 10 == 0 THEN
# SHOW Number is valid
# ELSE
# SHOW number is invalid
# ENDIF
creditCard = input("What is your creditcard?")
total = 0
for i in creditCard[-1]:
if i % 2 == 0:
i = i * 2
if i > 9:
i += i
total = total + i
else:
total = total + i
if total % 10 == 0:
print("Valid")
else:
print("Invalid")
well, i can see 2 problems:
1)when you do:
for i in creditCard[-1]
you dont iterate on the creditCard you simply take the last digit.
you probably meant to do
for i in creditCard[::-1]
this will iterate the digits from the last one to the first one
2)
the pseudocode said to double the number if its POSITION is even, not if the digit itself is even
so you can do this:
digit_count = len(creditCard)
for i in range(digit_count -1, -1, -1):
digit = creditCard[i]
or have a look at the enumerate built-in function
edit:
complete sample:
creditCard = input("What is your creditcard?")
total = 0
digit_count = len(creditCard)
for i in range(0, digit_count, -1):
digit = creditCard[i]
if i % 2 == 0:
digit = digit * 2
if digit > 9:
digit = digit / 10 + digit % 10 # also noticed you didnt sum the digits of the number
total = total + digit
if total % 10 == 0:
print("Valid")
else:
print("Invalid")

Narcissistic number

Today I saw an interesting task. To make a program which outputs all "narcissistic numbers" (all digits are raised to the power of 3). My program has this code
for number in range(1, 408):
result = 0
for digit in str(number):
result += int(digit) ** 3
if result == number:
print(number)
The output is
1
153
370
370
371
407
Why does 370 appear twice?
You should unindent the last if statement, which runs after each digit:
for number in range(1, 408):
result = 0
for digit in str(number):
result += int(digit) ** 3
if result == number:
print(number)
As another answer notes, this can give you false duplicates if there is match in a number with trailing 0's. There is an added danger, though, of false positives if there is a number whose left X digits equal it, but whose total digits do not.
You're checking whether result==number after each digit in the number. You probably want this check in the outer for loop. As it is, it sees that 370 = 3**3 + 7**3, but it is also 3**3 + 7**3 + 0**3, so it's printed on both of those iterations.
Below code will return true or false if number is narcissistic:
def narcissistic(number):
number = str(number)
empty_arr = []
count = 0
for n in number:
n = int(n)
empty_arr.append(n ** len(number))
for n in empty_arr:
count = count + n
count = int(count)
number = int(number)
if count == number:
return True
else:
return False
I've done something like that to solve the problem:
import math;
def narcissistic( n ):
DecimalPlaces = 0 if n == 0 else math.floor(1 + math.log10(n))
soma = 0
digit = 0
NarcissisticSum = 0
i = 0
for i in range(1,DecimalPlaces):
digit = int((n % 10**i - digit) / (10**(i-1)))
NarcissisticSum += digit ** (DecimalPlaces)
lastDigit = int((n - soma) / (10**i))
NarcissisticSum += lastDigit ** (DecimalPlaces)
return NarcissisticSum == n

Python: Code to find a number where first N digits are divisible by N (from 0-9)

I've been trying to write a recursive solution to a program to find a number where first N digits are divisible by N.
As an example: 3816547290, 3 is divisible by 1, 38 is divisible by 2, 381 is divisible by 3 and so on...
My recursive solution works fine while going "into" the recursion, but has issues when the stack unwinds (i.e. I don't specifically know how to backtrack or take steps on the way out
ARR = [0]*10
ARR[0] = 1 #dummy entry
def numSeq(pos, num):
if all(ARR):
print num
return True
if (pos>0) and (num%pos) != 0:
return False
for i in xrange(1,10):
if ARR[i] == 1:
continue
new_num = num*10 + i
if new_num%(pos+1) == 0:
ARR[i] = 1
numSeq(pos+1,new_num)
The problem with this code seems to be that it follows the number generation correctly while going into the recursion...so it correctly generates the number 123654 which is divisible by 6 and follows first N digits being divisible by N, but after it fails to find any further digits from 7-8 or 9 that divide 7, i don't get the next set of steps to "reset" the global ARR and begin from index 2, i.e. try 24xxxx,and eventually get to 3816547290
Thanks in Advance for your help!
EDIT: One condition I'd forgotten to mention is that each digit must be used exactly once (i.e. repetition of digits is disallowed)
2nd EDIT:
I was able to finally apply proper backtracking to solve the problem...this code works as is.
ARR = [0]*10
def numDivisibile(num,pos):
if all(ARR):
print num
return True
for i in xrange(0,10):
if ARR[i] == 1:
continue
new_num = num*10+i
#check for valid case
if new_num%(pos+1) == 0:
ARR[i] = 1
if numDivisibile(new_num, pos+1):
return True
#backtrack
ARR[i] = 0
return False
print numDivisibile(0, 0)
To generate all 10 digits integers where the first n digits are divisible by n for each n from 1 to 10 inclusive:
#!/usr/bin/env python3
def generate_ints_nth_digit_divisible_by_n(n=1, number=0):
number *= 10
if n == 10:
yield number # divisible by 10
else:
for digit in range(not number, 10):
candidate = number + digit
if candidate % n == 0: # divisible by n
yield from generate_ints_nth_digit_divisible_by_n(n + 1, candidate)
print("\n".join(map(str, generate_ints_nth_digit_divisible_by_n())))
Output
1020005640
1020061620
1020068010
...
9876062430
9876069630
9876545640
To get numbers where each digit occurs only once i.e., to find the permutations of the digits that satisfy the divisibility condition:
def divisibility_predicate(number):
digits = str(number)
for n in range(1, len(digits) + 1):
if int(digits[:n]) % n != 0:
return n - 1
return n
def generate_digits_permutation(n=1, number=0, digits=frozenset(range(1, 10))):
# precondition: number has n-1 digits
assert len(set(str(number))) == (n - 1) or (number == 0 and n == 1)
# and the divisibility condition holds for n-1
assert divisibility_predicate(number) == (n - 1) or (number == 0 and n == 1)
number *= 10
if n == 10:
assert not digits and divisibility_predicate(number) == 10
yield number # divisible by 10
else:
for digit in digits:
candidate = number + digit
if candidate % n == 0: # divisible by n
yield from generate_digits_permutation(n + 1, candidate, digits - {digit})
from string import digits
print([n for n in generate_ints_nth_digit_divisible_by_n()
if set(str(n)) == set(digits)])
print(list(generate_digits_permutation()))
Output
[3816547290]
[3816547290]
In your function, you never do return numSeq(...), this seems like causing the issue.
If you want to have a iterative solution, you can check the following:
def getN(number):
strNum = str(number)
for i in range(1, len(strNum)+1):
if int(strNum[:i]) % i != 0:
return i-1
return i
print getN(3816)
print getN(3817)
print getN(38165)
Output:
4
3
5
We can modify your recursive function a little to try different possibilities. Rather than have a global record (ARR) of used positions, each thread of the recursion will have its own hash of used digits:
def numSeq(pos, num, hash):
if pos != 1 and num % (pos - 1) != 0: # number does not pass the test
return
elif pos == 11: # number passed all the tests
print num
elif pos == 5:
numSeq(pos + 1,10 * num + 5,hash) # digit is 5 at position 5
elif pos == 10:
numSeq(pos + 1,10 * num,hash) # digit is 0 at position 10
else:
k = 2 if pos % 2 == 0 else 1 # digit is even at even positions
for i in xrange(k,10,2):
if hash & (1 << i): # digit has already been used, skip it
continue
numSeq(pos + 1,10 * num + i,hash | (1 << i))
numSeq(1,0,0) # 3816547290

Categories