# refac vs root (historical)

**The refac version is now the main version** (root Command.py, Program.py, Plotter.py). This doc is kept for reference.

Original comparison of the core modules: **Command.py**, **Program.py**, **Plotter.py**.

---

## Command.py

| Aspect | Root | refac |
|--------|------|--------|
| **import math** | ❌ Missing (bug: `rotate()` uses `math.cos`/`math.sin`) | ✅ Present |
| **Class attributes** | `inicoms`, `scalecoms`, `movecoms` only | Same + **`abscoms`**, **`relcoms`**, **`arccoms`** (for PA/PD/PU, PR, CI/AA) |
| **scalable / movable** | `return True if ... else False` | `return self.name in ... and self.args` (shorter, same meaning) |
| **x** | `self.args[0] if self.movable else None` | `self.args[0] if self.args else None` |
| **y** | `self.args[1] if self.movable else None` (and `len(self.args)<2` check with wrong indent) | `self.args[-1] if self.args else None` (works for single-arg commands like CI) |
| **rotate()** | `Command((self.name, ...), (...))` → **bug**: first arg is a tuple, not name | ✅ `Command(self.name, ...)` |
| **flip()** | `Command(self.name, self.y, -self.x)` → **wrong**: swaps x/y | ✅ `Command(self.name, self.x, -self.y)` (mirror in y) |

**Summary:** refac fixes missing `math`, corrects `rotate()` and `flip()`, and adds command-type sets used by Program parsing/simulation.

---

## Program.py

| Aspect | Root | refac |
|--------|------|--------|
| **__init__** | `commands or []`; no bounds | `commands` (can be None); if commands given, **computes bounds once** via `__simulate()` |
| **Bounds (xmin, xmax, …)** | **@property** – computed from commands each time | Set once in **__init__** from `__simulate()` (no property; no update if commands change) |
| **parsefile / parse** | **Instance methods**: `p.parsefile(f)` mutates `self.commands` | **@staticmethod**: `Program.parsefile(f)` / `Program.parse(code)` **return new Program** |
| **Parsing** | One Command per semicolon; all args in one list | **Multi-point PA/PD/PU**: if `len(args)>2`, splits into (x,y) pairs and creates one Command per point |
| **show()** | ❌ Not in Program (show in main.py) | ✅ **Program.show()**: flip, rotate 270°, fitin to 1024×600, Tk canvas |
| **fitin(), scaleto(), moveto()** | ❌ Not in root | ✅ Present (scale/move to rectangle with alignment fx, fy) |
| **multi(w, h)** | ❌ Not in root | ✅ Tile program in w×h grid with spacing |
| **Program.parse() return** | N/A (mutates self) | Returns **Program(commands)** |

**Summary:** refac adds static parsing (return new Program), multi-point parsing, simulation for bounds, and helpers: show(), fitin(), scaleto(), moveto(), multi().

---

## Plotter.py

| Aspect | Root | refac |
|--------|------|--------|
| **Import** | `import pyserial` (wrong name; should be `serial`) | `import serial` |
| **Boundaries storage** | `self.__boundaries` (private) | `self.boundaries` (public) |
| **p0incenter** | `True` | `False` |
| **getoutput()** | `self.ser.read()` → str; returns `''.join(s)` | **Bytes**: `outstr` used as-is; `x == b"\x0d"`; returns `b''.join(s).decode()` |
| **write()** | `self.ser.write(str(programm))` (str) | `self.ser.write(str(programm).encode())` (bytes) |
| **full(prog)** | ✅ Scale prog to fit plotter bounds | ❌ **Removed** (scaling done elsewhere, e.g. Program.fitin) |
| **centralize()** | Same logic | Same logic (behavior differs only if p0incenter differs) |

**Summary:** refac uses proper `serial` and bytes for Python 3; drops `full()`; different default for `p0incenter`.

---

## Overall

- **refac** = cleaned-up, Python‑3‑friendly version: correct Command (math, rotate, flip), static Program parsing, multi-point parsing, bounds simulation, fitin/show/multi, and serial over bytes.
- **Root** = older version: Command has bugs (no math, wrong rotate/flip), instance-method parsing only, no fitin/show/multi, and broken `pyserial` import.

Recommendation: use **refac** as the main implementation and, if needed, replace root with it (or make root a thin wrapper around refac).
