Trans Scend Survival

Trans: Latin prefix implying "across" or "Beyond", often used in gender nonconforming situations – Scend: Archaic word describing a strong "surge" or "wave", originating with 15th century english sailors – Survival: 15th century english compound word describing an existence only worth transcending.

I wrote a mutual aid mental health service

Check out this project here: https://tetrahedron.gay/

 

There are a few goals of this experimental humanitarian project:
  • recreate the structure group therapy offers; to do this, we host a daily wakeup call at ~8:30 every day via Discord.   Any member with the ‘wakeup-call’ attribute is empowered to initiate, join and call (and- if needed- delegate further wakeup calls, via any means necessary- phone call, discord, email, DMs, doordash coffee delivery to your peer, knock on their door, call their neighbors, drone strike etc) .   I intend to write a utility to automate wakeup phone calls and allow users to securely wake each other up without having their personal info (phone #, address etc).
  • recreate and extend the social and interpersonal aspects of a group therapy program through in-person activities as well as virtual, peer led group sessions
  • experiment with horizontal organization structures with minimal hierarchical organization in  a traditionally stratified space; enable the trusting reliance of individuals to guide group moderation while protecting personal info.

A little financial reporting CLI from the bus

I wrote this lil command line application while riding on a bus to and from New York City- find the project repository here at jesssullivan/AccuWixReport. 😸

This utility generates a variety of concise, merged monthly financial superlative reports in raw markdown, drawing from transaction CSVs exported by Acuity and Wix.

  • “Paid” transaction reports are marked as “paid” by the respective platforms (automatically via credit card or manually upon receiving otherwise untracked currency)
  • “Unpaid” transaction reports were not explicitly marked as “paid”; while the most likely scenario is that this transaction was completed successfully offline (via cash / venmo), an “Unpaid” status may imply the client did not settle up or the transaction was recorded erroneously due to cancellation, revision or other extenuating circumstances.

Intended usage:

Setup:

python3.12 -m venv accuwix_venv
source accuwix_venv/bin/activate
pip install -r requirements.txt

Generate and print report for January:

 python3 src/cmdline.py -m Jan

Generate and save all reports to markdown file:

 python3 src/cmdline.py -all > AccuWixReport.md

Generate a sexy PDF report from markdown file:

pandoc AccuWixReport.md -o output.pdf -V geometry:margin=1in

Display help screen:

usage: 
 -h   : print this message again 
 -all : generate all reports 
 -m   : `month` (optional); specify a month to generate a superlative report`  

 use any of the following month qualifiers: 
 Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec

Lets write a simple, efficient and fast flask-based image server in an afternoon

….that uses lanczos resampling to serve optimized cached photos.

Find this project on GitHub here: jesssullivan/FastPhotoAPI

Interact with this API graphically here (hosted on koyeb via Docker): https://api.birdphoto.website/

Structure:

This application adopts the factory pattern; `flask run` instantiates the built-in development server by executing `create_app()` at the root of the `app/` package, while `python application.py` creates a new production application, served by waitress.

git clone https://github.com/Jesssullivan/FastPhotoAPI && cd FastPhotoAPI
python3.12 -m venv fast_photo_venv
source fast_photo_venv/bin/activate
pip install -r requirements.txt

Structure:

├── app
├── __init__.py # create and serve development application
└── main
├── config
│ │ └── config.cfg # set directories, max image dimensions, etc
│ ├── fullsize
│ │ └── routes.py # Blueprint routing for serving verbatim image files
│ ├── __init__.py # `create_app()` entrypoint
│ ├── resampled
│ │ ├── model.py # Image resampling methods
│ │ └── routes.py # Blueprint routing for `/image/`
│ └── static
│ └── routes.py # Blueprint routing for `/static/`
├── application.py # create and serve production application w/ waitress
├── cache # resampled images are dynamically generated adn stored here
├── Dockerfile # currently deployed at Koyeb
├── pictures # full res pictures go here
├── README.md # you are here
├── static
│ └── style.css # index styling
└── templates
├── index.html
└── upload.html

Build:

Locally:

# dev WSGI:
flask run # 0.0.0.0:5000
# waitress WSGI:
flask run # 0.0.0.0:8000
Production via Docker:

## build production docker image:
# docker build -t <srv>.

## serve production docker image locally:
docker run -d -p 8000:8000 <srv>:latest

## stop local image:
# docker ps
# docker stop

## push image to a container registery:
# docker push <srv>

Basic Usage:
– Fetch a resampled & cached image `/image/<yourimage>`
– Fetch the original, unmodified image `/full/<yourimage>`

Turkey Probe

A spur-of-the moment turkey thermometer with dubious accuracy, questionable code and unhelpful complexity made of random gahbage.

Uses Steinhart-Hart equation to estimate the temperature from the 8266’s analog pin (this board has a single channel 10 bit ADC) produced by a 100k 104GT-2/104NT-4 thermistor using 10k pullup resistor. The ESP 8266 serves a real-time temperature readout via a websocket connection over the local network.   Find this ridiculous project of mine on Github here: https://github.com/Jesssullivan/turkeyprobe

Turkey Probe in action during thanksgiving

Just moments before thanksgiving

smol updates – November 9 2022

  • This winter, I am excited to be teaching a new youth-oriented class at the Odessa Public Library- "TinkerCAD for Functional 3d Printing & Propmaking"! Sign up here: https://ithacagenerator.org/tinkercad
    "Youth ages 8-18 will master the tools and skills required to design and print just about anything made of plastic, and will be confident in their ability to search for projects and models others have designed and print them at the Odessa Public Library."
  • I’ve been fairly distant for the last few months, but not for a lack of exciting projects! I’ve been sorta hyperfocused on the research and development of ultrasonically emulsified polyethylene polymers for an upcoming and very exciting material brand of my own.

Makerspace financial reporting w/ ipython

Visit this project on github here

  • Merge PayPal & Membershipworks members in a sorta intelligent way to create kinda accurate financial reports
  • Convert a PayPal transaction export into an upsert-able csv to import into membershipworks
  • Keep tabs on PayPal memberships as they become deprecated

(note, you’ll need nbconvert, pandoc, TeX to write to pdf)

…If all goes well, the output will look something like:

loaded **** paypal records
loaded ** existing membershipworks records
converted Date column to datetime objects
kept *** records processed between 01/01/22 and 22/11/21; discarded **** records
discarded **'s Donation Payment record for **, continuing...
discarded **'s PreApproved Payment Bill User Payment record for **, continuing...
** ** already in member list! continuing...
discarded ** **'s Payment Refund record for -**.00, continuing...
discarded ** **'s Donation Payment record for **.00, continuing...
exported: ** Members!
 - ** Standard Members
 - ** Offline Standard Members
 - ** Extra Members
 - ** Offline Extra Members
 ...to a membershipworks-readable format at ./csv/membershipworks_import.csv

This and that, bits and bobs…

Afternoon scribbles & prints:
…Continuing to fix Jess and Cloud’s New York nest with PLA:
…Experimental microphone hardware for Merlin Sound ID:
YMMV, but YOLO: 3d printing @ IG repo and docs:
…A variety of improvements and updates to the chrome remote desktop automatic patching repo for Ubuntu Budgie

Continue reading

Bits & Bobs, Mushstools & Toadrooms

…Despite being a chilly & wintery March up here in the White Mountains, there is no shortage of fun birds and exciting projects!

Merlin AI pipeline for Mushroom identification!

It’s happening, and it is going to be awesome YMMV, but YOLO:

Continue reading

Annotators, interpreters & audio demo stuff

…Notes, Repo

….Even more demos @ ai.columbari.us

miscellaneous dregs, bits, bobs, demos in this playlist on youtube

Continue reading

Chindōgu ASCII art

A ridiculous Chindōgu utility prompt & CLI for fetching private releases & files from GitHub & BitBucket

  • Fetch, unpack, extract specific releases & files or a complete master branch from a private GitHub repo with an api access token
  • Fetch and extract specific files or complete branches from a private BitBucket account with user’s git authentication
  • Prefill default prompt values with a variety of console flags
  • Save & load default prompt values with a file of environment variables, see templates FetchReleasegSampleEnv_GitHub, FetchFilegSampleEnv_BitBucket, FetchEverythingSampleEnv_BitBucket, FetchEverythingSampleEnv_GitHub; pass as an argument with the -e flag, (./LeafletSync -e YourEnvFile) or provide one on launch.
curl https://raw.githubusercontent.com/Jesssullivan/LeafletSync/main/LeafletSync --output LeafletSync && chmod +x LeafletSync && ./LeafletSync

Continue reading

naive distance measurements with opencv

Knowing both the Field of View (FoV) of a camera’s lens and the dimensions of the object we’d like to measure (Region of Interest, ROI) seems like more than enough to get a distance.

Note, opencv has an extensive suite of actual calibration tools and utilities here.

…But without calibration or much forethought, could rough measurements of known objects even be usable? Some notes from a math challenged individual:

# clone:
git clone https://github.com/Jesssullivan/misc-roi-distance-notes && cd misc-roi-distance-notes

Most webcams don’t really provide a Field of View much greater than ~50 degrees- this is the value of a MacBook Pro’s webcam for instance. Here’s the plan to get a Focal Length value from Field of View:

So, thinking along the lines of similar triangles:

  • Camera angle forms the angle between the hypotenuse side (one edge of the FoV angle) and the adjacent side
  • Dimension is the opposite side of the triangle we are using to measure with.
  • ^ This makes up the first of two "similar triangles"
  • Then, we start measuring: First, calculate the opposite ROI Dimension using the arbitrary Focal Length value we calculated from the first triangle- then, plug in the Actual ROI Dimensions.
  • Now the adjacent side of this ROI triangle should hopefully be length, in the the units of ROI’s Actual Dimension.

source a fresh venv to fiddle from:

# venv:
python3 -m venv distance_venv
source distance_venv/bin/activate

# depends are imutils & opencv-contrib-python:
pip3 install -r requirements.txt

The opencv people provide a bunch of prebuilt Haar cascade models, so let’s just snag one of them to experiment. Here’s one to detect human faces, we’ve all got one of those:

mkdir haar
wget https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_alt2.xml  -O ./haar/haarcascade_frontalface_alt2.xml

Of course, an actual thing with fixed dimensions would be better, like a stop sign!

Let’s try to calculate the distance as the difference between an actual dimension of the object with a detected dimension- here’s the plan:

YMMV, but YOLO:

# `python3 measure.py`
import math
from cv2 import cv2

DFOV_DEGREES = 50  # such as average laptop webcam horizontal field of view
KNOWN_ROI_MM = 240  # say, height of a human head  

# image source:
cap = cv2.VideoCapture(0)

# detector:
cascade = cv2.CascadeClassifier('./haar/haarcascade_frontalface_alt2.xml')

while True:

    # Capture & resize a single image:
    _, image = cap.read()
    image = cv2.resize(image, (0, 0), fx=.7, fy=0.7, interpolation=cv2.INTER_NEAREST)

    # Convert to greyscale while processing:
    gray_conv = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray_conv, (7, 7), 0)

    # get image dimensions:
    gray_width = gray.shape[1]
    gray_height = gray.shape[0]

    focal_value = (gray_height / 2) / math.tan(math.radians(DFOV_DEGREES / 2))

    # run detector:
    result = cascade.detectMultiScale(gray)

    for x, y, h, w in result:

        dist = KNOWN_ROI_MM * focal_value / h
        dist_in = dist / 25.4

        # update display:
        cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2)
        cv2.putText(image, 'Distance:' + str(round(dist_in)) + ' Inches',
                    (5, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
        cv2.imshow('face detection', image)

        if cv2.waitKey(1) == ord('q'):
            break

run demo with:

python3 measure.py

-Jess

« Older posts

© 2024 Trans Scend Survival

α wιρ Σ ♥ by Jess SullivanUp ↑