forked from cool-RR/python_toolbox
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmath_tools.py
More file actions
106 lines (80 loc) · 2.69 KB
/
math_tools.py
File metadata and controls
106 lines (80 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# Copyright 2009-2014 Ram Rachum.
# This program is distributed under the MIT license.
'''This module defines math-related tools.'''
from __future__ import division
import numbers
infinity = float('inf')
def get_sign(x):
'''Get the sign of a number.'''
if x > 0:
return 1
if x == 0:
return 0
assert x < 0
return -1
def round_to_int(x, up=False):
'''
Round a number to an `int`.
This is mostly used for floating points. By default, it will round the
number down, unless the `up` argument is set to `True` and then it will
round up.
If you want to round a number to the closest `int`, just use
`int(round(x))`.
'''
rounded_down = int(x // 1)
if up:
return int(x) if (isinstance(x, float) and x.is_integer()) \
else rounded_down + 1
else:
return rounded_down
def ceil_div(x, y):
'''Divide `x` by `y`, rounding up if there's a remainder.'''
return (x // y) + (1 if x % y else 0)
def convert_to_base_in_tuple(number, base):
'''
Convert a number to any base, returning result in tuple.
For example, `convert_to_base_in_tuple(32, base=10)` will be `(3, 2)` while
`convert_to_base_in_tuple(32, base=16)` will be `(2, 0)`.
'''
assert isinstance(number, numbers.Integral)
assert isinstance(base, numbers.Integral)
assert base >= 2
sign_ = get_sign(number)
if sign_ == 0:
return (0,)
elif sign_ == -1:
raise NotImplementedError
work_in_progress = []
while number:
work_in_progress.append(int(number % base))
number //= base
return tuple(reversed(work_in_progress))
def get_median(iterable):
'''Get the median of an iterable of numbers.'''
sorted_values = sorted(iterable)
if len(iterable) % 2 == 0:
higher_midpoint = len(iterable) // 2
lower_midpoint = higher_midpoint - 1
return (sorted_values[lower_midpoint] +
sorted_values[higher_midpoint]) / 2
else:
midpoint = len(iterable) // 2
return sorted_values[midpoint]
def get_mean(iterable):
'''Get the mean (average) of an iterable of numbers.'''
sum_ = 0
for i, value in enumerate(iterable):
sum_ += value
return sum_ / (i + 1)
def restrict_number_to_range(number, low_cutoff=-infinity,
high_cutoff=infinity):
'''
If `number` is not in the range between cutoffs, return closest cutoff.
If the number is in range, simply return it.
'''
if number < low_cutoff:
return low_cutoff
elif number > high_cutoff:
return high_cutoff
else:
return number