Skip to content

Instantly share code, notes, and snippets.

View XoseLluis's full-sized avatar

XoseLluis XoseLluis

  • Xixón, Asturies
View GitHub Profile
# inspired by:
# https://github.com/neogeny/late/blob/master/late/__init__.py
# and
# href="https://peps.python.org/pep-0671/
from dataclasses import dataclass
from typing import Callable, Any
import functools
import inspect
@XoseLluis
XoseLluis / delegation.py
Created August 6, 2023 09:18
Delegation in Python
from typing import Callable
import inspect
from typing import Protocol
from abc import abstractmethod
def _create_method(to_method_name: str, to_attr_name: str):
# returns a closure that traps the name of the method to invoke and the attribute_name of the object that will act as receiver-self
def new_method(self, *args, **kargs):
inner_self = getattr(self, to_attr_name)
@XoseLluis
XoseLluis / safe_access.py
Created November 13, 2022 23:16
function motivated by the lack of an Optional Chaining, safe Navigation operator (?, proposed in PEP-505)
def safe_access(fn):
try:
return fn()
except (TypeError, KeyError, IndexError, AttributeError):
return None
# usage:
class Person:
def __init__(self, name, age, profession):
@XoseLluis
XoseLluis / async_executor.py
Created September 19, 2022 14:04
AsyncExecutor class to limit the number of python awaitables running at a given time
import asyncio
from dataclasses import dataclass
import random
from typing import Any
import json
@dataclass
class AsyncAction:
future: asyncio.Future
awaitable_fn: Any # function that returns an awaitable (coroutine, a task...)
@XoseLluis
XoseLluis / asyncExecutor.js
Created August 19, 2022 10:33
asyncExecutor to limit the number of javascript async calls running at a given time
class AsyncAction{
constructor(fn, args, resolveFn, rejectFn){
this.fn = fn;
this.args = args;
this.resolveFn = resolveFn;
this.rejectFn = rejectFn;
}
}
export class AsyncExecutor{
@XoseLluis
XoseLluis / func_with_timeout.py
Created July 22, 2022 15:24
Run a python function with a timeout by means of multiprocessing
import multiprocessing
import queue
import threading
from time import sleep
from typing import Any, Dict, TextIO, List, Callable, Tuple, Optional, AnyStr, Match, cast
class TimeoutException(Exception):
pass
@XoseLluis
XoseLluis / intercept_instance.py
Created July 6, 2022 15:46
Intercept python instance
# In Groovy we can add interception to an instance (not to a whole class) by means of adding it to the instance metaclass
# we can do something like that in Python by creating a new class that inherits the original class of the instance, and changing the class of the instance
# in that new class we implement __getattribute__
class Person:
def __init__(self, name):
self.name = name
def say_hi(self, person):
#print("inside say_hi")
@XoseLluis
XoseLluis / lazy_object.py
Last active May 8, 2022 11:40
Python Lazy objects via __getattribute__, __setattr__ and dynamic classes and inheritance
def lazy(cls, *args, **kwargs):
class _Lazy(cls):
def __init__(self, *args, **kwargs):
_Lazy.original_args = args
_Lazy.original_kwargs = kwargs
def _lazy_init(self):
print(f"_lazy_init")
# remove the traps so that they do not interfere in the next accesses
del _Lazy.__setattr__
@XoseLluis
XoseLluis / tee.js
Created February 20, 2022 12:19
itertools.tee for JavaScript
function tee(iterable, num){
let internalIterator = iterable[Symbol.iterator]();
let buffer = [];
//it's very interesting that a generator function can capture the outer variables in a closure, though
//in the end what is being generated by the compiler is an object with a next() method, not a function having access to the activation object
function* generatorFn(){
let pos = 0;
let finished = false;
while (!finished){
function recursiveFactorial(n, accumulator) {
if (n <= 0) return accumulator;
return recursiveFactorial(n-1, n*accumulator);
}
console.log("recursiveFactorial: " + recursiveFactorial(50,1));
console.log("--------------------------");