Skip to content

Instantly share code, notes, and snippets.

View martin-ueding's full-sized avatar

Martin Ueding martin-ueding

View GitHub Profile
@martin-ueding
martin-ueding / jtbd.md
Last active July 19, 2026 07:51
JTBD Maintenance Tracker

Jobs-to-be-Done — bicycle-maintenance-playground

Reverse-engineered from app/maintenance.py, app/models/database.py, and the templates. Intended as the spec for a SQLAlchemy-based reimplementation inside Geo Activity Playground, not a description of the current code's structure.

Data source dependency

  • JTBD-0: Resolve "which bikes exist and their total distance" by joining equipments/activities in the geo-activity-playground database (equipments.name, SUM(activities.distance_km)). This is the integration seam — in GAP it should become a direct SQLAlchemy relationship/query, not a second SQLite file being cross-joined by raw path.

Repairs & Upgrades ("maintenance" entries) — ad-hoc, one-off log

  • JTBD-1: Log a one-off maintenance/repair/upgrade event for a bike: description, date, odometer km at time of event, cost, optional photo (+ auto-generated thumbnail).
  • JTBD-2: Record an optional "next due" reminder on that same entry (next_due_km and/or next_due_date) — a lightweight u
[style]
# Align closing bracket with visual indentation.
align_closing_bracket_with_visual_indent=True
# Allow dictionary keys to exist on multiple lines. For example:
#
# x = {
# ('this is the first element of a tuple',
# 'this is the second element of a tuple'):
# value,
@martin-ueding
martin-ueding / scm_prompt.sh
Created May 6, 2020 12:55
Version control prompt
#!/bin/bash
# Copyright © 2012 Martin Ueding <dev@martin-ueding.de>
# This script has been placed in the public domain via the CC0 license:
# https://creativecommons.org/publicdomain/zero/1.0/
# Checks the current working directory for a git, bzr (or svn or hg, …) tree
# and displays the apropriate name. If the status is supposed to be displayed,
# a ``bzr status`` is run. Git features the ``__git_ps1``, which is used instead in
# case a git repo is found.
# Copyright © 2015 Martin Ueding <mu@martin-ueding.de>
font := /usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-R.ttf
diag := $(wildcard *.diag)
pdf := $(diag:.diag=.pdf)
svg := $(diag:.diag=.svg)
all: $(pdf) $(svg)
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Copyright © 2016 Martin Ueding <mu@martin-ueding.de>
import argparse
stacks = [
[4, 3, 2, 1],
module lightdm-utab 1.0;
require {
type unlabeled_t;
type mount_var_run_t;
type home_root_t;
type xdm_t;
class file { append create getattr read write open };
class dir { create write setattr };
}
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Copyright © 2015-2016 Martin Ueding <mu@martin-ueding.de>
# Licensed under The MIT License
import argparse
import jinja2
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Copyright © 2016 Martin Ueding <mu@martin-ueding.de>
import argparse
import re
import subprocess
PATTERN = re.compile(r'Boot([0-9A-F]{4})\*?\s+([^\t]+)\s(\S+)')
// Copyright © 2016 Martin Ueding <mu@martin-ueding.de>
// Test the cost of various time implementations.
#include <mpi.h>
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
module mycube() {
cube(size = 20, center = true);
};
module myplane(thickness) {
color("black", alpha = 0.1)
rotate([0, 0, 180])
rotate([0, 0, 135])
rotate([-145, 0, 0])
translate([-20, 0, -20])