Skip to content

Instantly share code, notes, and snippets.

@nwjlyons
nwjlyons / roman_numeral.ex
Last active June 12, 2023 19:47
Converts a number to a roman numeral.
defmodule RomanNumeral do
@min_number 1
@max_number 3999
@type to_roman_error() :: :less_than_min_number | :greater_than_max_number
@spec to_roman(pos_integer()) :: {:ok, String.t()} | {:error, to_roman_error()}
@doc """
Converts a number to a roman numeral.
@nwjlyons
nwjlyons / list_view.ex
Last active August 4, 2022 21:11
Reusable Phoenix.LiveView
defmodule ListView do
@callback query(socket :: Phoenix.LiveView.Socket.t()) :: Ecto.Query.t()
defmacro __using__(opts \\ []) do
quote bind_quoted: [opts: opts] do
opts = Keyword.validate!(opts, [:repo, :schema, :per_page])
@repo Keyword.fetch!(opts, :repo)
@schema Keyword.get(opts, :schema)
@per_page Keyword.get(opts, :per_page, 10)
@nwjlyons
nwjlyons / queryset.py
Created April 12, 2021 13:54
Django QuerySet function that will return up to `max_length` objects from the `selected` queryset, falling back to the `fallback` queryset to make up the numbers.
def get_selected_or_fallback(*, selected: QuerySet, fallback: QuerySet, max_length: int) -> list:
"""
Return up to `max_length` objects from the `selected` queryset,
falling back to the `fallback` queryset to make up the numbers.
"""
selected = list(selected[:max_length])
fallback = list(fallback.exclude(id__in=[obj.id for obj in selected])[:max_length])
return (selected + fallback)[:max_length]
@nwjlyons
nwjlyons / circle.py
Last active April 5, 2021 20:16
Plot points along circumference using Trigonometry
import math
radius = 20
circumference_points_ratios = [(math.cos(degree), math.sin(degree)) for degree in range(360)]
circumference_points = [(x * radius, y * radius) for x, y in circumference_points_ratios]
circumference_points_ints = [(int(x), int(y)) for x, y in circumference_points]
for y in range(-30, 30):
@nwjlyons
nwjlyons / index.py
Last active November 4, 2022 19:49
CGI Python Example
#! /usr/bin/env python
print("""Content-Type: text/html
<h1>Hello World</h1>""")
@nwjlyons
nwjlyons / block_types_used_in_field.py
Created January 29, 2021 15:23
Determine what blocks are used in a Wagtail StreamField.
def block_types_used_in_field(queryset, field_name: str) -> set:
used_block_types = set()
for page in queryset:
for block in getattr(page, field_name):
used_block_types.add(block.block_type)
return used_block_types
# block_types_used_in_field(BlogPage.objects.all(), 'body')
@nwjlyons
nwjlyons / data.txt
Created December 10, 2020 18:33
Advent Of Code Day Four Part Two
ecl:hzl byr:1926 iyr:2010
pid:221225902 cid:61 hgt:186cm eyr:2021 hcl:#7d3b0c
hcl:#efcc98 hgt:178 pid:433543520
eyr:2020 byr:1926
ecl:blu cid:92
iyr:2010
iyr:2018
eyr:2026
@nwjlyons
nwjlyons / integer_float.py
Last active August 19, 2023 10:04
Python isinstance checks behave differently from type annotations
>>> isinstance(1, int)
True # 👍
>>> isinstance(1, float)
False # 👍
>>> isinstance(1.0, int)
False # 👍
>>> isinstance(1.0, float)
@nwjlyons
nwjlyons / main.py
Last active April 5, 2021 20:22
Regression to the mean
import random
from collections import Counter
def regression_to_the_mean(n):
data = [random.randint(1, 10) for x in range(n)]
return sum(data) // len(data)
# 10
Counter([regression_to_the_mean(10) for x in range(50)]).most_common()
@nwjlyons
nwjlyons / irrational_numbers.ex
Last active August 17, 2020 09:59
Taking the square root of each number from 1 to 100, which of them are irrational
Enum.reject 1..100, fn i ->
square_root = Decimal.sqrt(i)
remainder = Decimal.rem(square_root, 1)
Decimal.eq?(remainder, 0)
end