Python 3, context based division - python

I'm trying to find out if numbers divide cleanly by seeing if they divide into a float or an int, for example:
10/2 = 5
10/3 = 3.333
The problem is, as I understand it, you can either use / and get ONLY float results or use // and get ONLY int results. I'm trying to figure out a way to see if some number n is prime.
The idea I had was to see if all numbers between 1 and n-1 divide into floats, as that would mean none of them divide cleanly.
This is an exercise gauging my ability for an introductory course, I realize there may be some library I can import but I'm supposed to solve this problem using methods that are at my level and importing libraries isn't.
So I was wondering if theres a way to use a divison which will return the true type of the answer, if such a question even makes sense.

To see if a number "divides cleanly", you want to use the %1 operator:
10 % 3 # 1
11 % 3 # 2
12 % 3 # 0
Clearly if a divides b "cleanly", then the result is of b % a is 0.
1Modulus operator

Related

Python Decimal Calculation Is Not Precise

The result of 1 / 9 * 9 should equal 1. However, Python returns 0.99999999999...
from decimal import Decimal
import decimal
decimal.getcontext().rounding = decimal.ROUND_HALF_UP
decimal.getcontext().prec = 256
dec1 = Decimal('1')
dec9 = Decimal('9')
dec_result = dec1 / dec9 * dec9
print(type(dec_result))
print(dec_result)
I need a precise method for calculations,; hence, the usage of decimal vs. float.
Can anybody suggest a fix? Thanks...
explanation of why this happens:
This is not a precession error from python's decimal module.
Many calculating machines and many other programming languages behave the same way. Grab an old calculator, divide 1 by 9 and multiply it again by 9. You'll get the 0.9999999 that you got from python.
We, as humans can determine that the exact result is equal to one by simplifying the fraction 1 * 9 / 9 = 1. But many digital calculating machines calculate the operation by going through each element one by one, basically dividing the operation into smaller operations. So for a computer, 1 / 9 * 9 is going to be like this: Calculate 1 divided by 9. Multiply the result by 9. If you do the calculation by hand, going through each sub-operation one by one, you'll get the same result.
However: Even though from my perspective, 0.9999999 result is much accurate, many modern calculators and many modern programming languages such as Python, JS, Java, C++ and even C handles this problem with their primitive data types. That mean's that if you are using primitive data types of those programming languages, double and float, you don't need to worry about this sort of precession problems. I tested both JS and Python and got similar results.
Python 3.8
>>> a = 1.0
>>> b = 9.0
>>> a / b * b
1.0
It seems like the problem of accuracy is within the Decimal module itself
Normally doing this operation
1/9 * 9
Will give us the result as 1.0
I Recomend You To Go With The Normal Division Itself

Divide values in Python

I made a xlrd to json parsing script, which doesn't divide variables. It always returns zero... the code which I am using to divide the variables is:
if not row_values[2]:
key['nr_one'] = 0
else:
key['nr_one'] = int(row_values[2])
if not row_values[4]:
key['nr_two'] = 0
else:
key['nr_two'] = int(row_values[4])
try:
key['perc'] = float(key['nr_two']/key['nr_one']*100)
except ZeroDivisionError:
key['perc'] = 0
I have printed the following code at the end of the script:
print('one')
print(key['nr_one'])
print('two')
print(key['nr_two'])
print('perc')
print(key['perc'])
This returns:
one
103386547
two
135680054
perc
0.0
So. I don't understand why the division fails and returns 0? Could someone please help me format a good way to calculate the percentage
it should be float(key['nr_two']) /key['nr_one']*100
Integer division is like this :
1/3 #=> 0
The easiest way to understand this result is not as a fraction, but as the answer to the question "How many times do 3 fit in 1?".
So 0 multiplied by 100 is still :
1/3 * 100 #=> 0
You need
100.0*1/3 #=> 33.333333
For your code :
key['perc'] = 100.0*key['nr_two']/key['nr_one'] (without using float(...))
It returns :
76.1987808465937
NOTE: You really need to type 100.0 (a float), not just 100 (an int). You'd get 76 otherwise.
key['nr_two'] is integer and so is key['nr_one']. So when they are divided, the result is forced to be an integer in Python 2x versions (in Python 3x this limitation does not exist and your code would run just fine). What you therefore get, is 0, which is later multiplied by 100, so still 0 but float, 0.0.
To achieve float division in python 2.x you can just add:
from __future__ import division
This way you will not need to convert your numbers each time you divide them.

Division & Modulo Operator

I just started learning how to code, and I've been assigned a problem that I've been stuck on for many hours now and was hoping I could receive some hints at the very least to solve the problem. The main point of this exercise is to practice division and modulus. We can use basic statements, but nothing fancy like conditionals or anything since we haven't gotten to that point.
I need a user to input a # from 1 - 25, and then my program will let them know which unit and row that number is in. I've managed to get the code working for the rows, but I cannot figure out how to get the unit number.
Here's my code:
shelfNumber = int(raw_input('What is the shelf number? '))
row = int(shelfNumber / 5.1) + 1
unit =
I've tried a lot of things for unit, but none of them worked out, so I left it blank. I would appreciate any hints that anyone can give me. Thank you for any help.
Edit: I realized that I should try and at least show which ideas I've tried. If I do a regular modulo with # % 5, that works for everything but the multiples of 5 all the way on the right. I've also tried implementing the row #'s each # has but haven't gotten anywhere with that either. I've also tried something similar by dividing by a decimal, casting it as an int, then using modulo but failed, etc., etc.\
Edit: Sorry, I realized I uploaded the wrong image.
This problem would be easier if everything were countrd from 0 instead of from 1. That is, if the row and unit numbers were 0 to 4 instead of 1 to 5 and if the input value were 0 to 24 instead of 1 to 25.
In that case, we'd just write:
row = shelfNumber / 5
unit = shelfNumber % 5
Since everything starts ftom 1 ("is one-indexed" in the usual jargon), shelfNumber is one bigger than what that formula needs, and we need to make row and unit one bigger than what we computed.
But there's no trouble fixing that:
row = (shelfNumber - 1) / 5 + 1
unit = (shelfNumber - 1) % 5 + 1
In Python 3, you'd need to write // insted of /, and that will work with a reasonably recent Python 2.

Python find smallest multiple of numbers from 1-20. What is the issue in my code?

Yes, it's Euler problem 5. I'm new to python and I'm trying to solve a couple of problems to get used to the syntax. And yes I know that there are other question regarding the same problem, but I have to know why my code is not working:
import sys
def IsEvDivBy1to20(n):
for i in range(1,21):
if n%i!=0:
return 0
return 1
SmallMultiple = 0
for i in range(sys.maxsize**10):
if IsEvDivBy1to20(i) == 1:
SmallMultiple = i
break
print(SmallMultiple)
It returns 0.
range() by default starts at 0. The first time through your loop, then, i is 0: and so the first time through your (horribly-named) function, the values being compared against are 0.
Your code fails because,
range(sys.maxsize**10)
The first value returned by range is 0 and every number between 1 and 21 divides 0 without leaving any remainder. So, 0 is considered as the solution.
Also: Euler problems are not about brute forcing, it's also about finding an efficient solution.
For example, if a number is evenly divisible by the numbers 1 - 20 you can simply multiply 1 * 2 * ... * 20 = ... to find an upper bound. This number would clearly satisfy the conditions but it's likely not the smallest number.
You can then reason as follows: if the number can be divided by 6 then it can also be divided by 2 and 3. So I don't really need to include 6 in the 1 * 2 * ... * 20 multiplication. You can repeatedly apply this reasoning to find a much smaller upper bound and work your way towards the final answer.

Python thinks Euler has identity issues (cmath returning funky results)

My code:
import math
import cmath
print "E^ln(-1)", cmath.exp(cmath.log(-1))
What it prints:
E^ln(-1) (-1+1.2246467991473532E-16j)
What it should print:
-1
(For Reference, Google checking my calculation)
According to the documentation at python.org cmath.exp(x) returns e^(x), and cmath.log(x) returns ln (x), so unless I'm missing a semicolon or something , this is a pretty straightforward three line program.
When I test cmath.log(-1) it returns πi (technically 3.141592653589793j). Which is right. Euler's identity says e^(πi) = -1, yet Python says when I raise e^(πi), I get some kind of crazy talk (specifically -1+1.2246467991473532E-16j).
Why does Python hate me, and how do I appease it?
Is there a library to include to make it do math right, or a sacrifice I have to offer to van Rossum? Is this some kind of floating point precision issue perhaps?
The big problem I'm having is that the precision is off enough to have other values appear closer to 0 than actual zero in the final function (not shown), so boolean tests are worthless (i.e. if(x==0)) and so are local minimums, etc...
For example, in an iteration below:
X = 2 Y= (-2-1.4708141202500006E-15j)
X = 3 Y= -2.449293598294706E-15j
X = 4 Y= -2.204364238465236E-15j
X = 5 Y= -2.204364238465236E-15j
X = 6 Y= (-2-6.123233995736765E-16j)
X = 7 Y= -2.449293598294706E-15j
3 & 7 are both actually equal to zero, yet they appear to have the largest imaginary parts of the bunch, and 4 and 5 don't have their real parts at all.
Sorry for the tone. Very frustrated.
As you've already demonstrated, cmath.log(-1) doesn't return exactly i*pi. Of course, returning pi exactly is impossible as pi is an irrational number...
Now you raise e to the power of something that isn't exactly i*pi and you expect to get exactly -1. However, if cmath returned that, you would be getting an incorrect result. (After all, exp(i*pi+epsilon) shouldn't equal -1 -- Euler doesn't make that claim!).
For what it's worth, the result is very close to what you expect -- the real part is -1 with an imaginary part close to floating point precision.
It appears to be a rounding issue. While -1+1.22460635382e-16j is not a correct value, 1.22460635382e-16j is pretty close to zero. I don't know how you could fix this but a quick and dirty way could be rounding the number to a certain number of digits after the dot ( 14 maybe ? ).
Anything less than 10^-15 is normally zero. Computer calculations have a certain error that is often in that range. Floating point representations are representations, not exact values.
The problem is inherent to representing irrational numbers (like π) in finite space as floating points.
The best you can do is filter your result and set it to zero if its value is within a given range.
>>> tolerance = 1e-15
>>> def clean_complex(c):
... real,imag = c.real, c.imag
... if -tolerance < real < tolerance:
... real = 0
... if -tolerance < imag < tolerance:
... imag = 0
... return complex(real,imag)
...
>>> clean_complex( cmath.exp(cmath.log(-1)) )
(-1+0j)

Categories

Resources