table of contents

python

2022-08-09
# import sys
# import os
# import os.path
# import numpy as np
# import matplotlib.pyplot as plt
import matplotlib as mpl # mpl is essential because i must style it before usage for better output images
# import re
# import torch
# import random
# import collections

# import keras
# import tensorflow as tf
# from keras import layers

automating interpreter installation and setup

this doesnt work because torchtext isnt in nixos.. <2024-06-30 Sun 20:15:00>

(setq temp-python-interpreter (shell-command-to-string "nix-shell -p '(pkgs.python3.withPackages (p: with p; [torch torchtext numpy matplotlib]))' --run \"whereis python3 | cut -d ' ' -f2\""))
(let ((python-shell-interpreter temp-python-interpreter))
  (call-interactively 'run-python))

add method to class dynamically

from functools import wraps

"""this one didnt work properly (has issues with 'self')"""
# def add_to_class(cls):
#     def decorator(func):
#         @wraps(func)
#         def wrapper(self, *args, **kwargs):
#             return func(*args, **kwargs)
#         setattr(cls, func.__name__, wrapper)
#         return func
#     return decorator

def add_to_class(cls):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)
        setattr(cls, func.__name__, wrapper)
        return func
    return decorator

example usage:

# class A has no methods nor variables.
class A:
    pass

a = A()
@add_to_class(A)
def foo():
    print('printing from foo')

a.foo()
printing from foo

slicing operator

the colon in python is used as a slicing operator in lists

consider the expression list[a:b:c], here, a is the index to start from, b is the index to stop at (element at b is excluded), and c is the size of the jump when "slicing"

return 'hello there its me'[0:10:2]
hlote

the operator [:] is often used to copy a list's element into another:

original = [1, 2, 3]
other = original
other2 = original[:]
print('other ', other)
print('other2', other2)
original[:] = [0, 0]
print('other ', other)
print('other2', other2)
other  [1, 2, 3]
other2 [1, 2, 3]
other  [0, 0]
other2 [1, 2, 3]

in the snippet above, the difference between mylist[:] = and mylist = is that the latter doesn't replace elements in the original list but rather changes the list pointer, whereas the former modifies the list and the pointer stays doesnt change.

the operator ::1 is often used to reverse a list:

return [1,2,3,4,5,6][::-1]
[6, 5, 4, 3, 2, 1]

lambda

students = {111: "anna", 222: "john", 333: "katy", 444: "suzanne", 555: "julia"}
print(sorted(students,
             key=lambda s: len(students[s]),
             reverse=True))
[444, 555, 111, 222, 333]
list(map(lambda x: x**2, [77, 85, 67, 83, 95]))
[5929, 7225, 4489, 6889, 9025]

filesystem

import os.path
import os
print(os.curdir)
print(os.path.isfile('/root'))
print(os.path.isdir('/root'))
.
False
True

list comprehension

return [num for num in range(-10, 10) if num > 0]
1 2 3 4 5 6 7 8 9

reading documentation

the easiest way to read the documentation for a package is to use pydoc <package> on the commandline

the easiest way to read the documentation for a "symbol" is to run help(symbol)

for usage with emacs this could be of help https://www.emacswiki.org/emacs/ExternalDocumentation, or we can use https://codeberg.org/ravi/consult-dash or https://github.com/blahgeek/emacs-devdocs-browser

python set union

print(set({1}).union({2}))
print(set().union({2}))
{1, 2}
{2}

python index of item in list

mylist.index(myelement)

random item from list

import random

foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))

remove item from list

list.pop(index)

list.pop(index)

>>> l = ['a', 'b', 'c', 'd']
>>> l.pop(0)
'a'
>>> l
['b', 'c', 'd']
>>>

del list[index]

del list[index]

>>> l = ['a', 'b', 'c', 'd']
>>> del l[0]
>>> l
['b', 'c', 'd']
>>>

with slicing

x = [0,1,2,3,4]
x = x[1:]

if x is empty, x=x[1:] would leave it empty without complaining. x.pop(0) would throw for an empty list x. Sometimes throwing is what one wants: If the assumption that there is at least an element in the list is wrong, one might want to get notified.

https://stackoverflow.com/questions/4426663/how-do-i-remove-the-first-item-from-a-list

random int

random.randint(3, 9) # between 3 and 9, both included

pick random sublist

random.sample(["some", "provider", "can", "be", "null"], 3)

concatenate lists

simply list1 + list2.

get user home dir

from os.path import expanduser
home = expanduser("~")

python spawn command avoid zombie process

as an example, launch a command using:

os.spawnlp(os.P_NOWAIT, 'test', 'sleep', '10')

avoid a zombie state when the command is finished by adding this at the top of your file:

import signal
signal.signal(signal.SIGCHLD, lambda _x,_y: os.wait())

actually, it seems this works alot better (and detaches the subprocess too):

import subprocess
p = subprocess.Popen(['your', 'command', 'here'], start_new_session=True)

requests library

post request

usage example from blk-python-requests-lib-docs:

requests.post(url, data=None, json=None, **kwargs)

using json makes requests set the correct headers for a json body, but data does accept dicts so no need to do data=json.dumps if you still want to use data over json.

iterate through every two adjacent elements in a list at a time

for (index, thing) in enumerate(the_list[:-1]):
    current, next_ = thing, the_list[index + 1]

read file line by line

with open(filename) as file:
  for line in file:
      print(line.rstrip())

get local ip address

import socket

# create a dummy connection to an external ip
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
local_ip = s.getsockname()[0]
s.close()

print(f"local IP address: {local_ip}")

beautifulsoup4

simple example:

from bs4 import BeautifulSoup

soup = BeautifulSoup('<p>this is p</p>', 'html5lib')

unlike html5lib, this parser (html.parser) makes no attempt to create a well-formed HTML document by adding a <body> tag. Unlike lxml, it doesn’t even bother to add an <html> tag.

from bs4 import BeautifulSoup

a = BeautifulSoup('<h1>FOO</h1>', "html.parser")
print(a)

b = BeautifulSoup('<h1>FOO</h1>', "html5lib")
print(b)
<h1>FOO</h1>
<html><head></head><body><h1>FOO</h1></body></html>

https://stackoverflow.com/questions/14822188/dont-put-html-head-and-body-tags-automatically-beautifulsoup

define iterator for class

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self

  def __next__(self):
    x = self.a
    self.a += 1
    return x

myclass = MyNumbers()
myiter = iter(myclass)

print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))

threadpoolexecutor

ThreadPoolExecutor is useful when wanting to quickly parallelize stuff, heres a simple example:

from concurrent.futures import ThreadPoolExecutor
import requests

def download_page(url):
    print(url)
    response = requests.get(url)
    return response.content

urls = ['https://stackoverflow.com', 'https://google.com', 'https://facebook.com']

with ThreadPoolExecutor(max_workers=3) as executor:
    results = []
    for url in urls:
        result = executor.submit(download_page, url)
        results.append(result)

for result in results:
    print(len(result.result()))