Skip to content

Commit

Permalink
fractions concept
Browse files Browse the repository at this point in the history
  • Loading branch information
colinleach committed Nov 26, 2023
1 parent 1cd88ed commit d6d5f7a
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 0 deletions.
5 changes: 5 additions & 0 deletions concepts/fractions/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"blurb": "The fractions module enables working with rational numbers, which preserve exact values and avoid the rounding errors common with floats.",
"authors": ["bethanyg", "cmccandless", "colinleach"],
"contributors": []
}
101 changes: 101 additions & 0 deletions concepts/fractions/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# About

The [`Fractions`][fractions] module allows us to handle `rational numbers`: fractions with an integer numerator divided by an integer denominator.
For example, we can store `2/3` as an exact fraction instead of the approximate `float` value `0.6666...`

## Creating

The constructor is quite flexible.
Most obviously, it can take take two integers.
Common factors are removed, to convert the fraction to its "lowest form": the smallest integers that accurately represent the fraction.

```python
>>> from fractions import Fraction

>>> f1 = Fraction(2, 3) # 2/3
>>> f1
Fraction(2, 3)

>>> f2 = Fraction(6, 9)
>>> f2
Fraction(2, 3) # automatically simplified

>>> f1 == f2
True
```

It can also parse a string representation of the fraction:

```python
>>> f3 = Fraction('2/3')
>>> f3
Fraction(2, 3)
```

It can work with `float` parameters, but this may run into problems with the approximate nature of representing the decimal value interally as binary.
For a more reliable result, there is the `limit_denominator()` method.
This can take an integer parameter if you have specific requirements, but even the default can work well.

```python
>>> Fraction(1.2)
Fraction(5404319552844595, 4503599627370496)

>>> Fraction(1.2).limit_denominator()
Fraction(6, 5)
```

## Arithmetic

The usual arithmetic operators `+ - * / **` work with fractions.
Integers and other `Fraction`s can be included and give a `Fraction` result.
Including a `float` results in `float` output.

```python
>>> Fraction(2, 3) + Fraction(1, 4) # addition
Fraction(11, 12)

>>> Fraction(2, 3) * Fraction(6, 5) # multiply fractions
Fraction(4, 5)

>>> Fraction(2, 3) * 6 / 5 # fraction with integers
Fraction(4, 5)

>>> Fraction(2, 3) * 1.2 # fraction with float -> float
0.7999999999999999

>>> Fraction(2, 3) ** 2 # exponentiation with integer
Fraction(4, 9)
```

## Conversions

Fractions are great for preserving precision during intermediate calculations, but may not be what you want for the final output.

It is possible to get the numerator and denominator individually or as a tuple:

```python
>>> Fraction(2, 3).numerator
2
>>> Fraction(2, 3).denominator
3
>>> Fraction(2, 3).as_integer_ratio()
(2, 3)
```

Various standard Python functions also give the expected result:

```python
>>> round(Fraction(11, 3))
4

>>> from math import floor, ceil
>>> floor(Fraction(11, 3))
3
>>> ceil(Fraction(11, 3))
4

>>> float(Fraction(11, 3))
3.6666666666666665
```

[fractions]: https://docs.python.org/3/library/fractions.html
101 changes: 101 additions & 0 deletions concepts/fractions/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Introduction

The [`Fractions`][fractions] module allows us to handle `rational numbers`: fractions with an integer numerator divided by an integer denominator.
For example, we can store `2/3` as an exact fraction instead of the approximate `float` value `0.6666...`

## Creating

The constructor is quite flexible.
Most obviously, it can take take two integers.
Common factors are removed, to convert the fraction to its "lowest form": the smallest integers that accurately represent the fraction.

```python
>>> from fractions import Fraction

>>> f1 = Fraction(2, 3) # 2/3
>>> f1
Fraction(2, 3)

>>> f2 = Fraction(6, 9)
>>> f2
Fraction(2, 3) # automatically simplified

>>> f1 == f2
True
```

It can also parse a string representation of the fraction:

```python
>>> f3 = Fraction('2/3')
>>> f3
Fraction(2, 3)
```

It can work with `float` parameters, but this may run into problems with the approximate nature of representing the decimal value interally as binary.
For a more reliable result, there is the `limit_denominator()` method.
This can take an integer parameter if you have specific requirements, but even the default can work well.

```python
>>> Fraction(1.2)
Fraction(5404319552844595, 4503599627370496)

>>> Fraction(1.2).limit_denominator()
Fraction(6, 5)
```

## Arithmetic

The usual arithmetic operators `+ - * / **` work with fractions.
Integers and other `Fraction`s can be included and give a `Fraction` result.
Including a `float` results in `float` output.

```python
>>> Fraction(2, 3) + Fraction(1, 4) # addition
Fraction(11, 12)

>>> Fraction(2, 3) * Fraction(6, 5) # multiply fractions
Fraction(4, 5)

>>> Fraction(2, 3) * 6 / 5 # fraction with integers
Fraction(4, 5)

>>> Fraction(2, 3) * 1.2 # fraction with float -> float
0.7999999999999999

>>> Fraction(2, 3) ** 2 # exponentiation with integer
Fraction(4, 9)
```

## Conversions

Fractions are great for preserving precision during intermediate calculations, but may not be what you want for the final output.

It is possible to get the numerator and denominator individually or as a tuple:

```python
>>> Fraction(2, 3).numerator
2
>>> Fraction(2, 3).denominator
3
>>> Fraction(2, 3).as_integer_ratio()
(2, 3)
```

Various standard Python functions also give the expected result:

```python
>>> round(Fraction(11, 3))
4

>>> from math import floor, ceil
>>> floor(Fraction(11, 3))
3
>>> ceil(Fraction(11, 3))
4

>>> float(Fraction(11, 3))
3.6666666666666665
```

[fractions]: https://docs.python.org/3/library/fractions.html
6 changes: 6 additions & 0 deletions concepts/fractions/links.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{
"url": "https://docs.python.org/3/library/fractions.html/",
"description": "Documentation for the Fractions module."
}
]
5 changes: 5 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2567,6 +2567,11 @@
"uuid": "565f7618-4552-4eb0-b829-d6bacd03deaf",
"slug": "with-statement",
"name": "With Statement"
},
{
"uuid": "000e7768-38b9-4904-9ae2-9a4e448f366c",
"slug": "fractions",
"name": "Fractions"
}
],
"key_features": [
Expand Down

0 comments on commit d6d5f7a

Please sign in to comment.