PythiloLesson 2 of 15 · progress kept in this browser

Functional core, imperative shell

Code that decides and code that does are easier to test apart. Put the decisions in pure functions that take values and return values: the functional core. Put reading, writing and printing in a thin layer around it: the imperative shell.

from pathlib import Path

def word_counts(text):
    counts = {}
    for w in text.lower().split():
        counts[w] = counts.get(w, 0) + 1
    return counts

def main(path):
    text = Path(path).read_text()
    for w, n in word_counts(text).items():
        print(w, n)

text = "to be or not to be"
Path("a.txt").write_text(text)
main("a.txt")

word_counts needs no files and no mocks: a test passes a string and compares a dict. The shell has almost no logic, so one end-to-end test covers it.

Your task

Write a pure plan_sync(source, target), where both map file names to contents, returning ("copy", name) for names only in source, ("update", name) where contents differ and ("delete", name) for names only in target, sorted by name. Write the shell sync(src_dir, dst_dir) that reads the files of both folders, carries out the plan in dst_dir and returns it.