0

I’m writing in Python3. I created two lists in my code and I want to ‘connect’ them in a loop as fractions. Is there any possibility to do it in another way than using Fractions library? Unfortunately I can’t use it because it’s the task requirement. The problem comes up when fraction is a floating point number (for example 1/3). How can I solve this problem?

Here's an example:

p = [1,2,3]
q = [3,5,9]

frac = []
    for i in p:
      for j in q:
        f = i/j
        if f not in frac:
          frac.append(f)



olczig
  • 65
  • 6

4 Answers4

2

You can use the fractions.Fraction type.

  1. import this using: from fractions import Fraction
  2. cast your f equation f = p/q with Fraction; f = Fraction(p/q)
  3. then use the string conversion as well; f = str(Fraction(p/q))

    from fractions import Fraction
    f = str(Fraction(p/q))
    
triedit
  • 169
  • 1
  • 9
1

If I understood correctly your problem is not on "how to convert floats to fractions" but yes "how to get a string representation of fraction from arrays of numbers", right?

Actually you can do that in one line:

p = [1,2,3]
q = [3,5,9]

list(map(lambda pair: f"{pair[0]}/{pair[1]}", [(x, y) for x in p for y in q])))

Explaining:

map - receives a function and an iterator, passing each element of the iterator to that function.

[(x, y) for x in p for y in q] - this is a list comprehension, it is generating pairs of numbers "for each x in array p for each y in array q".

lambda pair - this is an anonymous function receiving an argument pair (which we know will be a tuple '(x, y)') and returns the string "x/y" (which is "pair[0]/pair[1]")

Optional procedures

Eliminate zeros in denominator

If you want to avoid impossible fractions (like anything over 0), the list comprehension should be this one:
[(x, y) for x in p for y in q if x != 0]

Eliminate duplicates

Also, if on top of that you want to eliminate duplicate items, just wrap the entire list in a set() operation (sets are iterables with unique elements, and converting a list to a set automatically removes the duplicate elements):
set([(x, y) for x in p for y in q if x != 0])

Eliminate unnecessary duplicate negative signs

The list comprehension is getting a little bigger, but still ok:
set([(x, y) if x>0 or y>0 else (-x,-y) for x in p for y in q if x != 0])
Explaining: if x>0 or y>0, this means that only one of them could be a negative number, so that's ok, return (x,y). If not, that means both of them are negative, so they should be positive, then return (-x,-y).

Testing

The final result of the script is:

p = [1, -1, 0, 2, 3]
q = [3, -5, 9, 0]

print(list(map(lambda pair: f"{pair[0]}/{pair[1]}", set([(x, y) if x>0 or y>0 else (-x,-y) for x in p for y in q if y != 0]))))


# output:
# ['3/-5', '2/-5', '1/5', '1/-5', '0/3', '0/9', '2/3', '2/9', '3/3', '-1/3', '-1/9', '0/5', '3/9', '1/3', '1/9'] 

Teodoro
  • 1,194
  • 8
  • 22
  • Yes, you're right. Thank you for solving my problem. How can I improve your solution to show for example -1/-6 as 1/6. Because in the case of negative numbers it's pointless to show "-" 2 times. – olczig May 26 '20 at 20:40
  • Just added this to the awnser, also I fixed a mistake on the first procedure (eliminate zeros over anything). It should be the opposite "anything over zero". – Teodoro May 26 '20 at 20:47
  • Thank you for your help! :) – olczig May 26 '20 at 21:02
  • Glad to help! If you could mark the answer as the correct one I would appreciate :) Good studying! – Teodoro May 26 '20 at 21:04
0

(0.33).as_integer_ratio() could work for your problem. Obviously 0.33 would be replaced by whatever float.

Per this question,

def float_to_ratio(flt):
    if int(flt) == flt:
        return int(flt), 1
    flt_str = str(flt)
    flt_split = flt_str.split('.')
    numerator = int(''.join(flt_split))
    denominator = 10 ** len(flt_split[1])
    return numerator, denominator

this is also a solution.

Johnny
  • 211
  • 3
  • 15
  • Thank you for this solution. How can I improve this code to show fractions in this way "1/3" not this "(1, 3)". – olczig May 26 '20 at 20:12
  • If you want the fractions to be in their simplest form, you can also divide both `numerator` and `denominator` by their `GCD` (Greatest Common Divisor) before returning. – Taimoor Zaeem Mar 06 '23 at 17:20
0

You can use a loop to figure out the fraction by the simple code below

x = 0.6725
a = 0
b = 1
while (x != a/b):
    if x > a/b:
        a += 1
    elif x < a/b:
        b += 1
print(a, b)

The result of a and b is going to be

269 400
Youstanzr
  • 605
  • 1
  • 8
  • 16