#! /usr/bin/env python3 # -*- coding: utf-8 -*- """ Copyright 2022, Nils Hilbricht, Germany ( https://www.hilbricht.net ) Most of this file is trivial code and does not reach the "Schaffenshöhe" for Urheberrecht. If it is: This is practically intended as my Public Domain software. However, there is no such thing as public domain in Germany. Therefore: Released under WTFPL License This program is free software. It comes without any warranty, to the extent permitted by applicable law. You can redistribute it and/or modify it under the terms of the Do What The Fuck You Want To Public License, Version 2, as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. """ def nothing(*args, **kwargs): pass from functools import lru_cache #https://docs.python.org/3.4/library/functools.html#functools.lru_cache cache_unlimited = lru_cache(maxsize=None) #use as @cache_unlimited decorator def dictdiff(a, b): """We use dicts for internal export packages. Compare two of them for changes""" result = {} for key, value in a.items(): if not b[key] == value: result[key] = (value, b[key]) return result import itertools def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), ..." a, b = itertools.tee(iterable) next(b, None) return zip(a, b) def onlyOne(iterable): true_found = False for v in iterable: if v: # a True was found! if true_found: # found too many True's return False else: # found the first True true_found = True # found zero or one True value return true_found class EndlessGenerator(object): """used to turn a single parameter into an endless list of paramters. DO NOT for loop over this object. It will never stop. Use it with next(instance)""" def __init__(self, value): self.value = value def __iter__(self): return self def __next__(self): return self.value def flatList(lst): """Take a nested list of any depth and make it a flat, plain list with only one level""" for elem in lst: if type(elem) in (list, tuple): for i in flatList(elem): yield i else: yield elem def compress(input, inputLowest, inputHighest, outputLowest, outputHighest): return (input-inputLowest) / (inputHighest-inputLowest) * (outputHighest-outputLowest) + outputLowest def listToUniqueKeepOrder(seq): seen = set() seen_add = seen.add return [x for x in seq if not (x in seen or seen_add(x))] def padhexa(self, s:str): """Like zfill, but for hex number strings""" return '0x' + s[2:].zfill(2) import inspect from pprint import pprint def whoCalled(): """If you want to use this only once, better use breakpoint()""" pprint (inspect.stack()) print() def provokecrash(): """Obviously for testing""" import ctypes p = ctypes.pointer(ctypes.c_char.from_address(5)) p[0] = b'x' def humanReadableFilesize(num, suffix="B"): for unit in ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]: if abs(num) < 1024.0: return f"{num:3.1f}{unit}{suffix}" num /= 1024.0 return f"{num:.1f}Yi{suffix}"