This question already has answers here:
Why does integer division yield a float instead of another integer?
(4 answers)
Closed 3 years ago.
I have created a small Python program in repl.it to illustrate the Collatz Conjecture, which says that if you start with any positive integer number n and you apply the following operations recursively: n/2 if n is even, 3n+1 if n is odd, you will always reach 1.
This is the code:
invalid_input = 0
while(invalid_input == 0):
n = input("Give me a positive integer: ")
try: #check for positive integer. If it cannot do int(n) it means a string was entered, and it goes to except.
if(int(n)>0):
invalid_input = 1 #this is to tell the while loop above that the right input was entered
print("Thank you.")
print("Now loading:")
else: #an integer was entered, but it was negative
print("Please enter a positive integer")
except: #a string was entered
print("Please enter a positive integer")
n=int(n)
nentered = n #this will keep track of the initial n
npeak = n #this will keep track of the highest n reached
iteration = 1 #this will keep track of the number of iterations
iterationmax = 1 #this will keep tack of the iteration at which npeak was reached
while(n != 1):
print("%5i: %5i" % (iteration,n))
if(n % 2 == 0): #divide by 2 if even
n=n/2
else: #if it is odd, multiply by 3 and add 1
n=3*n+1
iteration = iteration + 1
if(n>npeak): #record the higher n and its iteration
npeak = n
iterationmax = iteration
It works. But there is a problem: if the entered number is big enough, for example 6666666666666666666666666, then it does something really strange. This is what I get:
Give me a positive integer: 6666666666666666666666666
Thank you.
Now loading:
1: 6666666666666666666666666
2: 3333333333333333277409280
3: 1666666666666666638704640
4: 833333333333333319352320
5: 416666666666666659676160
6: 208333333333333329838080
7: 104166666666666664919040
8: 52083333333333332459520
9: 26041666666666666229760
10: 13020833333333333114880
etc
As you can see, I am expecting the second number to be exactly 3333333333333333333333333, but instead I am getting different numbers at the end.
As another example, entering 1000000000000000000000000 returns 499999999999999991611392 in the second iteration.
What could be the reason for this?
The reason of why what #ruohola said is true, is because when you use floating-point division with a single /, what happens is that a floating-point number is created. However, it cannot be represented as the number is so large, so it is rounded to the closest most accurate representation. So you will have to use // instead of /.
However, using //, is integer division. This results in an integer which can be represented much easier than a high float.
A very similar question can be found here, it contains some more explanation.
Change your / operation to be //, so that they don't result in (inaccurate) floating point values.
So this:
if(n % 2 == 0): #divide by 2 if even
n=n/2
Should be:
if(n % 2 == 0): #divide by 2 if even
n=n//2
Or as properly formatted by Python conventions:
if n % 2 == 0:
n //= 2
Related
The output shows a different result. Yes, the factorials of those numbers are right but the numbers outputted aren't right.
Here's the code:
input:
n = int(input("Enter a number: "))
s = 0
fact = 1
a = 1
for i in range(len(str(n))):
r = n % 10
s += r
n //= 10
while a <= s:
fact *= a
a += 1
print('The factorial of', s, 'is', fact)
Output:
Enter a number: 123
The factorial of 3 is 6
The factorial of 5 is 120
The factorial of 6 is 720
You're confusing yourself by doing it all in one logic block. The logic for finding a factorial is easy, as is the logic for parsing through strings character by character. However, it is easy to get lost in trying to keep the program "simple," as you have.
Programming is taking your problem, designing a solution, breaking that solution down into as many simple, repeatable individual logic steps as possible, and then telling the computer how to do every simple step you need, and what order they need to be done in to accomplish your goal.
Your program has 3 functions.
The first is taking in input data.
input("Give number. Now.")
The second is finding individual numbers in that input.
for character in input("Give number. Now."):
try:
int(character)
except:
pass
The third is calculating factorials for the number from step 2. I won't give an example of this.
Here is a working program, that is, in my opinion, much more readable and easier to look at than yours and others here. Edit: it also prevents a non numerical character from halting execution, as well as using only basic Python logic.
def factorialize(int_in):
int_out = int_in
int_multiplier = int_in - 1
while int_multiplier >= 1:
int_out = int_out * int_multiplier
int_multiplier -= 1
return int_out
def factorialize_multinumber_string(str_in):
for value in str_in:
print(value)
try:
print("The factorial of {} is {}".format(value, factorialize(int(value))))
except:
pass
factorialize_multinumber_string(input("Please enter a series of single digits."))
You can use map function to get every single digit from number:
n = int(input("Enter a number: "))
digits = map(int, str(n))
for i in digits:
fact = 1
a = 1
while a <= i:
fact *= a
a += 1
print('The factorial of', i, 'is', fact)
Ok, apart from the fact that you print the wrong variable, there's a bigger error. You are assuming that your digits are ever increasing, like in 123. Try your code with 321... (this is true of Karol's answer as well). And you need to handle digit zero, too
What you need is to restart the calculation of the factorial from scratch for every digit. For example:
n = '2063'
for ch in reversed(n):
x = int(ch)
if x == 0:
print(f'fact of {x} is 1')
else:
fact = 1
for k in range(2,x+1):
fact *= k
print(f'fact of {x} is {fact}')
So, I wrote a code to find if a number is PRIME or NOT...
I wrote it in 2 different ways, they are almost same but I just had a doubt. So here it is:
1st code:
num = int(input("Enter the number: "))
lim = num//2 + 1
for i in range(2,lim):
if num % i == 0:
print("Prime!")
break
else:
print("Not Prime!")
2nd Code:
num = int(input("Enter the number: "))
for i in range(2,num):
if num % i == 0:
print("Prime!")
break
else:
print("Not Prime!")
The 1st code takes the input(num) and according to the input sets a limit(which is the half number + 1)
and then checks if the num is divisible by all the numbers in range (2 to lim)
The second one is same but instead of setting a limit it just checks all numbers lower than the input, which means it has to do a little more work...
Now both of these are almost same, the only difference is I saved a line in 2nd one and output efficiency is also better!
Which code would you want me to prefer/
also if this code has any problems, pointing them out would be helpful!
Thanks :)
Explanation
The most important piece of iteration, namely determining whether a number is prime or not, is to keep track of it. Without this process and in the OP's program, a variable is not used to handle this, meaning that he checks whether a number is or isn't prime every single time and concludes at that point. He also uses an else statement which is syntactically incorrect.
To prevent this, we can use a variable to keep track of this. Let's call it isprime. We need to assume that a number will always be a prime unless otherwise said. This can be achieved by setting isprime to default be True, and setting it to be False when we conclude that it is not a prime, because is has a divisor. Finally, we can check this variable at the end and determine whether that number is a prime or not, because it would be set to False if not, or left as True if it is.
Another observation made is that the limit for determining primes can be reduced down to sqrt(n). This is because we do not need to find every factor if it exists, just its lowest corresponding factor. Let's look at an example:
Factors of 24: 2, 3, 4, 6, 8, 12
We can stop checking for the factors right here:
2, 3, 4 | 6, 8, 12, 24
This is because if a number has a factor (such as greater than the square root), it will have a corresponding factor less than the square root. As a result, we can set our limit to be sqrt(n), just for peace of mind + a time complexity of O(sqrt(n)) v. O(n).
As an extra note, sqrt is not inbuilt into Python. You will have to import it from the math library using:
from math import sqrt
Final Code
# Setup
num = int(input("Enter the number: "))
lim = sqrt(num)
isprime = True
# Loop & check
for i in range(2,lim):
if num % i == 0:
isprime = False
break
# Results
if isprime:
print("Prime!")
else:
print("Not prime!")
The logic of the solution is wrong. You gave to switch the "Prime" and "Not Prime" tags. Like follows;
num = int(input("Enter the number: "))
lim = num//2 + 1
for i in range(2,lim):
if num % i == 0:
print("Not Prime!")
break
else:
print("Prime!")
The solution 1 is more efficient because you do not need to do extra
computation to check num//2 + 1. So it is preferable.
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 2 years ago.
This is a simple code I wrote in Python for telling if the input is odd or even. It is also probably redundant in some parts(I was just trying so that the program doesn't crash for any input).
try:
num = input("Please,\nenter your integer to check if it's odd or even: ")
rem = float(num) % 2
if rem == 0:
print("Your number", int(num), "belongs to the set of even integers!")
elif rem == 1:
print("Your number", int(num), "belongs to the set of odd integers!")
else:
print("Your number", num, "does not belong to the set of integers!")
except ValueError:
print("Your input does not belong to the set of integers!")
Such a simple operation gives a wrong result for a 17 digit number. For example
Please,
enter your integer to check if it's odd or even: 49761934591459137
Your number 49761934591459137 belongs to the set of even integers!
Why is this happening, when python can even perform tetration(repeated exponentiation) of 2 upto 5 times(which is a 19,729 digit number)?
You converted the number to float so this is what happens
number_str = 49761934591459137
print(float(number_str))
>> 4.976193459145914e+16
It gets rounded, if you convert it to integer again you get this
print(int(float(number_str)))
>> 49761934591459136
So the last digit was converted from 7 to 6.
This happens because the float representation in bytes has one part for the exponent and other for the base, which means the least significant digits lose precision on bigger numbers.
You can fix your code by casting the number to integer
rem = int(num) % 2
but a smarter approach would only get the last digit and see if its divisible by 2
rem = int(num[-1]) % 2
So you can write an input of arbitrary length
I am trying to count the number of digits of an input. However, whenever I input 10 or 11 or any two digit number, the output is 325. Why doesn't it work?
inputnumber = int(input())
countnumber = inputnumber
digitcount = 0
while countnumber > 0:
digitcount += 1
countnumber = countnumber/10
print(digitcount)
# result is 325 when input is 10 or 11
Your error mainly happened here:
countnumber=countnumber/10
Note that you are intending to do integer division. Single-slash division in Python 3 is always "float" or "real" division, which yields a float value and a decimal part if necessary.
Replace it with double-slash division, which is integer division: countnumber = countnumber // 10. Each time integer division is performed in this case, the rightmost digit is cut.
You also have to watch out if your input is 0. The number 0 is considered to be one digit, not zero.
I would not convert that beautiful input to int to be honest.
print(len(input())
would be sufficient.
An easily understandable one liner that no one can complain about.
But of course, if negative sign bothers you like wisty said,
len(str(abs(int (v))))
will be safer for sure.
Again, if you are worried about the non numeric inputs like mulliganaceous said, you better cover that case.
str = input()
if str.isnumeric():
print(len(str(abs(v))))
else:
print("bad input")
The reason is that in python 3 the division of two integers yields a floating point number. It can be fixed using the // operator:
number = int(input())
digits_count = 0
while number > 0:
digits_count += 1
number = number // 10
You must be using Python3, logically your function is right. You just have to change
countnumber = countnumber // 10
because Python3, // is floor division, meanwhile / is true division.
>>>print(1 / 10)
0.1
>>>print(1 // 10)
0
Btw, as #chrisz said above, you can just simply using the len() function to get the number of digits of the input
>>>print(len(input())
num = int(input())
count = 0
while num > 0:
count += 1
num = num // 10
print(count)
def digits(number):
number = str(number)
lenght = len(number)
return lenght
print(digits(25)) # Should print 2
print(digits(144)) # Should print 3
print(digits(1000)) # Should print 4
print(digits(0)) # Should print 1
This question already has answers here:
Implementing the collatz function using Python
(8 answers)
Closed 5 years ago.
Note: I was trying to figure out why my while statement did not evaluate to False when the integer was, so I don't believe this is a duplicate
Doing an automating the boring stuff exercise in python where the program receives an input and reduces it to 1 using the following algorithm.
#even / 2
#odd * 3 + 1
def collatz():
print("Enter number:")
number = input()
try:
data = int(number) # Input Validation
while int(data) != 1:
if data % 2 == 0: #Number is even
data = int(data/2)
print(data)
if data % 2 == 1: # Number is odd
data = int(3*data+1)
print(data)
except:
print("Please input a valid value")
collatz()
collatz()
Instead of the while loop breaking, when the number is reduced to 1. The loop continues and it multiplies 1 by 3 and adds 1(Just as normal odd number). Btw many int conversions were done as I thought it may have returned a floating point.
So please tell me where are the unncessary int conversions and how to break it using a while statement. Any cleanup to code is appreciated
There are a few things that you should neaten up to make your code work properly and just generally better:
Rename data to n, this isn't going to make much of a difference, but I would say it just makes more sense.
There is no need to do endless conversions to int, n only needs to be converted from a string to an integer once.
Don't put your entire code in a function then call it once, instead have the main algorithm in a smaller function which you then can call from the main body of your code or even create another function to call the algorithm which handles the inputting side of things.
Use the integer division operator (//) instead of the floating point divider (/), since the number will be even, you can be sure that the decimal place will be 0.
You don't need to check if n % 2 is 0 and then on the next line check if it n % 2 is 1, you can just use an if ... else clause.
And that's about it! Here's what it looks like:
#even / 2
#odd * 3 + 1
def collatz(n):
while n != 1:
if n % 2 == 0: #Number is even
n = n // 2
else:
n = n * 3 + 1
print(n)
number = input("Enter number:")
try:
number = int(number)
collatz(number)
except ValueError:
print("Please input a valid value")
And a test shows it works (input of 24):
12
6
3
10
5
16
8
4
2
1