2A bunch of miscellaneous functions and classes that might be useful
7from random
import randint
13from itertools
import chain
14from inspect
import isgenerator
15from rich
import print as rprint
16from rich.panel
import Panel
18from rich.console
import Console
21 """ Of the parameters passed, returns the parameters which are not `null` """
22 return list(filter(
lambda i: i != null, args))
24def only1(*args, null=None) -> bool:
25 """ Returns true only if there is only 1 non-`null` parameter """
26 return len(
available(*args, null=null)) == 1
28def interpret_percentage(percentage:Union[int, float]) -> float:
29 if isinstance(percentage, bool):
30 return float(percentage)
32 return percentage / 100
38 <code that has a 50% chance of running>
39 NOTE: .5 works
as well
as 50
41 return randint(1, 100) < interpret_percentage(percentage)*100
44 """ Returns, randomly, either True or False """
45 return bool(randint(0, 1))
48 """ Returns True if a is within tolerance range of b """
49 return a <= b + tolerance
and a >= b - tolerance
51def closest(target:SupportsInt, compare:Iterable[SupportsInt], index=
False) -> int:
52 """ Finds the value in `compare` that is closest to `target`.
53 Returns the index (if `index`
is True),
or the value.
55 If there are multiple closest values
in the list, it returns the first one
57 val = min(compare, key=lambda i: abs(target - i))
59 return compare.index(val)
62def furthest(target:SupportsInt, compare:Iterable[SupportsInt], index=
False) -> int:
63 """ Finds the value in `compare` that is furthest from `target`.
64 Returns the index (if `index`
is True),
or the value.
65 If there are multiple furthest values
in the list, it returns the first one
68 val = max(compare, key=lambda i: abs(target - i))
70 return compare.index(val)
74 """ Returns true if x is a power of 2 """
75 return (x != 0)
and ((x & (x - 1)) == 0)
77def between(target, start, end, left_open=False, right_open=False) -> bool:
78 """ Returns True if `target` is between start and end """
79 return (target >= start
if left_open
else target > start)
and \
80 (target <= end
if right_open
else target < end)
82def insert_str(string:str, index:int, inserted:str) -> str:
83 """ Returns the string with `inserted` inserted into `string` at `index` """
84 return string[:index] + inserted + string[index+1:]
87 """ Constrains `val` to be within `low` and `high` """
88 return min(high, max(low, val))
92 from_start:SupportsAbs, from_end:SupportsAbs,
93 to_start:SupportsAbs, to_end:SupportsAbs
95 """ Proportionally maps `value` from being within the `from` range to the `to` range """
96 return ((abs(value - from_start) / abs(from_end - from_start)) * abs(to_end - to_start)) + to_start
98def frange(start:float, stop:float, skip:float=1.0, accuracy:int=10000000000000000):
100 for x
in range(int(start*accuracy), int(stop*accuracy), int(skip*accuracy)):
104 prompt:str=
'Continue?',
106 quit_msg:str=
'Exiting...',
107 return_if_invalid:bool=
False,
108 include_YN:bool=
True,
110 """ Promt the user to confirm via terminal whether to continue or not. If given an invalid response,
111 it will continue to ask, unless `return_if_invalid`
is set to
True.
113 response = input(prompt + (" (y/N): " if include_YN
else '')).lower()
114 if response
in (
'y',
'yes'):
116 elif response
in (
'n',
'no'):
122 print(
'Invalid Input')
123 if return_if_invalid:
126 confirm(prompt, include_YN=include_YN, quit=quit, quit_msg=quit_msg)
129 """ Simply return whatever is in the given file path. Just like the Unix `cat` command. """
130 with open(f,
'r')
as f:
134 """ Return the string name, i.e. 1st, 2nd, 3rd, etc. for the given integer """
137 if i[-1] ==
'1' and not i.endswith(
'11'):
139 elif i[-1] ==
'2' and not i.endswith(
'12'):
141 elif i[-1] ==
'3' and not i.endswith(
'13'):
146def grade(percentage:Union[float, int]) -> str:
147 """ This returns the letter grade given, based on the percentage you have in a class
148 NOTE: This is one scale, that represents general accuracy. Your institution may
149 use a different scale. As far
as I know, there isn
't a standardized scale for letter grades.
152 percentage = interpret_percentage(percentage)
156 elif percentage < .62:
158 elif percentage < .68:
160 elif percentage < .70:
162 elif percentage < .73:
164 elif percentage < .78:
166 elif percentage < .80:
168 elif percentage < .83:
170 elif percentage < .88:
172 elif percentage < .90:
174 elif percentage < .93:
180def isiterable(obj, include_str:bool=
True) -> bool:
181 """ Returns True if you can iterate over obj. Optionally excludes strings """
182 if isinstance(obj, str):
185 if isinstance(obj, type):
188 isinstance(obj, Iterable)
or
190 getattr(obj,
'__iter__',
False)
or
191 getattr(obj,
'__next__',
False)
195 """ Ensures that `iter` is an iterable, if it isn't already.
196 If `iter` is not an iterable, it
'll make it one of type `cast`, and if `ensure_cast_type` is
197 True, it will cast `iter` to `cast`
as well. Otherwise it returns `iter` unchanged.
198 Strings,
in this context, don
't count as iterables.
200 if not isiterable(iter, include_str=
False):
203 return cast((iter, ))
209ensureIterable = ensure_iterable
213 """ Ensures that `iter` is *not* an iterable, IF `iter` only has one element.
214 If `iter` has 0 or more than 1 elements, it returns iter unchanged.
215 This function works
with generators, but they must self-terminate.
216 DO NOT PASS INFINITE ITERATORS TO THIS FUNCTION.
217 There
is no good way to test
for them,
and they will cause an infinite loop
219 if not isiterable(iter):
222 if isgenerator(iter):
229ensureNotIterable = ensure_not_iterable
236def cp(thing=None, rnd:int=3, show=
False, not_iterable=
True, evalf=
True):
237 """ Quick shortcut for notebooks for copying things to the clipboard in an easy way"""
238 from sympy
import latex, Basic, Float
239 from clipboard
import copy
247 if isinstance(thing, Basic)
and not isinstance(thing, Float)
and not evalf:
255 thing = thing.evalf()
258 copy(str(round(thing, rnd)))
270def in_IPython(return_instance=True):
276 if (instance := IPython.get_ipython())
is not None:
277 return instance
if return_instance
else True
281def flatten(iter:Iterable, recursive:bool=
True) -> list:
282 """ Denest either 1 or all lists inside of `iter` into one big 1 dimentional list. """
284 if recursive
and any(map(isiterable, rtn)):
285 rtn = flatten(rtn, recursive)
289 """ Returns the dict given, but with the keys as values and the values as keys. """
290 return dict(zip(d.values(), d.keys()))
295 def __init__(self, stdout=None, stderr=None):
296 if isinstance(stdout, io.TextIOBase):
299 self.
_stdout = open(stdout
or os.devnull,
'w')
300 if isinstance(stderr, io.TextIOBase):
303 self.
_stderr = open(stderr
or os.devnull,
'w')
306 self.old_stdout, self.
old_stderr = sys.stdout, sys.stderr
307 self.old_stdout.flush(); self.
old_stderr.flush()
310 def __exit__(self, exc_type, exc_value, traceback):
313 sys.stdout = self.old_stdout
319 """ A quick function for helping you practice notecards. `cards` is a dict of
320 {card front: card back}.
325 print(
'Press enter for the next card, f to flip the card, b to flip back, and q to quit')
326 while (resp := input()) !=
'q':
329 while (front := random.choice(list(cards.keys()))) == cur_front:
pass
331 cur_back = cards[front]
334 rprint(Panel(cur_back))
bool confirm(str prompt='Continue?', bool quit=False, str quit_msg='Exiting...', bool return_if_invalid=False, bool include_YN=True)
Promt the user to confirm via terminal whether to continue or not.
str insert_str(str string, int index, str inserted)
Returns the string with inserted inserted into string at index
bool between(target, start, end, left_open=False, right_open=False)
Returns True if target is between start and end.
str grade(Union[float, int] percentage)
This returns the letter grade given, based on the percentage you have in a class NOTE: This is one sc...
bool randbool()
Returns, randomly, either True or False.
int furthest(SupportsInt target, Iterable[SupportsInt] compare, index=False)
Finds the value in compare that is furthest from target.
def constrain(val, low, high)
Constrains val to be within low and high
def percent(Union[int, float] percentage)
Usage: if (percent(50)): <code that has a 50% chance of running> NOTE: .5 works as well as 50.
list available(*args, null=None)
Of the parameters passed, returns the parameters which are not null
str cat_file(str f)
Simply return whatever is in the given file path.
def close_enough(a, b, tolerance)
Returns True if a is within tolerance range of b.
dict invert_dict(dict d)
Returns the dict given, but with the keys as values and the values as keys.
str umpteenth(int i)
Return the string name, i.e.
def cp(thing=None, int rnd=3, show=False, not_iterable=True, evalf=True)
Quick shortcut for notebooks for copying things to the clipboard in an easy way.
def ensure_not_iterable(Iterable iter)
Ensures that iter is not an iterable, IF iter only has one element.
int closest(SupportsInt target, Iterable[SupportsInt] compare, index=False)
Finds the value in compare that is closest to target.
def ensure_iterable(Iterable iter, type cast=list, bool ensure_cast_type=True)
Ensures that iter is an iterable, if it isn't already.
bool isPowerOf2(int x)
Returns true if x is a power of 2.
def run_notecards(dict cards)
A quick function for helping you practice notecards.
bool only1(*args, null=None)
Returns true only if there is only 1 non-null parameter.