Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Python Snippets
def clipboard(string):
"""Copy a string to the clipboard."""
if platform in ("win32", "cygwin"):
Popen(["clip"], stdin=PIPE).communicate(string.encode())
else:
raise Exception("Platform not supported.")
def get_width():
"""Get the console width (number of chars or columns)."""
if platform == "win32":
result = Popen("mode con", stdout=PIPE, shell=True).communicate()[0].decode()
return int(search(r"Columns:\s*(\d+)", result)[1])
else:
return int(Popen("stty size", stdout=PIPE, shell=True).communicate()[0].decode().split()[1])
def get_size():
"""Get the console width and height."""
if platform == "win32":
raise Exception("Platform not supported.")
else:
size = Popen("stty size", stdout=PIPE, shell=True).communicate()[0].decode().split()[1]
return int(size[1]), int(size[0])
#! /usr/bin/env python3
# -*- coding: utf8 -*-
from PIL import Image
import numpy as np
# Standard cube map
# | . | T | . | . |
# | L | F | R | B |
# | . | B | . | . |
def make_map(im_paths, bg=0):
face_im = Image.open(im_paths)
w, h = face_im.size
if not w == h:
raise ValueError("Cube map size improper. Must be square.")
map_im = Image.new("RGBA", (w * 4, h * 3), bg)
map_im.paste(face_im, (w, 0))
map_im.paste(face_im, (w, 2 * h))
map_im.paste(face_im, (0, h))
map_im.paste(face_im, (2 * w, h))
map_im.paste(face_im, (w, h))
map_im.paste(face_im, (3 * w, h))
return map_im
def generate(map_path, bg=1):
map_im = Image.open(map_path)
if not (map_im.height == 3 / 4 * map_im.width and map_im.width % 4 == 0 and map_im.height % 3 == 0):
raise ValueError("Cube map size improper. Must be 4:3 scale image, width divisible by 4, and height divisible by 3.")
w, h = map_im.size
face_bounds = {
"top": (1/4 * w, 0, 2/4 * w, 1/3 * h),
"bottom": (1/4 * w, 2/3 * h, 2/4 * w, 3/3 * h),
"left": (0, 1/3 * h, 1/4 * w, 2/3 * h),
"right": (2/4 * w, 1/3 * h, 3/4 * w, 2/3 * h),
"front": (1/4 * w, 1/3 * h, 2/4 * w, 2/3 * h),
"back": (3/4 * w, 1/3 * h, 4/4 * w, 2/3 * h)
}
face_ims = {}
for face, box in face_bounds.items():
face_ims[face] = map_im.crop(face_bounds[face])
#
# for face in face_ims:
# face_ims[face].show()
generate("test.png")
make_map("texture.png").show()
#! /usr/bin/env python3
from time import strftime
from pyfiglet import figlet_format
from os import system, name as os_name, popen
# Function to pretty print to the perfect center of a console window
def fullscreen_print(text, font="dotmatrix", top_pad=0):
size = popen("stty size", "r").read().split() # Make a tuple for the size of the console
size = int(size[1]), int(size[0]) # Switch them, make it W, H with ints
fig = figlet_format(str(text), font=font, justify="center", width=size[0]) # Get the fig formatted string
fig_height = len(fig.split("\n")) # Get the line length of the figlet formatted string
top_pad += round((size[1] - fig_height) / 2) # Calculate top padding (newlines) to put before the fig
clear() # Clear the screen
print("\n" * top_pad, fig) # Print the figlet and padding
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# -*- author: spikespaz -*-
from PIL import Image
from os import path, listdir, mkdir
# Define constants / settings to be used for image conversion.
# Shape size is thesize of each image to be generated. Pick a size that seems to be close to the average.
shape_size = (100, 120)
# Resample is the algorithm to use when downscaling. Image.LANCZOS is best for thumbnails.
# NEAREST, BOX, BILINEAR, HAMMING, BICUBIC, LANCZOS, NEAREST
resample = Image.LANCZOS
# raw_dir is the RELATIVE PATH to the original face images.
raw_dir = path.abspath("./faces_raw")
# snape_dir and grey_dir are relative paths to the shaped and greyscale outputs.
shape_dir = path.abspath("./faces_shape")
grey_dir = path.abspath("./faces_grey")
# If the shape_dir and grey_dir paths don't exist, create them.
try:
mkdir(shape_dir)
except FileExistsError:
pass
try:
mkdir(grey_dir)
except FileExistsError:
pass
# Helper function to join arbitrary paths and get the absolute full path.
def absjoin(*p):
return path.abspath(path.join(*p))
# Helper function to rename the file to a .png file.
def makepng(p):
return path.splitext(p)[0] + ".png"
# Looping for each file in raw_dir.
for fp in listdir(raw_dir):
# If the file is an accepted file type (images).
if fp.split(".")[-1] in ("png", "jpg", "jpeg"):
# Open and initiate the image.
raw_fp = absjoin(raw_dir, fp)
print("Opening:", raw_fp)
im = Image.open(raw_fp)
# Create and resize the image to the shape defined above.
shape_fp = makepng(absjoin(shape_dir, fp))
print("Saving:", shape_fp)
im = im.resize(shape_size, resample)
im.save(shape_fp, "JPEG")
# Convert open image to greyscale (LA) and save as a PNG format.
grey_fp = makepng(absjoin(grey_dir, fp))
print("Saving:", grey_fp)
im = im.convert("LA")
im.save(grey_fp, "PNG")
# File is not an acceptable image file, skip it.
else:
print("Skipping:", absjoin(raw_dir, fp))
#! /usr/bin/env python3
from PIL import Image, ImageDraw, ImageFont
from os import path
from parser import read_config
def read_sentences(fp):
with open(fp) as f:
return tuple(l.strip() for l in f.readlines() if l.strip())
training_settings_path = path.abspath("./store/training_settings.txt")
print("Training settings path:", training_settings_path)
def get_settings_rel(*p):
return path.abspath(path.join(path.dirname(training_settings_path), *p))
training_settings = read_config(training_settings_path)
try:
training_settings["rotation_filter"] = eval(training_settings["rotation_filter"])
except NameError:
print("Rotation filter invalid. Defaulting to BICUBIC.")
training_settings["rotation_filter"] = Image.BICUBIC
try:
training_settings["training_filter"] = eval(training_settings["training_filter"])
except NameError:
print("Rotation filter invalid. Defaulting to BICUBIC.")
training_settings["training_filter"] = Image.BICUBIC
training_sentences_path = get_settings_rel(training_settings["training_sentences"])
print("Training sentences path:", training_sentences_path)
training_sentences = read_sentences(training_sentences_path)
font_default_path = get_settings_rel(training_settings["font_default"])
print("Font default path:", font_default_path)
def create_text_image(text, size=10, rot=None, pad=(4,) * 4, fg=(0,) * 3, bg=(255,) * 3,
fpath=font_default_path,
ttf=training_settings["font_default_ttf"]):
if ttf:
font = ImageFont.truetype(fpath, size)
else:
font = ImageFont.load(fpath)
im_size = font.getsize(text)
im_size = (im_size[0] + pad[2] + pad[3], im_size[1] + pad[0] + pad[1])
im = Image.new("RGBA", im_size, bg)
im_draw = ImageDraw.Draw(im)
im_draw.text((pad[2], pad[0]), text, font=font, fill=fg)
if rot:
return im.rotate(rot, resample=training_settings["rotation_filter"], expand=True)
else:
return im
def get_save_path(scale, name):
return path.join(get_settings_rel(training_settings["training_path"], str(scale), name))
counter = -1
for sentence in training_sentences:
for size in training_settings["font_sizes"]:
for rot in training_settings["rotation_degrees"]:
counter += 1
print(str(counter) + ": " + str((sentence, size, rot)))
text_im = create_text_image(sentence, size, rot, training_settings["font_padding"],
training_settings["font_foreground"],
training_settings["font_background"])
text_im.save(get_save_path(1.0, str(counter) + ".png"))
im_size = (int(text_im.width * training_settings["training_scale"]),
int(text_im.height * training_settings["training_scale"]))
text_im = text_im.resize(im_size, training_settings["training_filter"])
text_im.save(get_save_path(training_settings["training_scale"], str(counter) + ".png"))
#! /usr/bin/env python3
from sys import argv
from pprint import PrettyPrinter
from functools import wraps
from json import dumps
pp = PrettyPrinter(indent=4)
class Testable:
"""A decorator that allows functions to be tested from the terminal. Pass the function name and simple arguments
(`int`s, `float`s, and `str`s) into the terminal to read the direct output. Some advanced printing is available.
Example:
These are the contents of `testable.py`.
>>> @Testable(5, 6, 7)
>>> def test_function(first, second, special=1):
... return sum(first, second) * special
...
>>>
Command line examples are as follows.
$ python testable.py test_function
77
$ python testable.py test_function 80 10
90
$ python testable.py test_function 80 10 2
180
Additionally, `_pretty` and `_json` can be appended before the function name in the command to get more visually
appealing outputs.
>>> @Testable()
>>> def test_function():
... return {"one": 1, "two": 2, "three": 3, "four": 4, "five": 5}
...
>>>
Followed by the commands and their outputs.
$ python utils.py _json test_function
{
"five": 5,
"one": 1,
"four": 4,
"three": 3,
"two": 2
}
Replacing `_json` with `_pretty` works better for lists with really long values.
Attributes:
args (tuple): A variable length list of arguments to be tested with if none are supplied by the command line.
kwargs (tuple): A dictionary of keyword arguments to be tested with.
"""
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
def __call__(self, func):
if len(argv) > 1 and argv[1] == func.__name__:
if len(argv) > 2:
parsed_args = argparse(*argv[2:])
print(func(*parsed_args[0], **parsed_args[1]))
else:
print(func(*self.args, **self.kwargs))
elif len(argv) > 2 and argv[2] == func.__name__:
if argv[1] == "_pretty":
def printer(output):
pp.pprint(output)
elif argv[1] == "_json":
def printer(output):
print(dumps(output, indent=4))
if len(argv) > 3:
parsed_args = argparse(*argv[3:])
printer(func(*parsed_args[0], **parsed_args[1]))
else:
printer(func(*self.args, **self.kwargs))
return func
@Testable("90.8")
def parsestr(string):
"""Attempts to parse a string into a number. This will return the original string if failed.
Args:
string (str): The string input to parse.
Returns:
int: The integer value from the string.
float: The float value from the string.
str: The original string passed in. Returned when `int` and `float` failed.
"""
try:
return int(string)
except ValueError:
try:
return float(string)
except ValueError:
return string
@Testable("90.8", "-1", "10", "string", "--kwarg0", "test", "--kwarg1", "90")
def argparse(*args):
"""Parse a list of arguments (in ``sys.argv`` format) into a variable length list and a keyword arguments dictionary.
This is just a simpler version of the argument parser included with the Python Standard Library.
Arguments preceded by two dashes will be considered keys in the keyword arguments dictionary.
Example:
>>> args = ("90.8", "-1", "10", "string", "--kwarg0", "test", "--kwarg1", "90")
>>> argparse(args)
([90.8, -1, 10, 'string'], {'kwarg1': 90, 'kwarg0': 'test'})
>>>
Args:
*args: Variable length argument list of strings to be parsed.
Returns:
tuple: A two-item tuple with a list of arguments and then the keyword arguments dictionary.
"""
parsed_args = []
parsed_kwargs = {}
iterable = iter(enumerate(args))
for arg in iterable:
value = arg[1].strip()
if arg[1].startswith("--"):
parsed_kwargs[value[2:]] = parsestr(args[arg[0] + 1])
next(iterable)
else:
parsed_args.append(parsestr(value))
return parsed_args, parsed_kwargs
def return_yield(func):
"""Decorator that wraps a generator and returns its value in a list as if it were a normal function.
Example:
Test function definition **without** the ``@return_yield`` applied, returns a generator.
>>> def test_generator(loops):
... for i in range(loops):
... yield str(i)
...
>>> test_generator(10)
<generator object test_generator at 0x00000215B2FC00A0>
>>>
Now, **with** ``@return_yield``.
>>> @return_yield
>>> def test_generator(loops):
... for i in range(loops):
... yield str(i)
...
>>> test_generator(10)
["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
>>>
Args:
func: Function to wrap, applied as a decorator with no parenthesis.
Returns:
func: Returns the original function as a non-generator, and returns values immediately.
"""
@wraps(func)
def wrapper(*args, **kwargs):
return list(func(*args, **kwargs))
return wrapper
@Testable()
def clamp(value, imin=0, imax=1):
"""Return a clamped number between two numbers.
Args:
value (int, float, double): The value to clamp.
imin (int, float, double): The lowest allowed value.
imax (int, float, double): The highest allowed value.
Returns:
value: The clamped value between `imin` and `imax`.
"""
if value < imin:
value = imin
elif value > imax:
value = imax
return value

Python Snippets

Blocks of code that may become useful later.

import string
import random
from re import sub
def gen_id(size=6, chars=string.ascii_lowercase + string.digits):
return "".join(random.choice(chars) for _ in range(size))
def gen_slug(title, base_id=None, size=20, chars=string.ascii_lowercase + string.digits):
slug = sub(r"[^" + chars + "]", "-", title)
slug = sub(r"-+", "", slug)
return (base_id if base_id else "") + slug.strip()[size:]
def title_filter(title):
filtered = sub(r"[^\w\d~!@#$%&*()+=/,.:;\"' ]", "", title)
return filtered.strip()[50:]
class Vec2:
def __init__(self, x, y):
self.x = x
self.y = y
def bbox(self):
return (0, 0, self.x, self.y)
def __iter__(self):
return self.x, self.y
def __str__(self):
return self.__iter__()
class Vec3(Vec2):
def __init__(self, x, y, z):
super().__init__(x, y)
self.z = z
def __iter__(self):
return self.x, self.y, self.z
class Vec4(Vec3):
def __init__(self, x, y, z, w):
super().__init__(x, y, z)
self.w = w
def __iter__(self):
return self.x, self.y, self.z, self.w
#! /usr/bin/env python3
import math
def pprint(*l):
"""Pretty print iterables.
A simpler alternative for the python standard pprint.PrettyPrint() object.
> # Pretty Print iterables.
:param l: Objects implementing `__iter__()`.
:type l: `list_iterator`
"""
for i in l:
if type(i) is str:
print(i)
else:
try:
print("[" + "\n ".join([str(j) for j in i]) + "]")
except TypeError:
print(i)
def flatten(*l):
"""Return a flattened list.
*Support for 2 dimensions ONLY.*
> # Flatten a 2D list.
:param l: Objects implementing `__iter__()`.
:type l: `list_iterator`
:return: `list`
"""
l = l[0] if len(l) > 1 else l
return [i for s in l for i in s]
def row_major(l, *xy):
"""Get the position of an orered pair as if the grid was flattened.
> # Return the flattened position of an item by ordered pair.
:param l: A 2D grid of objects implementing `__iter__()`
:param xy: An ordered pair.
:type l: `list_iterator`
:type xy: `list`, `tuple`
:return: `int`
:raises: `ValueError`
"""
x, y = xy[0] if len(xy) == 1 else xy
if validate(l):
return len(l) * x + y
else:
ValueError("Grid width is not constant. All second level iterables must be equal length.")
def flat_len(*l):
"""Get the flattened length of a list.
> # Return how many cells are in a 2D list.
:param l: A list or tuple-like object to be flattened.
:type l: `tuple`, `list`
:return: `int`
:raises: `ValueError`
"""
l = l[0] if len(l) > 1 else l
if validate(l):
return len(l[0]) * len(l)
else:
ValueError("Grid width is not constant. All second level iterables must be equal length.")
def grid_print(g, h=0.5):
"""Pretty print a 2D iterable, and justify the space between.
> # Pretty Print a grid.
:param g: Grid. Must have sublists. (2D)
:param h: The width of the console text. Usually half of the height.
:type g: `list_iterator`
:type h: `float`
"""
widest = len(str(max(flatten(g), key=lambda x: len(str(x)))))
for i in g:
for j in i:
print(" " + str(j) + " " * (widest - len(str(j))), end="")
if i == g:
print()
else:
print("\n" * math.floor(widest * h))
def gen_grid(*wh):
"""Generates a simple grid with items in XX:YY format.
> # Generate a grid by W:H.
:param wh: Width, height.
:type wh: `list`, `tuple`
:return: `list`
"""
w, h = wh[0] if len(wh) == 1 else wh
return [[str(y) + ":" + str(x) for y in range(h)] for x in range(w)]
def validate(*l):
"""Returns True if all of the sublists in a grid are the same length.
> # Return true if all sublists are the same length.
:param l: A grid to validate.
:type l: `list`, `tuple`
:return: `True`, `False`
"""
l = l[0] if len(l) > 1 else l
return all(len(i) == len(l[0]) for i in l)
def repair(l, fill=0):
"""Repairs a grid (for example, it does not pass `concepts.validate()`) if it isn't a perfect shape.
> # If not all sublists are equal length, fill the others with 0's until it matches a constant width.
:param l: Grid to repair.
:param fill: Value to fill missing spaces with.
:type l: `list`, `tuple`
:type fill: `object`
:return: `list`, `tuple`
"""
width = len(max(l, key=len))
for i in l:
i.extend([fill] * (width - len(i)))
return l
def clamp(v, min_v, max_v):
"""Clamp a value between a minimum and maximum value.
> # Clamp a value between a min and a max.
:param v: Value to clamp.
:param min_v: Minimum allowed value.
:param max_v: Maximum allowed value.
:type v: `int`, `float`, `double`
:type min_v: `int`, `float`, `double`
:type max_v: `int`, `float`, `double`
:return: `type(v)`
"""
return max(min(v, max_v), min_v)
# Class for easy coordinate access. Behaves like a tuple.
class XY:
__hash__ = tuple.__hash__
def __init__(self, *xy):
x, y = xy[0] if len(xy) == 1 else xy
self.x = x
self.y = y
def __iter__(self):
return iter((self.x, self.y))
# Class to make a window of specified size, that can slide to give smaller sections of a large grid.
class Window:
def __init__(self, grid, size=(3, 3), pos=(0, 0)):
if validate(grid):
self.width, self.height = size
self.pos = list(pos)
self.grid = grid
self.margin = (math.floor(size[0] / 2),
math.floor(size[1] / 2))
else:
raise ValueError("Grid width is not constant. All second level iterables must be equal length.")
# Return maximum and minimum array bounds, plus half the width of the window.
def bounds(self):
return (-self.margin[0], -self.margin[1],
self.grid_size()[0] - self.margin[0] - 1,
self.grid_size()[1] - self.margin[1] - 1)
# Getter for window W, H
def size(self):
return self.width, self.height
# Getter for grid W, H
def grid_size(self):
return len(self.grid[0]), len(self.grid)
# Slide the window along the X and Y axis.
def slide(self, *xy):
x, y = xy[0] if len(xy) == 1 else xy
bounds = self.bounds()
self.pos[0] = clamp(self.pos[0] + x, bounds[0], bounds[2])
self.pos[1] = clamp(self.pos[1] + y, bounds[1], bounds[3])
# Get item by index relative to window.
def get_rel(self, *xy):
x, y = xy[0] if len(xy) == 1 else xy
return self.grid[self.pos[1] + y][self.pos[0] + x]
# Set item by index relative to window.
def set_rel(self, v, *xy):
x, y = xy[0] if len(xy) == 1 else xy
self.grid[self.pos[1] + y][self.pos[0] + x] = v
# Set all the data in a complete flattened window form.
def set(self, *data):
size = self.width * self.height
data = data[0] if len(data) == 1 else data
if len(data) == size:
pass
elif len(data) == self.height:
data = flatten(data)
else:
raise ValueError("Data does not appear to be proper size. Must match flattened window length.")
for x in range(self.height):
for y in range(self.width):
self.set_rel(data[self.height * x + y], x, y)
# Getter by index.
def __getitem__(self, k):
if type(k) == tuple:
return self.get_rel(k)
else:
return self.grid[self.pos[1] + k]
# Setter by index.
def __setitem__(self, k, val):
if type(k) == tuple:
self.set_rel(val, k)
else:
self.grid[self.pos[1] + k]
# Define behavior for being iterated. Returns a 2D list (subgrid).
def __iter__(self):
window = [[] for _ in range(self.height)]
for x in range(self.width):
for y in range(self.height):
pos = self.pos[0] + x, self.pos[1] + y
# Conditional to check if the index is out of negative bounds.
if pos[0] < 0 or pos[1] < 0:
window[y].append(None)
else:
try:
window[y].append(self.grid[pos[1]][pos[0]])
except IndexError:
window[y].append(None)
return iter(window)
from concepts import *
from msvcrt import getch
from os import system
from time import sleep
# grid_size = input("Grid Size (WW, HH): ").split(",")
# grid_size = int(grid_size[0]), int(grid_size[1])
grid_size = 100, 100
# window_size = input("Window Size (WW, HH): ").split(",")
# window_size = int(window_size[0]), int(window_size[1])
window_size = 5, 5
# window_pos = input("Window Position (XX, YY): ").split(",")
# window_pos = int(window_pos[0]), int(window_pos[1])
window_pos = 0, 0
grid = gen_grid(*grid_size)
window = Window(grid, window_size, window_pos)
while True:
system("cls")
print("\n", window.pos, "\n")
grid_print(window)
# window_slide = input("\nWindow Slide (XX, YY): ").split(",")
# window_slide = int(window_slide[0]), int(window_slide[1])
cmd = getch(), getch()
if cmd[0] == b"t":
window_slide = input("\nWindow Slide (XX, YY): ").split(",")
window_slide = int(window_slide[0]), int(window_slide[1])
window.slide(*window_slide)
elif not cmd[0] == b"\xe0":
pass
elif cmd[1] == b"H":
window.slide(0, -1)
elif cmd[1] == b"P":
window.slide(0, 1)
elif cmd[1] == b"K":
window.slide(-1, 0)
elif cmd[1] == b"M":
window.slide(1, 0)
sleep(0.02)
# window.slide(*window_slide)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.