Function is not returning any values - python

I am coding to find whether or not a number is a disarium number or not. A disarium number is a number in which it's digits can be raised to the power of their respective positions and added to give the number.
Example1: 75 is not a disarium number, because 7^1 + 5^2 = 32 and not 75
Example2: 135 is a disarium number, since: 1^1 + 3^2 + 5^3 = 1 + 9 + 125 = 135
In my code, even though 75 is not a disarium number, nothing is returned. It's like my function isn't even going through my if and else statements
def is_disarium(number):
number = str(number)
selection_array = [int(num) for num in number]
disarium_check = 0
for i in range(len(selection_array)):
disarium_check += int(selection_array[i])**(i+1)
if disarium_check == number:
return True
else:
return False
is_disarium(75)
My code (image)

This code is currently returning False for every number because in the if statement you are comparing an integer with a string. And you can use the print command to find the return value.
Use this modified code to check whether it is working as expected.
def is_disarium(number):
number = str(number)
selection_array = [int(num) for num in number]
disarium_check = 0
for i in range(len(selection_array)):
disarium_check += int(selection_array[i])**(i+1)
if disarium_check == int(number):
return True
else:
return False
output = is_disarium(135)
print(output)

Related

How do I keep a loop going with a variable that changes in every loop

So I'm new to coding and I'm struggling with the following exercise
So we start with a random number and we have to count the even numbers and the odd numbers. With this, we make a second number that starts with the amount of the even numbers, amount of the odd numbers, and the amount of numbers in total. We should continue this until the number 123 is reached.
For example:
number = 567421 --> odd numbers = 3 , even numbers = 3 , total numbers = 6 --> new number = 336 -->...
I had an idea to write it like this:
number = input()
evennumbers = ''
oddnumbers = ''
a = len(number)
while number != '123':
for i in str(number):
if int(i) % 2 == 0:
evennumbers += i
else:
oddnumbers += i
b = len(evennumbers)
c = len(oddnumbers)
number = input(print(f"{b}{c}{a}"))
But I have no idea how to keep this loop going with the variable 'number' until 123 is reached
You need your variable initialization to be inside the while loop, and remove the input(print(... on the final line.
number = '567421'
while number != '123':
print(number)
evennumbers = ''
oddnumbers = ''
a = len(number)
for i in str(number):
if int(i) % 2 == 0:
evennumbers += i
else:
oddnumbers += i
b = len(evennumbers)
c = len(oddnumbers)
number = f"{b}{c}{a}"
You could simplify like this:
while number != '123':
print(number)
total = len(number)
odds = sum(int(digit) % 2 for digit in number)
evens = total - odds
number = f"{evens}{odds}{total}"

How to check if a number is a concatenation of 1, 14 or 144

I've managed to get the code to check whether or not it's a concatenation of 1, 14, or 144 but the main problem here is that when I print numbers like 144441 it returns "YES" when it should give a "NO."
This problem occurs as long as there are at least 3 fours sandwiched between 2 ones (i.e. 14441, 14444444444441, 1444441)
def magic_num(N):
magic = N
while magic in range(1,1000000001):
if (magic % 1000 == 144):
magic /= 1000
elif (magic % 100 == 14):
magic /= 100
elif (magic % 10 == 1):
magic /= 10
else:
return"NO"
return "YES"
N = int(input("Enter an integer between 1 and 10^9: "))
print(magic_num(N));
I think for your case you just need to check that your number only contains 1s and 4s, that it starts with a 1 and that you don't have three or more 4's in a row:
def is_concatenation(n):
"""Returns True if n is a concatenation of 1, 14 and 144"""
n = str(n)
return set(n) <= {"1", "4"} and n.startswith("1") and "444" not in n
I really suggest using RegEx (Regular Expression) to handle this issue. You can do that simply like so:
import re
regex = r"^(1+4{,2})+$"
def is_concatenation(N):
return re.match(regex, str(N)) is not None
Let's test this function over some test-cases:
>>> is_concatentaion(1)
True
>>> is_concatentaion(14)
True
>>> is_concatentaion(144)
True
>>> is_concatentaion(1444)
False
>>> is_concatentaion(14414)
True
>>> is_concatentaion(14414111)
True
>>> is_concatentaion(144414111)
False
>>> is_concatentaion(144441)
False
>>> is_concatentaion(14444444444441)
False
>>> is_concatentaion(1444441)
False
I like the pattern match answer from #Anwarvic. However if you want make your approach work instead of converting it to a string, try this:
def magic_num(magic):
while magic:
if (magic % 1000 == 144):
magic //= 1000
elif (magic % 100 == 14):
magic //= 100
elif (magic % 10 == 1):
magic //= 10
else:
return"NO"
return "YES"
N = int(input("Enter an integer "))
print(magic_num(N))
You should be doing integer division. Also you just need to check that the result is not 0 as the loop terminator. As a result of that change you do not have to limit the size of the number input either.
You can directly operate on the number parameter passed in. In this context it is only changing the value passed and NOT changing the callers copy of the number passed in, so this is safe to do.
Here's my way:
n = [1, 14, 144]
def magic_num(N):
n.sort(reverse=True) # Sort the list from greatest to least
for number in n:
if str(number) in N:
while N != N.replace(str(number),'_',1):
N = N.replace(str(number),'_',1)
if N.replace('_','') == '':
return 'YES'
return 'NO'
N = input("Enter an integer: ")
print(magic_num(N))
This program will not work if the list isn't sorted from greatest to least. The reason: Lets say our integer is 14414. When the program iterates through the list, if it sees a 1 first, it will replace the first 1 in 14414, before the program notices the 144 that's supposed to be replaced, leaving the program with 4414, and obviously, it will return 'NO'.
Try this instead
from re import findall, search
def magic_num(n):
n = str(n)
if search("[^14]", n) or any(len(s) > 2 for s in findall("4+", n)):
return "NO"
return "YES"

All function only checking one element

counter = 0
numList = []
beginning = 1
primeOrNot = False
number = int(input("Type a number to check if it's prime."))
while True:
if number == 2:
primeOrNot = True
elif "2" in str(number) or "4" in str(number) or "6" in str(number) or "8" in str(number) or "0" in str(number) or number == 1:
primeOrNot = False
numList = [''.join(p) for p in permutations(str(number))]
for p in range(0, len(numList)):
numList[p] = int(numList[p])
for u in range(2, number):
if all(o % u == 0 for o in numList):
counter = counter + 1
if counter == 0:
print(numList)
break
I'm trying to make it so it prints a prime if all permutations of the number are also primes.
I've tried to do that with all but what it's doing is checking if atleast 1 of the elements in the list fits the o % u = 0. I want it to check if all of the elements work, not if one. Anything I can do using all or using something else?
Example of output now:
Input: 12
Output: Nothing, Neither 12 nor 21 are prime
Input: 35
Output: 35, 53
Even though 35 isn't prime it prints because 53 is.
Your logic is faulty:
for u in range(2, number):
if all(o % u == 0 for o in numList):
counter = counter + 1
For each potential divisor in the range, you check to see whether that divisor goes into every permutation of the input. What value of u do you envision is going to divide both 35 and 53?
For starters, you need this to be any, not all.
Second, I strongly recommend that you look up how to find primes and/or factor numbers. You can learn better ways to handle this, especially when your input string is longer.
Also, note that a 0 or 5 in the input will also ensure that some of the permutations will be composite; assuming that the input is at least two digits, it must be entirely composed of 1379 digits.
if number in [2, 3, 5, 7]:
print("number is prime")
exit(0)
if any (d not in "1379" for d in str(number)):
print("This input has composite permutations")

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

The Next Palindrome number

I am beginner in programming, So can you please tell me what's wrong with my code?
I want to print next palindrome number if the number entered by the user (n) is not palindrome
n = int(input("Enter any number :- "))
reverse = 0
temp = n
while (n!=0):
reverse = reverse * 10
reverse = reverse + n%10
n=n//10
if(temp==reverse):
print ("Already palindrome:: ")
if(temp != reverse):
new_temp = temp
new_reverse = 0
for i in range(new_temp,new_temp+10):
while(temp != 0):
new_reverse = new_reverse * 10
new_reverse = new_reverse + temp%10
temp = temp//10
if(new_temp==new_reverse):
print ("Next pallindrome is :- ",new_temp)
break
if(new_temp != new_reverse):
temp = new_temp+1
There are two problems with your code.
1) Your "for i in range" loop calculates the reverse of the temp variable, but you don't change the temp variable's value.
You do
new_temp = temp
for i in range(new_temp,new_temp+10):
[SNIP]
if(new_temp != new_reverse):
temp = new_temp+1 #this value never changes.
So you're making 10 iterations with one and the same value.
2) Ten iterations might not be enough to find a palindrome. Keep going until you find a palindrome.
Working code:
def reverse(num):
reverse= 0
while num:
reverse= reverse*10 + num%10
num= num//10
return reverse
num= int(input("Enter any number :- "))
if num==reverse(num):
print ("Already palindrome.")
else:
while True:
num+= 1
if num==reverse(num):
print ("Next palindrome is : %s"%num)
break
To check if a number is a palindrome, you don't need to convert it to a number. In fact, its a lot simpler if you just check the string equivalent of your number.
>>> i = '212'
>>> i == i[::-1]
True
>>> i = '210'
>>> i == i[::-1]
False
Use this to your advantage, and create a function:
def is_palindrome(foo):
return str(foo) == str(foo)[::-1]
Next, to find the next palindrome, simply increment the number till your palindrome check is true.
Combine all that, and you have:
def is_palindrome(n):
return str(n) == str(n)[::-1]
n = raw_input('Enter a number: ')
if is_palindrome(n):
print('Congratulations! {0} is a palindrome.'.format(n))
else:
n1 = n
while not is_palindrome(n1):
n1 = int(n1)+1
print('You entered {0}, but the next palindrome is {1}'.format(n, n1))
Here is how it works:
$ python t.py
Enter a number: 123
You entered 123, but the next palindrome is 131
$ python t.py
Enter a number: 121
Congratulations! 121 is a palindrome.
If it helps, I believe it's possible to solve this problem with n/2 iterations where n is the length of the input number. Here's my solution in Python:
def next_palin_number(number):
number+=1
# Convert the number to a list of its digits.
number = list(str(number))
# Initialize two indices for comparing symmetric digits.
i = 0
j = len(number) - 1
while i < j:
# If the digits are different:
if number[i] != number[j]:
# If the lower-power digit is greater than the higher-power digit:
if int(number[j]) > int(number[i]):
if number[j-1]!='9':
number[j - 1] = str(int(number[j - 1]) + 1)
number[j] = number[i]
else:
number = list(str(int(''.join(number[:j]))+1))+number[j:]
else:
number[j] = number[i]
i += 1
j -= 1
# Concatenate and return the result.
return "".join(number)
This problem has a wonderful number of ways to solve them.
One of them is
def nearest_palindrome(number):
#start writitng your code here
while True:
number+=1
if str(number) == str(number)[::-1]:
return number
number=12300
print(nearest_palindrome(number))
Thanks for your time to read my answer : )
I have written this for finding next pallindrome number given a pallindrome number.
def palindrome(num):
bol=False
#x=len(str(num))
num=num+1
while(bol==False):
if(check_palindrome(num)):
bol=True
else:
num=num+1
return num
def check_palindrome(n):
temp=n
rev=0
while(n>0):
dig=n%10
rev=rev*10+dig
n=n//10
if(temp==rev):
return True
b=palindrome(8)
print(b)
def next_palin_drome(n):
while True:
n+=1
if str(n) == str(n)[::-1]:
return n
n=12231
print(next_palin_drome(n))
output:12321
def nearest_palindrome(number):
for i in range(1,number):
number=number+1
tem=str(number)
tem1=tem[-1::-1]
if(tem==tem1):
return number
else:
continue
number=12997979797979797
print(nearest_palindrome(number))
def nearest_palindrome(number):
n = len(str(number))//2
if(len(str(number)) % 2 == 0):
#number like 1221
number_1 = int((str(number))[:n]) #12
number_2 = int((str(number))[n:]) #21
if(number_1 < number_2):
number_1 += 1
number_2 = int(str(number_1)[::-1])
else:
number_2 = int(str(number_1)[::-1])
# if last half part is zero then just reverse the first number
if number_2 == 0:
number_2 = str(number_1)[::-1]
#combining the both parts
ans = int(str(number_1) + str(number_2))
return ans
else:
#numer like 12510 n=2
nu = int((str(number))[:n+1]) #add in this number
number_1 = int((str(number))[:n]) # 12
number_2 = int((str(number))[n+1:]) # 21
if (number_1 < number_2):
nu += 1
number_2 = int((str(nu))[::-1][1:])
else:
number_2 = int((str(nu))[::-1][1:])
#if last half part is zero then just reverse the first number
if number_2 == 0:
number_2 = str(nu)[::-1]
number_2 = number_2[1:]
#combinning both parts
ans = int(str(nu) + str(number_2))
return ans
number=12331
print(nearest_palindrome(number))
If a definite range is given:
# function to check if the number is a palindrome
def palin(x):
s=str(x)
if s==s[::-1]:
return True
else:
return False
n=int(input("Enter the number"))
# Putting up range from the next number till 15 digits
for i in range(n+1,int(10e14)):
if palin(i) is True:
print(i)
break
A brute force method:
def math(n):
while not var:
n += 1
if str(n) == str(n)[::-1] : f = 'but next is : '+str(n); return f
n = int(input()); t = math(n); print('Yes',t) if str(n) == str(n)[::-1] else print('No',t); global var; var = False
This is a good fast solution. I saw that the other solutions were iterating and checking through every +1 they did, but this is really slow for big numbers.
This solution has O(n) time if you look at the length of the number
beginNumber = 123456789101112131415161718 #insert number here for next palidrome
string = str(beginNumber + 1)
length = len(string)
number= [int(x) for x in list(string)]
for i in range(length//2):
if (number[i] != number[length-1-i]):
if (number[i]<number[length-1-i]):
number[length-2-i] += 1
number[length-1-i] = number[i]
print("".join([str(x) for x in number]))
I have written this for finding next pallindrome number given a pallindrome number..
#given a pallindrome number ..find next pallindrome number
input=999
inputstr=str(input)
inputstr=inputstr
#append 0 in beginning and end of string ..in case like 99 or 9999
inputstr='0'+inputstr+'0'
length=len(inputstr)
halflength=length/2;
#if even length
if(length%2==0):
#take left part and reverse it(which is equal as the right part )
temp=inputstr[:length/2]
temp=temp[::-1]
#take right part of the string ,move towards lsb from msb..If msb is 9 turn it to zero and move ahead
for j,i in enumerate(temp):
#if number is not 9 then increment it and end loop
if(i!="9"):
substi=int(i)+1
temp=temp[:j]+str(substi)+temp[j+1:]
break;
else:
temp=temp[:j]+"0"+temp[j+1:]
#now you have right hand side...mirror it and append left and right part
output=temp[::-1]+temp
#if the length is odd
if(length%2!=0 ):
#take the left part with the mid number(if length is 5 take 3 digits
temp=inputstr[:halflength+1]
#reverse it
temp=temp[::-1]
#apply same algoritm as in above
#if 9 then make it 0 and move on
#else increment number and break the loop
for j,i in enumerate(temp):
if(i!="9"):
substi=int(i)+1
temp=temp[:j]+str(substi)+temp[j+1:]
break;
else:
temp=temp[:j]+"0"+temp[j+1:]
#now the msb is the middle element so skip it and copy the rest
temp2=temp[1:]
#this is the right part mirror it to get left part then left+middle+right isoutput
temp2=temp2[::-1]
output=temp2+temp
print(output)
similarly for this problem take the left part of given number ...reverse it..store it in temp
inputstr=str(number)
if(inputstr==inputstr[::-1])
print("Pallindrome")
else:
temp=inputstr[:length/2]
temp=temp[::-1]
for j,i in enumerate(temp):
if(i!="9"):
substi=int(i)+1
temp=temp[:j]+str(substi)+temp[j+1:]
break;
else:
temp=temp[:j]+"0"+temp[j+1:]
now depending on length of your number odd or even generate the output..as in the code
if even then output=temp[::-1]+temp
if odd then temp2=temp1[1:]
output=temp2[::-1]+temp
I am not sure about this solution..but hope it helps

Categories