python

  # 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:33>

  (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)
other2 [1, 2, 3]
other [0, 0]
other2 [1, 2, 3]
other [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'))
True
False
.

list comprehension

  return [num for num in range(-10, 10) if num > 0]

123456789

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 broken link: 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}))
{2}
{1, 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

  1. 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

<<<blk-python-requests-lib-docs>>>broken link: elisp:(open-devdocs-entry "requests")
imported as

  import requests

post request

usage example from broken link: blk: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)
<html><head></head><body><h1>FOO</h1></body></html>
<h1>FOO</h1>
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()))