#!/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 sorted(), min() and max() see sortable.': 'For details about 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, but is usually implemented as a function that returns a closure.',
'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\'
.',
'For object to be hashable, all attributes must be hashable and \'frozen\' must be True.': 'For object to be hashable, all attributes must be hashable and \'frozen\' must be 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.',
'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).',
'To print the spreadsheet to the console use Tabulate library.': 'To print the spreadsheet to the console use Tabulate library (p. 34).',
'For XML and binary Excel files (xlsx, xlsm and xlsb) use Pandas library.': 'For XML and binary Excel files (xlsx, xlsm and xlsb) use Pandas library (p. 46).',
'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).',
'An object with the same interface called ProcessPoolExecutor provides true parallelism by running a separate interpreter in each process. All arguments must be pickable.': 'An object with the same interface called ProcessPoolExecutor provides true parallelism by running a separate interpreter in each process. All arguments must be pickable (p. 25).',
'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).',
'A WSGI server like Waitress and a HTTP server such as Nginx are needed to run globally.': 'A WSGI server like Waitress and a HTTP server such as Nginx are needed to run globally.',
'The "latest and greatest" profiler that can also monitor GPU usage is called Scalene.': 'The "latest and greatest" profiler that can also monitor GPU usage is called Scalene.',
}
def main():
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()