#!/usr/bin/env python3 # # Usage: ./remove_links.py # Removes links from index.html and adds page numbers in brackets instead (p. XX). from pathlib import Path MATCHES = { 'For details about built-in functions sorted(), min() and max() see sortable.': 'For details about built-in functions sorted(), min() and max() see sortable (p. 16).', 'Module operator provides functions itemgetter() and mul() that offer the same functionality as lambda expressions above.': 'Module \'operator\' (p. 31) provides functions itemgetter() and mul() that offer the same functionality as lambda expressions (p. 11) above.', 'Adding \'!r\' before the colon converts object to string by calling its repr() method.': 'Adding \'!r\' before the colon converts object to string by calling its repr() method (p. 14).', 'It can be any callable, but is usually implemented as a function that returns a closure.': 'It can be any callable (p. 17), but is usually implemented as a function that returns a closure (p. 12).', 'Objects can be made sortable with \'order=True\' and immutable with \'frozen=True\'.': 'Objects can be made sortable with \'order=True\' and immutable with \'frozen=True\'.', 'Function field() is needed because \'<attr_name>: list = []\' would make a list that is shared among all instances. Its \'default_factory\' argument can be any callable.': 'Function field() is needed because \'<attr_name>: list = []\' would make a list that is shared among all instances. Its \'default_factory\' argument can be any callable (p. 17).', 'Sequence iterators returned by the iter() function, such as list_iterator and set_iterator.': 'Sequence iterators returned by the iter() function, such as list_iterator and set_iterator (p. 3).', 'Objects returned by the itertools module, such as count, repeat and cycle.': 'Objects returned by the itertools module, such as count, repeat and cycle (p. 3).', 'Generators returned by the generator functions and generator expressions.': 'Generators returned by the generator functions (p. 4) and generator expressions (p. 11).', 'File objects returned by the open() function, etc.': 'File objects returned by the open() function (p. 22), etc.', 'Another solution in this particular case is to use functions and_() and or_() from the module operator.': 'Another solution in this particular case is to use functions and_() and or_() from the module \'operator\' (p. 31).', 'Functions report OS related errors by raising either OSError or one of its subclasses.': 'Functions report OS related errors by raising OSError or one of its subclasses (p. 23).', 'Bools will be stored and returned as ints and dates as ISO formatted strings.': 'Bools will be stored and returned as ints and dates as ISO formatted strings (p. 9).', 'Asyncio module also provides its own Queue, Event, Lock and Semaphore classes.': 'Asyncio module also provides its own Queue, Event, Lock and Semaphore classes (p. 30).', } def main(): """ Replaces all occurrences of `from_` with `to_` in the file at the given path. Args: from_ (str): The string to be replaced. to_ (str): The replacement string. index_path (Path): Path object representing the file that is being modified by this function call. This parameter is not optional, and it has a default value of None because we are required to pass it as an argument but we have no use for it in our code since we don't need access to its attributes or methods while calling this function; therefore, there's no sensible default value for us to provide here. """ index_path = Path('..', 'index.html') lines = read_file(index_path) out = ''.join(lines) for from_, to_ in MATCHES.items(): out = out.replace(from_, to_, 1) write_to_file(index_path, out) ### ## UTIL # def read_file(filename): p = Path(__file__).resolve().parent / filename with open(p, encoding='utf-8') as file: return file.readlines() def write_to_file(filename, text): p = Path(__file__).resolve().parent / filename with open(p, 'w', encoding='utf-8') as file: file.write(text) if __name__ == '__main__': main()