Python3: The Fraction - python-3.x

from fractions import Fraction
from functools import reduce
def product(fracs): ## fracs is a list of Fraction objects from the subsequent function call
t = Fractions(reduce(lambda x,y: x.numerator * y.numerator,fracs), reduce(lambda x,y: x.denominator * y.denominator, fracs))
return t.numerator, t.denominator
if __name__ == '__main__':
fracs = []
for _ in range(int(input())):
fracs.append(Fraction(*map(int, input().split())))
result = product(fracs)
print(*result)
I'm trying to multiply a series of fractions together using Python3 functool's Fraction function. The problem i have is with the denominator perimeter for the t variable in the product(fracs) function. Upon testing with the following test case:
3
1 2
3 4
10 6
5 1
The output was 5 1. The numerator seem to work fine but broke down for the denominator. I am aware and have found alternative solutions to my problem however i am hoping to get this mystery solved. I've ran it through python tutor but i couldn't decipher the code's behavior.

I think it's how you are using reduce. The first time it's called you are passing two Fraction objects:
Fraction(1,2).denominator * Fraction(3,4).denominator
which returns 8 and is what you expect. However, the reduce function is not making this 8 a fraction so the next call to reduce looks like this:
8.denominator * Fraction(10,6).denominator
Which is 6 not the expected 48. This problem doesn't exist for the numerator because for an Int X:
X = X.numerator
Therefore you get 30 in the numerator and 6 in the denominator which reduces to 5.
I'm not familiar with the Fraction class but it seems like you might be reinventing the wheel a bit.
I suspect you can just multiply the fraction objects and it's multiplication operator is overloaded:
def product(fracs):
return reduce(lambda x,y: x * y, fracs)

Related

What is the most efficient way print first K digits of a factorial without calculating the whole factorial?

My K has to be around 15,
and the number of which i am tring to get first k of its factorial is ~10^9.
Essentially I need to compute first 15 digits of n! where <= 1000000000 in under a second or so.
Everyone says its easy in python but I am still not able to .
My attempt using Stirlings approximation is only printing first 4 digits correctly. Let alone efficiency. :'(
import * from decimal
import *from math
getcontext().prec = 100
n = int(input())
x = Decimal("10") ** Decimal(str(Decimal(str(n)) * Decimal(str(n)).log10() - Decimal(str(n)) * Decimal(e).log10()))
print(x * Decimal(Decimal("2") * Decimal(str(n)) * Decimal(pi)).sqrt())
Tried increasing precision of Decimal more but doesnt make any difference.

why is np.exp(x) not equal to np.exp(1)**x

Why is why is np.exp(x) not equal to np.exp(1)**x?
For example:
np.exp(400)
>>>5.221469689764144e+173
np.exp(1)**400
>>>5.221469689764033e+173
np.exp(400)-np.exp(1)**400
>>>1.1093513018771065e+160
This is optimisation of numpy that raise this diff.
Indeed, you have to understand how is calculated the Euler number in math:
e = (1/n)**n with n == inf.
I think numpy stop at a certain order:
You have in the numpy exp documentation here that is not very clear about how the Euler number is calculated.
Because of this order that is not equal to infinity, you have this small difference in the two calculations.
Indeed the value np.exp(400) is calculated using this: (1 + 400/n)**n
>>> (1 + 400/n)**n
5.221642085428121e+173
>>> numpy.exp(400)
5.221469689764144e+173
Here you have n = 1000000000000 wich is very small and raise this difference at 10e-5.
Indeed there is no exact value of the Euler number. Like Pi, you can only have an approched value.
It looks like a rounding issue. In the first case it's internally using a very precise value of e, while in the second you get a less precise value, which when multiplied 400 times the precision issues become more apparent.
The actual result when using the Windows calculator is 5.2214696897641439505887630066496e+173, so you can see your first outcome is fine, while the second is not.
5.2214696897641439505887630066496e+173 // calculator
5.221469689764144e+173 // exp(400)
5.221469689764033e+173 // exp(1)**400
Starting from your result, it looks it's using a value with 15 digits of precision.
2.7182818284590452353602874713527 // e
2.7182818284590450909589085441968 // 400th root of the 2nd result

Why does this n choose r python code not work?

These 2 variations of n choose r code got different answer although followed the correct definition
I saw that this code works,
import math
def nCr(n,r):
f = math.factorial
return f(n) // f(r) // f(n-r)
But mine did not:
import math
def nCr(n,r):
f = math.factorial
return int(f(n) / (f(r) * f(n-r)))
Use test case nCr(80,20) will show the difference in result. Please advise why are they different in Python 3, thank you!
No error message. The right answer should be 3535316142212174320, but mine got 3535316142212174336.
That's because int(a / b) isn't the same as a // b.
int(a / b) evaluates a / b first, which is floating-point division. And floating-point numbers are prone to inaccuracies, roundoff errors and the like, as .1 + .2 == 0.30000000000000004. So, at some point, your code attempts to divide really big numbers, which causes roundoff errors since floating-point numbers are of fixed size, and thus cannot be infinitely precise.
a // b is integer division, which is a different thing. Python's integers can be arbitrarily huge, and their division doesn't cause roundoff errors, so you get the correct result.
Speaking about floating-point numbers being of fixed size. Take a look at this:
>>> import math
>>> f = math.factorial
>>> f(20) * f(80-20)
20244146256600469630315959326642192021057078172611285900283370710785170642770591744000000000000000000
>>> f(80) / _
3.5353161422121743e+18
The number 3.5353161422121743e+18 is represented exactly as shown here: there is no information about the digits after the last 3 in 53...43 because there's nowhere to store it. But int(3.5353161422121743e+18) must put something there! Yet it doesn't have enough information. So it puts whatever it wants to so that float(int(3.5353161422121743e+18)) == 3.5353161422121743e+18.

How can I solve finding consecutive factors problem in an optimal way?

I need to develop a function which finds consecutive factors of the given number and then the function will return the smallest of these consecutive numbers.
I tried to solve a Codility question. (I submitted my solution)
I need to develop the solution function.
def solution(N):
# write your code in Python 3.6
pass
An example:
If N is 6, the function will return 2 (because of 6 = 2 * 3)
If N is 20, the function will return 4 (because of 20 = 4 * 5)
If N is 29, the function will return 0
I developed the solution function (by checking all the numbers from 1 up to N, brute force search) and it works.
However, when the argument of the solution function is too big, the execution of the function takes too much time. Codility Python engine is running the function for a while and then it is throwing TIMEOUT ERROR.
What may be an optimal solution for this problem?
Thank you
I developed the function but it is not optimized.
def solution(N):
for i in range(1,N+1):
if i * (i+1) == N:
return i
return 0
When N is too big like 12,567,543, the function execution takes too much time.
After my comment, I thought a little bit about the question.
If you have an integer, N, and two consecutive factors, m and m+1, then it MUST be true that m < sqrt(N) and m + 1 > sqrt(N)
Therefore, all you have to do is check if the floor of the square root times the ceiling of the square root is equal to your original number..
import math
def solution(N):
n1 = math.floor(math.sqrt(N))
n2 = n1 + 1 # or n2 = math.ceil(math.sqrt(N))
if n1*n2 == N:
return n1
return 0
This has a run time of O(1).
import math
import math
def mysol(n):
s = math.sqrt(n)
if math.floor(s) * math.ceil(s) == n:
return math.floor(s)
else:
return 0

how to get fraction as it is ( without getting itssimplest fraction )? i vainly tried using this:

x=7
y=14
from fractions import Fraction
print(Fraction(7/14))
I got answer 1/2 but I needed 7/14. is there any way to write as it is without using string?
Most fraction libraries will simplify the numerator and denominator as soon as they are created as a performance optimization. If you are working with large unsimplified fractions there is a chance that they will overflow. So before each operation the fractions will have to be simplified anyway.
If you want to keep the original numerator and denominator intact you should create your own wrapper class like so:
class MyFraction:
def __init__(self, numerator=1, denominator=1):
self.numerator = numerator
self.denominator = denominator
def get_fraction(self):
from fractions import Fraction
return Fraction(numerator=self.numerator, denominator=self.denominator)
def __repr__(self):
return '{}/{}'.format(self.numerator, self.denominator)
f = MyFraction(numerator=7, denominator=14)
print(f) # prints 7/14
print(f.get_fraction()) # prints 1/2
Note: You should be invoking fraction using the Fraction(numerator=0, denominator=1) constructor.
Is your case what is happening is:
Fraction(7/14) => Fraction(0.5) => 1/2

Resources