Skip to content

Python

1. gmpy2

1.1 is_prime

By Miller-Rabin tests.

import gmpy2
gmpy2.is_prime(x)

2. Sys.argv

Example:

scale = 10000
step = 10000
loop = 10
if len(sys.argv) >= 2:
    scale = int(sys.argv[1])
    if len(sys.argv) >= 3:
        step = int(sys.argv[2])
        if len(sys.argv) >= 4:
            loop = int(sys.argv[3])

3. OS

Execute a command and get its return value:

not_same = os.system('diff {} {}'.format('ans.txt', 'output.txt'))

Execute a command and get its output as list by popen (seperated by lines) (pay attention to the stream redirection):

std_info = os.popen(
    '(gtime -f"%e\t\t%M\t\t" ./std < {} > {}) 2>&1'.format('input.txt', 'ans.txt')
).readlines()

4. Format

Example:

not_same = os.system('diff {} {}'.format('ans.txt', 'output.txt'))

The parameters substitute {} respectively in the original string.

5. Decorator

A flexible decorator:

def decorator(*dec_args, **dec_kwargs):
    import functools
    def _inner_wrapper(*args, **kwargs):
        print(f'dec args: {dec_args = } , {dec_kwargs = }')
        ret = getattr(_inner_wrapper, 'func')(*args, **kwargs)
        return ret
    if dec_args and callable(dec_args[0]):
        func = dec_args[0]
        setattr(_inner_wrapper, 'func', func)
        return functools.wraps(func)(_inner_wrapper)
    else:
        def _wrapper(func):
            setattr(_inner_wrapper, 'func', func)
            return functools.wraps(func)(_inner_wrapper)
        return _wrapper


@decorator
def myfunc_0(x):
    print(x)

print(myfunc_0)
myfunc_0(123)

@decorator(1, 2, k=3)
def myfunc_1(x):
    print(x)

print(myfunc_1)
myfunc_1(456)

5.1 Function

Naive style:

# a function (as a decorator) which returns a function
def a_new_decorator(a_func):

    def wrapTheFunction():
        print("I am doing some boring work before executing a_func()")

        a_func()

        print("I am doing some boring work after executing a_func()")

    return wrapTheFunction

# a function decorated by the decorator
@a_new_decorator
def a_function_requiring_decoration():
    """Hey you! Decorate me!"""
    print("I am the function which needs some decoration to "
          "remove my foul smell")

# '@' style in function definition is a syntactic sugar of:
def a_function_requiring_decoration():
    """Hey you! Decorate me!"""
    print("I am the function which needs some decoration to "
          "remove my foul smell")
a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)

# call the function as normal

To avoid that the name of the function is replaced by its decorator:

from functools import wraps

# decorator def.
def a_new_decorator(a_func):
    @wraps(a_func)
    def wrapTheFunction():
        print("I am doing some boring work before executing a_func()")
        a_func()
        print("I am doing some boring work after executing a_func()")

    return wrapTheFunction

# decorate a function
@a_new_decorator
def a_function_requiring_decoration():
    """Hey yo! Decorate me!"""
    print("I am the function which needs some decoration to "
          "remove my foul smell")

5.2 Class

from functools import wraps

class logit(object):
    def __init__(self, logfile='out.log'):
        self.logfile = logfile

    def __call__(self, func):
        @wraps(func)
        def wrapped_function(*args, **kwargs):
            log_string = func.__name__ + " was called"
            print(log_string)
            # 打开logfile并写入
            with open(self.logfile, 'a') as opened_file:
                # 现在将日志打到指定的文件
                opened_file.write(log_string + '\n')
            # 现在,发送一个通知
            self.notify()
            return func(*args, **kwargs)
        return wrapped_function

    def notify(self):
        # logit只打日志,不做别的
        pass

@logit()
def myfunc1():
    pass

5.3 line profiler

def profile(filename: str | None = None):
    import sys, functools
    from line_profiler import LineProfiler
    def _inner_wrapper(*args, **kwargs):
        profiler = LineProfiler()
        lp_wrapper = profiler(getattr(_inner_wrapper, 'func'))
        ret = lp_wrapper(*args, **kwargs)
        if filename:
            with open(filename, 'w') as f:
                profiler.print_stats(stream=f)
        else:
            profiler.print_stats(stream=sys.stdout)
        return ret
    if filename and callable(filename):
        func = filename
        setattr(_inner_wrapper, 'func', func)
        return functools.wraps(func)(_inner_wrapper)
    else:
        def _wrapper(func):
            setattr(_inner_wrapper, 'func', func)
            return functools.wraps(func)(_inner_wrapper)
        return _wrapper

@profile('profile.txt')
def myfunc(x):
    print(x)

print(myfunc)
myfunc(1)

6. Special Symbols for Passing Args.

6.1 Non-keyword Args

Use the symbol * to take in a variable number of arguments; by convention, it is often used with the word args.

def myFun(*args):
    for arg in args:
    # here args is a tuple: ('Hello', 'Welcome', 'to', 'GeeksforGeeks')
        print (arg)

myFun('Hello', 'Welcome', 'to', 'GeeksforGeeks')

Another usage of *:

def foo1(a, b=None):
    print(a, b)

# * indicates the end of the positional arguments.
# Every argument after that can only be specified by keyword.
def foo2(a, *, b=None):
    print(a, b)

foo1(1, 2)
foo2(1, 2)
# TypeError: foo1() takes 1 positional argument but 2 were given
foo2(1, b=2)

6.2 Keyword Arguments

The special syntax **kwargs in function definitions in python is used to pass a keyworded, variable-length argument list.

def myFun(**kwargs):
  # here kwargs is a dict
    for key, value in kwargs.items():
        print ("%s == %s" %(key, value))

# Driver code
myFun(first ='Geeks', mid ='for', last='Geeks')

6.3 Together

def myFun(*args, **kwargs):
    print("args: ", args)
    print("kwargs: ", kwargs)


# Now we can use both *args ,**kwargs
# to pass arguments to this function :
myFun('geeks','for','geeks',first="Geeks",mid="for",last="Geeks")

7. Generator Functions

  • A generator function is defined like a normal function

  • but whenever it needs to generate a value, it does so with the yield keyword rather than return

  • yield sends a value back to the caller;

    When resumed, the function continues execution immediately after the last yield run.

  • doesn't need to store the entire sequence in memory.

e.g. 1

# A Simple Python program to demonstrate working
# of yield

# A generator function that yields 1 for the first time,
# 2 second time and 3 third time
def simpleGeneratorFun():
    yield 1
    yield 2
    yield 3

# Driver code to check above generator function
for value in simpleGeneratorFun():
    print(value)

e.g. 2

def nextSquare():
    i = 1
    # An Infinite loop to generate squares
    while True:
        yield i*i               
        i += 1 # Next execution resumes
                # from this point   

# Driver code to test above generator function
for num in nextSquare():
    if num > 100:
        break   
    print(num)

8. stuck monitoring

# pip install hanging_threads
from hanging_threads import start_monitoring
start_monitoring(seconds_frozen=10, test_interval=100)

Last update: October 18, 2022
Authors: Co1lin (55.76%), Co1lin (16.06%), Co1lin (28.18%)