Skip to content

Commit

Permalink
Finished code for Chapters 7 & 8; updated metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
davecom committed May 4, 2024
1 parent 7d55e39 commit 12a9e48
Show file tree
Hide file tree
Showing 28 changed files with 148 additions and 102 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]
python-version: ["3.12", "3.13"]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
2 changes: 1 addition & 1 deletion Brainfuck/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Brainfuck/__main__.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion Brainfuck/brainfuck.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Brainfuck/brainfuck.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion Chip8/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Chip8/__main__.py
# From Fun Computer Science Projects in Python
# Copyright 2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion Chip8/vm.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Chip8/vm.py
# From Fun Computer Science Projects in Python
# Copyright 2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion KNN/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def run():
digit_pixels.fill(0)
elif key_name == "p": # predict what the digit should look like
pixels = digit_pixels.transpose((1, 0, 2))[:, :, 0].flatten() * P_TO_D
predicted_pixels = digits_knn.predict(K, Digit("", pixels), "pixels")
predicted_pixels = digits_knn.predict_array(K, Digit("", pixels), "pixels")
predicted_pixels = predicted_pixels.reshape((PIXEL_HEIGHT, PIXEL_WIDTH)).transpose((1, 0)) * D_TO_P
digit_pixels = np.stack((predicted_pixels, predicted_pixels, predicted_pixels), axis=2)
# Handle mouse events
Expand Down
2 changes: 1 addition & 1 deletion KNN/fish.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ def from_string_data(cls, data: list[str]) -> Self:
def distance(self, other: Self) -> float:
return ((self.length1 - other.length1) ** 2 + (self.length2 - other.length2) ** 2 +
(self.length3 - other.length3) ** 2 + (self.height - other.height) ** 2 +
(self.width - other.width) ** 2) ** 0.5
(self.width - other.width) ** 2) ** 0.5
15 changes: 10 additions & 5 deletions KNN/knn.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
# limitations under the License.
import csv
from typing import Protocol, Self
from pathlib import Path
from collections.abc import Iterable
import numpy as np


class DataPoint(Protocol):
Expand All @@ -29,13 +28,13 @@ def distance(self, other: Self) -> float: ...


class KNN[DP: DataPoint]:
def __init__(self, data_point_type: type[DP], file_path: Path, has_header: bool = True) -> None:
def __init__(self, data_point_type: type[DP], file_path: str, has_header: bool = True) -> None:
self.data_point_type = data_point_type
self.data_points = []
self._read_csv(file_path, has_header)

# Read a CSV file and return a list of data points
def _read_csv(self, file_path: Path, has_header: bool) -> None:
def _read_csv(self, file_path: str, has_header: bool) -> None:
with open(file_path, 'r') as f:
reader = csv.reader(f)
if has_header:
Expand All @@ -61,6 +60,12 @@ def classify(self, k: int, data_point: DP) -> str:

# Predict a property of a data point based on the k nearest neighbors
# Find the average of that property from the neighbors and return it
def predict(self, k: int, data_point: DP, property_name: str) -> float | Iterable:
def predict(self, k: int, data_point: DP, property_name: str) -> float:
neighbors = self.nearest(k, data_point)
return sum([getattr(neighbor, property_name) for neighbor in neighbors]) / len(neighbors)

# Predict a property of a data point based on the k nearest neighbors
# Find the average of that property from the neighbors and return it
def predict_array(self, k: int, data_point: DP, property_name: str) -> np.ndarray:
neighbors = self.nearest(k, data_point)
return np.sum([getattr(neighbor, property_name) for neighbor in neighbors]) / len(neighbors)
2 changes: 1 addition & 1 deletion NESEmulator/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NESEmulator/__main__.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion NESEmulator/cpu.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NESEmulator/cpu.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion NESEmulator/ppu.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NESEmulator/ppu.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion NESEmulator/rom.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NESEmulator/rom.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion NanoBASIC/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NanoBASIC/__main__.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion NanoBASIC/executioner.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NanoBASIC/executioner.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion NanoBASIC/interpreter.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NanoBASIC/interpreter.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion NanoBASIC/nodes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NanoBASIC/nodes.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion NanoBASIC/parser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NanoBASIC/parser.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion NanoBASIC/tokenizer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NanoBASIC/tokenizer.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
121 changes: 73 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ Source for the book Fun Computer Science Projects in Python by [David Kopec](htt

## Authorship and License

The code in this repository is Copyright 2022 David Kopec and released under the terms of the Apache License 2.0. That means you can reuse the code, but you must give credit to David Kopec.
The code in this repository is Copyright 2024 David Kopec and released under the terms of the Apache License 2.0. That means you can reuse the code, but you must give credit to David Kopec. Please read the license for details.

## Running and Testing Each Project

The following directions assume you are in the root directory of the repository in a terminal and that your Python command is `python` (on some systems it is `python3`). You need Python 3.9+ installed.
The following directions assume you are in the root directory of the repository in a terminal and that your Python command is `python` (on some systems it is `python3`). The code is written against Python 3.12, although most of it will run with Python 3.9+.

### Brainfuck
### Brainfuck (Chapter 1)

A simple [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) interpreter.

Expand All @@ -31,27 +31,7 @@ For example:

`python -m tests.test_brainfuck`

### Chip8

A Chip8 virtual machine.

#### Requirements

- PyGame

#### Running

`python -m Chip8 <your_file_name>`

For example:

`python -m Chip8 Chip8/Games/tetris.chip`

#### Testing

`python -m tests.test_chip8`

### NanoBASIC
### NanoBASIC (Chapter 2)

An interpreter for a very simple dialect of BASIC based on [Tiny BASIC](https://en.wikipedia.org/wiki/Tiny_BASIC).

Expand All @@ -71,28 +51,7 @@ For example:

`python -m tests.test_nanobasic`

### NESEmulator

A simple [NES](https://en.wikipedia.org/wiki/Nintendo_Entertainment_System) emulator that can play some basic public domain games.

#### Requirements

- PyGame
- NumPy

#### Running

`python -m NESEmulator <your_file_name>`

For example:

`python -m NESEmulator NESEmulator/Games/LanMaster.nes`

#### Testing

`python -m tests.test_nesemulator`

### RetroDither
### RetroDither (Chapter 3)

Dithers images into 1 bit black & white and exports them to MacPaint format.

Expand All @@ -112,7 +71,7 @@ Additional options:

`-g` output a .gif format version as well

### StainedGlass
### StainedGlass (Chapter 4)

Computationally draws abstract approximations of images using vector shapes.

Expand Down Expand Up @@ -147,4 +106,70 @@ Additional options:
`-v, --vector` Create vector output. A SVG file will also be output.

`-a ANIMATE, --animate ANIMATE` If a number greater than 0 is provided, will create an animated GIF with the number of milliseconds per frame
provided.
provided.

### Chip8 (Chapter 5)

A Chip8 virtual machine.

#### Requirements

- PyGame
- NumPy

#### Running

`python -m Chip8 <your_file_name>`

For example:

`python -m Chip8 Chip8/Games/tetris.chip`

#### Testing

`python -m tests.test_chip8`

### NESEmulator (Chapter 6)

A simple [NES](https://en.wikipedia.org/wiki/Nintendo_Entertainment_System) emulator that can play some basic public domain games.

#### Requirements

- PyGame
- NumPy

#### Running

`python -m NESEmulator <your_file_name>`

For example:

`python -m NESEmulator NESEmulator/Games/LanMaster.nes`

"a" is Select, "s" is Start, "arrow keys" are the D-pad, "z" is B, and "x" is A.

#### Testing

`python -m tests.test_nesemulator`

### KNN (Chapter 7)

A handwritten digit recognizer using the K-nearest neighbors algorithm.

#### Requirements

- PyGame
- NumPy

#### Running

`python -m KNN`

Then use the key commands "c" to classify, "p" to predict, and "e" to erase.

#### Testing

`python -m tests.test_knn`

## Type Hints
The code in this repository uses the latest type hinting features in Python 3.12. If you are using an older version of Python, you may need to remove some of the type hints to run the code. All the type hints in the source code were checked using [Pyright](https://github.com/microsoft/pyright).
2 changes: 1 addition & 1 deletion RetroDither/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# RetroDither/__main__.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion RetroDither/dither.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# RetroDither/dither.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion RetroDither/macpaint.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# RetroDither/macpaint.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion StainedGlass/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# StainedGlass/__main__.py
# From Fun Computer Science Projects in Python
# Copyright 2021-2022 David Kopec
# Copyright 2024 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
Loading

0 comments on commit 12a9e48

Please sign in to comment.