Skip to main content

A Pack of useful python QoL changes

Project description

PyQoL

This package contains a lot of feature for Quality of Life, functionnal programming, and others.

.CORE

codedit

Codedit is a decorator that lets you change the source code of a function using regexes. Sadly the syntax has to be "python-valid" before, but the code doesn't have to mean anything though.

@codedit("oooooooone", "1")
def add_one(x):
    return oooooooone
@codedit(r"_(.+)_more_than\[(.+)\]", r"\2 + \1")
def add_one(x):
    return _1_more_than[x]

Obviously, in that case it's not that useful, but I'm sure you can find some hacks using it :)

Codedits

Is a class that contains all known useful codedits.

.Lambda

Lets you define a custom lambda operator.

@Codedits.Lambda(">>")
def add_one(x):
    ld = {a >> a + 1}
    return ld(x)

Valid lambdas include: -1>, >, :, >>, ..

.Bittors (better iterators)

I is the new range

I, and its brothers IR, IC, IE are iteration functions, used to create loops. It will iterate over any iterable, and transform a int argument into a range from 0 to this int. Negative ints lead to a backwards loop. It will iterate over all arguments at the same time, and zip them.

Arguments are:

I(*args, revserse = False, enum = False, chunking=False, chunk_size=1)

Enum = True is the same as zipping with I(None), which returns an infinite loop. It also can be called with IE

Chunking, also called by IC returns multiple values at once, in a tuple.

IC(-8, chunk_size=2) -> (7, 6), (5, 4), (3, 2), (1, 0)

No start, end, step here, all arguments are the iterations

.Structs

Struct

Struct takes any arguments when created, and stores them. It is similar to a JS object.

my_object = Struct(health=100, strength=20)
my_object.sword = Swords.Diamond
def _run(self: Struct):
    pass
my_object.run = _run
my_object.run()

Registry

You can create registers of functions (for plugin management, or special scoping), by creating a registry:

r = Registry()

Then, you can register functions in it, and access them that way.

@r.register
def my_happy_little_function(x):
    print(f"happy little {x}")

r.registry["my_happy_little_function"]("accident")
r["my_happy_little_function"]("programmer")

.FP

Function

You can decorate one of your functions with Function to access function composition, and other features.

@Function
def add_two(n): return n + 2
mult_by_two = Function(lambda x: x * 2)

add_then_mult = (add_two + mult_by_two)
mult_then_add = (add_two * mult_by_two)

Bunction (better function)

This class is a superset of Function, which allows for cool setups. Let's implement the fibonacci function with it, in a very defensive manner:

# First, setup the default case
@Bunction
def fib(n):
    return fib(n-1) + fib(n-2) 

Alone, this function doesn't work, it needs to return 1 if the input is 0 or 1. We can easily patch this by adding cases, which will overwrite the default.

#if x is 0, this case will be executed
@fib.case(lambda x : x == 0)
def _one(x): return 1

Yes, this is ugly, that's why you can also do this:

# if input is 1, return 1
fib.case(1)(1)

Now, let's do a little defensive programming, and make our function idiot-proof:

fib.case(lambda x : x < 0)(0)

We can even preprocess the inputs, to fit in one of our cases when it couldn't before

@fib.preprocess(lambda x : type(x) == str)
def _exec(x):
    if x.isnumber(): # implement your own isnumber, python doesn't have one for floats for some reason
        return float(x) # will then be converted to a float
    else:
        return 0 # will input 0 to fib

# Then, convert floats to ints
fib.preprocess(lambda x : type(x) == float)(lambda x : int(x))

Map

A new tool for iterating, the Map

Map.over

Map over is a curried function taking in an iterable, then a function, and outputs a new List of the results of the function. You can use it as a decorator, or as a normal function call

Map.over([0, 1, 2, 3])(lambda x : x * 2) == L(0, 2, 4, 6)
@Map.over([0, 1, 2, 3])
def newlist(e):
    return e * 2
newlist == L(0, 2, 4, 6)

That last functionnality might look extremely wierd, and it does, but it can be practical if used correctly. If you have a set of objects you iterate over everywhere in the code, that you might change, why not have them all in once place ?

agents = L(...)
ForAllAgents = Map.over(agents)
#...
@ForAllAgents
def training_log(agent):
    #...
    return log_info
print(training_log)

Map.using

It is the exact same as Map.over, but the argument order is swapped.

@Map.using
def mult_list_by_two(e):
    return e * 2
mult_list_by_two([0, 1, 2, 3]) == L(0, 2, 4, 6)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyqol-0.0.4.tar.gz (7.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyqol-0.0.4-py3-none-any.whl (8.8 kB view details)

Uploaded Python 3

File details

Details for the file pyqol-0.0.4.tar.gz.

File metadata

  • Download URL: pyqol-0.0.4.tar.gz
  • Upload date:
  • Size: 7.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.36.1 CPython/3.7.4

File hashes

Hashes for pyqol-0.0.4.tar.gz
Algorithm Hash digest
SHA256 388ce010055a11a069cdb1789947adc19b447d775d1cc356512a00f4324ae8ba
MD5 a500c4ddc0b8888e1a807b5e289d9cfa
BLAKE2b-256 fdc833967fc77e9760be596a344be39d76b16653e44f1ede9e5b607c3ede86d2

See more details on using hashes here.

File details

Details for the file pyqol-0.0.4-py3-none-any.whl.

File metadata

  • Download URL: pyqol-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 8.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.36.1 CPython/3.7.4

File hashes

Hashes for pyqol-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 2e954c3e0bf2e8cc6441cd2dc6cdd0523c4195eb6bfd7337591dea3376d18aa1
MD5 69e1081e3a573d0901e952f9a834a183
BLAKE2b-256 1b364e6fda2a09b8700fa86131c1f1f5bc87f6d60f977765094a8af5f4330ff6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page