Compare commits

...
6 Commits
Author SHA1 Message Date
Julien Le Coupanec 774445f646 Merge pull request #472 from Ezra-Zhao/add-jq-cheatsheet
Add jq cheatsheet
2026-10-17 16:11:21 +02:00
Julien Le Coupanec e98d62843b Merge pull request #471 from Ezra-Zhao/add-ffmpeg-cheatsheet
Add FFmpeg cheatsheet
2026-10-17 16:10:48 +02:00
Julien Le Coupanec 554e41499e Merge pull request #470 from alapha888/add-code-review-cheatsheet
Add code review cheat sheet
2026-10-17 16:09:04 +02:00
Ezra Zhao 7d259abaff Add jq cheatsheet 2026-10-15 07:11:07 -07:00
Ezra Zhao 6a33d6a63a Add FFmpeg cheatsheet 2026-10-15 07:10:35 -07:00
alapha888 2f67cde7cd Add code review cheat sheet 2026-10-09 08:43:22 +00:00
4 changed files with 227 additions and 0 deletions

No files matched your search

+3
View File
@@ -119,10 +119,13 @@ Feel free to take a look. You might learn new things. They have been designed to
#### Development
- [cURL](tools/curl.sh)
- [Code Review](tools/code_review.md)
- [Drush](tools/drush.sh)
- [Elasticsearch](tools/elasticsearch.js)
- [Emmet](tools/emmet.md)
- [FFmpeg](tools/ffmpeg.sh)
- [Git](tools/git.sh)
- [jq](tools/jq.sh)
- [Puppeteer](tools/puppeteer.js)
- [Sublime Text](tools/sublime_text.md)
- [VIM](tools/vim.txt)
+88
View File
@@ -0,0 +1,88 @@
# Code Review
> Will this code become someone else's problem within three months?
## Core Rules
- Walk the five axes in priority order: **Correctness → Security → Readability → Performance → Tests**.
- Each axis is graded **pass / fail / N-A**.
- **Concrete-fix rule**: Every failure must include an exact line reference and a concrete fix.
- **Max 10 comments**: >10 issues means reject and ask for resubmission, not a 50-item grade sheet.
- **No style policing**: Formatting, quotes, and spacing belong to linters.
## Scope
| Diff size | Action |
| --- | --- |
| ≤ ~400 lines | Review normally |
| > ~400 lines | Request a split first; review quality collapses on large diffs |
## The Five Axes
### 1. Correctness (Blocks merge)
- Edge cases handled: null, empty, zero, negative, boundary/oversized input.
- Concurrency and timing assumptions hold; no race conditions.
- Errors and exceptions handled explicitly, never swallowed.
### 2. Security (Blocks merge)
- No user input concatenated into SQL, shell commands, or HTML.
- No hard-coded secrets, tokens, or credentials.
- Logs and error messages do not leak sensitive data or PII.
### 3. Readability
- Descriptive names; functions have a single responsibility.
- Magic numbers are extracted into named constants.
- Flag only incomprehensible logic, not personal style preferences.
### 4. Performance
- No repeated queries, allocations, or recomputations inside loops.
- No N+1 query patterns across boundaries.
- No data-free speculation ("this might be slow" is invalid feedback).
### 5. Test Coverage
- New logic and modified paths have automated tests.
- Edge cases and failure modes have dedicated test cases.
- All-green suites that miss critical paths get sent back.
## Writing Comments
### Fixed Format
```text
[severity][axis] file:line problem → suggested fix
```
**Examples:**
```text
[Must fix][Correctness] order.py:87 empty order list raises IndexError → guard before taking [0]
[Should fix][Readability] order.py:92 magic number 86400 → name it SECONDS_PER_DAY
```
### Triage
| Label | Axes | Blocks merge? |
| --- | --- | --- |
| Must fix | Correctness, Security | Yes |
| Should fix | Readability, Performance, Tests | No (say so explicitly) |
## Anti-patterns
| Anti-pattern | Failure mode |
| --- | --- |
| Drive-by LGTM | Approving before reading the whole diff |
| Style policing | Nits on quotes while logic defects slip through |
| Vague feedback | "This looks off" without line number or fix |
| Speculative perf | Blocking code on unmeasured performance worries |
| 50-item grading | Teaching in review instead of sending back to rewrite |
## Quick Checklist
```markdown
- [ ] Scope: diff ≤ ~400 lines (split if larger)
- [ ] Correctness: edge cases handled, exceptions caught, no races
- [ ] Security: input sanitized, no secrets, no sensitive logs
- [ ] Readability: clear names, single responsibility, no magic numbers
- [ ] Performance: no loop queries/N+1, no unverified perf speculation
- [ ] Tests: new paths covered, edge cases tested
- [ ] Fixes: every comment has file:line and a concrete fix (max 10)
```
+67
View File
@@ -0,0 +1,67 @@
##############################################################################
# FFMPEG — TRANSCODE
##############################################################################
ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp4 # Anything -> MP4 (H.264 + AAC), plays everywhere
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 2M -c:a libopus output.webm # MP4 -> WebM (VP9 + Opus) for the web
ffmpeg -i input.mkv -c copy output.mp4 # Remux only: change container, no re-encoding, no quality loss
##############################################################################
# FFMPEG — COMPRESSION & QUALITY
##############################################################################
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k output.mp4 # Compress with CRF (18 = high quality, 28 = small file, 23 = sweet spot)
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset slow output.mp4 # Slower preset = smaller file at same quality
ffmpeg -y -i input.mp4 -c:v libx264 -b:v 1M -pass 1 -an -f null /dev/null # Two-pass encoding, pass 1 (analysis, no audio)
ffmpeg -i input.mp4 -c:v libx264 -b:v 1M -pass 2 -c:a aac -b:a 128k output.mp4 # Two-pass encoding, pass 2 (hits a target size precisely)
##############################################################################
# FFMPEG — AUDIO
##############################################################################
ffmpeg -i input.mp4 -vn -c:a libmp3lame -q:a 2 audio.mp3 # Extract audio as MP3 (-vn = no video, -q:a 2 = high VBR quality)
ffmpeg -i input.mp4 -vn -c:a aac -b:a 192k audio.m4a # Extract audio as M4A (AAC)
ffmpeg -i input.mp4 -vn -c:a copy audio.aac # Extract audio without re-encoding (fastest, codec must fit container)
ffmpeg -i video.mp4 -i new_audio.mp3 -c:v copy -c:a aac -map 0:v:0 -map 1:a:0 -shortest output.mp4 # Replace a video's audio track
##############################################################################
# FFMPEG — GIF
##############################################################################
ffmpeg -i input.mp4 -vf "fps=10,scale=480:-1:flags=lanczos,palettegen" palette.png # Step 1: generate an optimized color palette
ffmpeg -i input.mp4 -i palette.png -filter_complex "fps=10,scale=480:-1:flags=lanczos[x];[x][1:v]paletteuse" output.gif # Step 2: render the GIF with that palette
##############################################################################
# FFMPEG — CUT & JOIN
##############################################################################
ffmpeg -ss 00:01:30 -i input.mp4 -t 00:00:30 -c copy clip.mp4 # Fast cut: 30s clip from 1:30 (-ss before -i seeks fast)
ffmpeg -i input.mp4 -ss 00:01:30 -t 00:00:30 -c:v libx264 -c:a aac clip.mp4 # Frame-accurate cut (re-encodes, slower)
ffmpeg -f concat -safe 0 -i list.txt -c copy joined.mp4 # Join videos losslessly (list.txt: one "file 'x.mp4'" per line; same codec required)
##############################################################################
# FFMPEG — SCALE, CROP, OVERLAY
##############################################################################
ffmpeg -i input.mp4 -vf "scale=1280:720" -c:a copy output.mp4 # Scale to exactly 720p
ffmpeg -i input.mp4 -vf "scale=640:-2" output.mp4 # Scale by width, keep aspect ratio (-2 = even height, H.264 needs even dimensions)
ffmpeg -i input.mp4 -vf "crop=640:480:100:50" output.mp4 # Crop a 640x480 region starting at (100, 50)
ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=W-w-10:10" -c:a copy output.mp4 # Watermark in the top-right corner (10px margin)
ffmpeg -i input.mp4 -vf "subtitles=subs.srt" -c:a copy output.mp4 # Burn subtitles into the video (needs a libass build)
##############################################################################
# FFMPEG — FRAMES & STREAMING
##############################################################################
ffmpeg -ss 00:00:05 -i input.mp4 -vframes 1 poster.jpg # Extract one frame at 5s (video thumbnail / poster)
ffmpeg -i input.mp4 -vf fps=1 frame_%03d.jpg # Dump one JPEG per second (frame_001.jpg, frame_002.jpg, ...)
ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f flv rtmp://live.example.com/app/STREAM_KEY # Push to an RTMP server (-re = read at native frame rate)
# Full command reference: https://ffmpeg.org/documentation.html
# Trilingual (EN/ES/PT) extended version: https://github.com/Ezra-Zhao/ffmpeg-cheatsheet
+69
View File
@@ -0,0 +1,69 @@
##############################################################################
# JQ — BASICS
##############################################################################
jq '.' data.json # Pretty-print JSON (identity filter)
jq '.name' data.json # Get one field
jq -r '.name' data.json # Raw output: no quotes around strings (for shell pipelines)
jq -c '.users[]' data.json # Compact output: one JSON value per line
echo '{"a":1}' | jq '.' # jq reads stdin too — this is how it composes with curl
##############################################################################
# JQ — NESTED DATA & ARRAYS
##############################################################################
jq '.owner.email' data.json # Nested field access
jq '.users[0]' data.json # First array element ([-1] = last)
jq '.users[]' data.json # Iterate: emit every element
jq '.users[].name' data.json # One field from every element
jq '.users | length' data.json # Count elements (works on arrays, objects, strings)
##############################################################################
# JQ — FILTERING WITH select
##############################################################################
jq '.users[] | select(.age > 18)' data.json # Keep elements matching a condition
jq '.users[] | select(.city == "Seattle")' data.json # String equality
jq '.users[] | select(.age > 18 and .active)' data.json # Combine conditions (and / or / not)
jq '.users[] | select(.name | test("^A"))' data.json # Regex test on a string field
##############################################################################
# JQ — RESHAPING WITH map & OBJECT CONSTRUCTION
##############################################################################
jq 'map(.name)' data.json # Array of just the names (input: a top-level array)
jq '.users | map({name, city})' data.json # Reshape: new objects with only these fields ({name} = shorthand for {name: .name})
jq '.users[] | {n: .name, senior: (.age >= 65)}' data.json # Build computed objects field by field
jq '[.users[] | select(.active)]' data.json # Collect filter results back into an array
##############################################################################
# JQ — STRINGS, NUMBERS, AGGREGATION
##############################################################################
jq '.price | tostring' data.json # Number -> string (tonumber goes the other way)
jq '.tags | join(", ")' data.json # Array of strings -> one string (split(",") reverses it)
jq '.users | sort_by(.age)' data.json # Sort an array of objects by a field
jq '.users | map(.city) | unique' data.json # Distinct values (unique sorts too)
jq '.users | group_by(.city) | map({city: .[0].city, count: length})' data.json # Group + count per group
jq '[.users[].age] | add' data.json # Sum an array of numbers (add also concatenates strings/arrays)
jq '.users | max_by(.age)' data.json # Element with the max field (min_by for the min)
##############################################################################
# JQ — KEYS & REAL-WORLD PIPELINES
##############################################################################
jq 'keys' data.json # List an object's keys (sorted)
jq 'has("email")' data.json # Does the key exist? (use .users[0] | has("email") for elements)
jq 'del(.password)' data.json # Remove a field (e.g. before sharing output)
curl -s https://api.github.com/users/octocat | jq '{login, followers}' # Shape a live API response in one line
jq -r '.[] | select(.level == "error") | .msg' app.log.json # Extract error messages from JSON logs
jq --arg v "2.4.1" '.version = $v' data.json # Pass a shell value safely with --arg (never string-interpolate JSON by hand)
jq -s '.' part1.json part2.json # --slurp: merge multiple JSON files into one array
# Manual: https://jqlang.github.io/jq/manual/
# Trilingual (EN/ES/PT) extended version: https://github.com/Ezra-Zhao/jq-cheatsheet