Compare commits
4 Commits
73cfc7cf13
...
d54543b160
| Author | SHA1 | Date | |
|---|---|---|---|
| d54543b160 | |||
| b939e70084 | |||
| a45e1e9585 | |||
| a94ec30f08 |
32
CLAUDE.md
Normal file
32
CLAUDE.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# homelab-dsa-tutoring
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This is a collection of Python projects for a tutoring side-gig focused on Data Structures and Algorithms (DSA).
|
||||||
|
|
||||||
|
It was previously deployed to a personal homelab server as a Tailscale file server (see `.github/workflows/deploy-homelab.yml`). The workflow SCP'd the repo to the server and ran a Docker Compose stack that served the files.
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
shared/
|
||||||
|
├── assignments/ # PDFs and other assignment materials
|
||||||
|
└── notes-and-examples/ # Lesson files organized by date (YYYY.MM.DD)
|
||||||
|
```
|
||||||
|
|
||||||
|
Each lesson folder under `notes-and-examples/` contains one or more Python files used during the tutoring session.
|
||||||
|
|
||||||
|
## Lessons
|
||||||
|
|
||||||
|
| Date | Topics |
|
||||||
|
|------|--------|
|
||||||
|
| 2026.01.21 | Sorting algorithms (bubble sort, insertion sort) |
|
||||||
|
| 2026.01.28 | Object references, shallow/deep copies, linked lists |
|
||||||
|
| 2026.02.04 | Queue data structure |
|
||||||
|
| 2026.02.11 | Stack data structure |
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- No external dependencies — pure Python, no `requirements.txt` needed.
|
||||||
|
- Student homework submissions go to `me@bchen.dev`.
|
||||||
|
- Lesson files often include skeleton classes with method stubs for students to implement.
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"TCP": {
|
|
||||||
"443": {
|
|
||||||
"HTTPS": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Web": {
|
|
||||||
"dsa-tutoring-1.tail8f43b.ts.net:443": {
|
|
||||||
"Handlers": {
|
|
||||||
"/": {
|
|
||||||
"Path": "/shared"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowFunnel": {
|
|
||||||
"dsa-tutoring-1.tail8f43b.ts.net:443": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
services:
|
|
||||||
tailscale:
|
|
||||||
image: tailscale/tailscale:stable
|
|
||||||
container_name: tailscale-dsa-tutoring
|
|
||||||
hostname: dsa-tutoring
|
|
||||||
environment:
|
|
||||||
- TS_AUTHKEY=${TS_AUTHKEY}
|
|
||||||
- TS_STATE_DIR=/var/lib/tailscale
|
|
||||||
- TS_SERVE_CONFIG=/config/tailscale-serve-config.json
|
|
||||||
volumes:
|
|
||||||
- tailscale-dsa-tutoring-state:/var/lib/tailscale
|
|
||||||
- /dev/net/tun:/dev/net/tun # shared interface across all Tailscale instances
|
|
||||||
- ./config:/config
|
|
||||||
- ./shared:/shared
|
|
||||||
cap_add:
|
|
||||||
- NET_ADMIN
|
|
||||||
- SYS_MODULE
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
tailscale-dsa-tutoring-state:
|
|
||||||
Binary file not shown.
71
shared/notes-and-examples/2026.02.28/linked_list_solution.py
Normal file
71
shared/notes-and-examples/2026.02.28/linked_list_solution.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# Solution to 2026.01.28 homework
|
||||||
|
|
||||||
|
class Node:
|
||||||
|
prev_node: "Node | None" = None
|
||||||
|
next_node: "Node | None" = None
|
||||||
|
|
||||||
|
def __init__(self, value) -> None:
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
class LinkedList:
|
||||||
|
head: "Node | None" = None
|
||||||
|
tail: "Node | None" = None
|
||||||
|
|
||||||
|
def append(self, thing):
|
||||||
|
if self.head==None:
|
||||||
|
self.head=Node(value=thing)
|
||||||
|
self.tail=self.head
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.tail is not None:
|
||||||
|
self.tail.next_node=Node(value=thing)
|
||||||
|
if self.tail.next_node is not None:
|
||||||
|
self.tail.next_node.prev_node = self.tail
|
||||||
|
self.tail=self.tail.next_node
|
||||||
|
|
||||||
|
def prepend(self, thing):
|
||||||
|
previous_head = self.head
|
||||||
|
self.head = Node(value=thing)
|
||||||
|
self.head.next_node = previous_head
|
||||||
|
|
||||||
|
if previous_head is not None:
|
||||||
|
previous_head.prev_node = self.head
|
||||||
|
|
||||||
|
def insert(self, thing, index):
|
||||||
|
current_node = self.head
|
||||||
|
if current_node is None:
|
||||||
|
self.append(thing)
|
||||||
|
return
|
||||||
|
|
||||||
|
if index == 0:
|
||||||
|
self.prepend(thing)
|
||||||
|
return
|
||||||
|
|
||||||
|
for _ in range(1, index):
|
||||||
|
if current_node is not None:
|
||||||
|
current_node = current_node.next_node
|
||||||
|
if current_node is None:
|
||||||
|
raise IndexError
|
||||||
|
|
||||||
|
prev_next = current_node.next_node
|
||||||
|
current_node.next_node = Node(thing)
|
||||||
|
current_node.next_node.prev_node = current_node
|
||||||
|
current_node.next_node.next_node = prev_next
|
||||||
|
|
||||||
|
|
||||||
|
def print_list(self):
|
||||||
|
current_node = self.head
|
||||||
|
while current_node is not None:
|
||||||
|
print(current_node.value)
|
||||||
|
current_node = current_node.next_node
|
||||||
|
|
||||||
|
example_list = LinkedList()
|
||||||
|
example_list.append("first")
|
||||||
|
example_list.append("second")
|
||||||
|
example_list.append("fourth")
|
||||||
|
example_list.insert("third", 2)
|
||||||
|
example_list.insert("zero", 0)
|
||||||
|
example_list.insert("last", 5)
|
||||||
|
|
||||||
|
example_list.print_list()
|
||||||
|
|
||||||
Reference in New Issue
Block a user