diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..766ec13 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +python_notes/_build diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..2d04131 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,22 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: python_notes/conf.py + +# We recommend specifying your dependencies to enable reproducible builds: +# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: requirements.pip diff --git a/CONTRIBUTORS b/CONTRIBUTORS index f6b03dd..be76370 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1,2 +1,5 @@ Adrianna PiƄska Simon Cross +Mariana Meireles +Joseph Sarpong +Erika diff --git a/doc/TODO.txt b/doc/TODO.txt deleted file mode 100644 index 00e2b5e..0000000 --- a/doc/TODO.txt +++ /dev/null @@ -1,5 +0,0 @@ -GLOBAL SEARCH AND REPLACE - -* replace "you" with "we" almost everywhere in earlier chapters - done up to collections; check everything -* put term definitions in italics in earlier chapters -* add hyperlinks between exercises and answers and whenever something is referenced? diff --git a/doc/rough-notes.rst b/doc/rough-notes.rst deleted file mode 100644 index 1e55e1b..0000000 --- a/doc/rough-notes.rst +++ /dev/null @@ -1,221 +0,0 @@ -.. From http://www.cs.uct.ac.za/mit_notes/Java/Latest/html/single-html.html - - -Chapter 1: Introduction -======================= - -* What is a Computer: - * update hardware introduction - -* Programming a Computer: - * mention dynamic languages and interpreters somewhere - * mention JITs somewhere - * convert Java Programming Language to Python - * convert Developing a Java Program to Python - -* Types of Computers: - * update section - -* History of Computers: - * add what happened after the 70s - -* Programming Languages: - * add static vs dynamic languages - * add strongly vs weakly typed languages - * explain where Python fits in - - -Chapter 2: Java Basics -====================== - -* Introduction - * mention Python 3 and Python 2. - -* Essentials of a Java Program - * skeleton, keywords, identifiers, __main__, indentation, print, - string formating, mention files - -* Primitive Types - * simple types -- integers, floats, boolean, strings - * delay discussion of static and class variables until OO section - -* Variables of Primitive Types and Strings - * assignment is just labelling in Python - -* Constants - * replace with discussion of mutable vs immutable - * mention constants in other languages. - -* Input - * input() - * translate scanner example - -* Type conversion - * translate discussion to Python - -* Compiling Java Programs - * Running Python programs - * Select appropriate Python IDE and translate wizard example - -* Differences between Python 2 and 3 - * raw_input() - * print - * unicode vs bytes - -* translate exercises - - -Chapter 3: Selection Control Statements -======================================= - -* Selection: if statement - * == vs "is" - * translate examples - -* More on the if statement - * nested if - * dangling else not applicable - * if ladders -> elif - -* Boolean Operators and Expression - * and, or and not operators - * translate operator precedence - * translate De Morgan's laws - * remove char type discussion - * Aha! Replace this with booleans! - -* The switch Statement - * mention Python doesn't have one - * discuss dictionary-based dispatch - -* Conditional Operators Shortcut - * "x if y else z" - -* Errors - * SyntaxError - * discussion of Python's exception hierarchy - * explain where Python fits in - * static error checking (pyflakes, pep8) - -* Testing and Debugging Programs - * Add discussion of unit vs functional vs integrated tests - - -Chapter 4: Loop Control Statements -================================== - -* The for statement - * discuss differences between Python and C/Java/C++ for loops. - -* The while statement - -* Add section of looping pitfalls - * not editing mutable sequences while you iterate over them. - * infinite loops - -* Do-while loops - * Replace with mention of do-while in other languages and while True - equivalent. - -* The break and continue statements - -* Add a section for list comprehensions - * Potential replacement for some simple for loops. - - -Chapter 5: Using Classes -======================== - -* Merge with chapter 6 probably. - -Chapter 6: Writing Your Own Classes -=================================== - -* Translate to Python -* classmethod, staticmethod, __init__, magic methods (__str__, __eq__, ...) -* Translate section on packaging classes to discussion on packages, modules, - etc. (probably move further up). - - -Chapter 7: Arrays -================= - -* Discussions of arrays in other languages. -* Discussion of lists in Python. -* Discussion of tuples. -* Maybe move to a more generic section about sequences. -* Mention how to do 2D arrays in Python. -* Do we need a discussion / mention of Numpy? - -Chapter 8: Sorting and Searching Arrays -======================================= - -* Translate algorithms -* Using all the equivalent Python statements in the standard library -* How much of the algorithm stuff should be kept? -* Timsort. :) - -Chapter 9: Object Orientated Approach to Programming -==================================================== - -* Mostly translating examples. -* Mention NotImplementedError. -* Mention Mix-ins. -* Are metaclasses too advanced to mention? -* Class decorators? - -Chapter 10: Exceptions -====================== - -* Translate to Python - -Chapters 11-12: Array List and Linked List -========================================== - -* Replace with discussion of all the cool Python collections: - * lists, dicts, sets -* Maybe move further up the discussion -* Should the linked list algorithm be replaced with something more relevant? - * Maybe a tree or graph implementation? - - -Chapter 13: Better Collections: Using Interfaces, OO, and Generics -================================================================== - -* Rewrite. -* Mention collections somewhere. -* Mention zope.interfaces somewhere. -* Generics mostly irrelevant. - -Chapter 14: Introduction to GUI Programming with Swing -====================================================== - -* translate to Tcl/Tk. -* mention other toolkits. -* replace with introduction to web programming? Django? Flask? - -Broader Issues -============== - -* docstrings need to be mentioned somewhere -- currently in packaging/testing chapter -* file I/O -- in Python Basics? Chop up Python Basics some more? - -* add more detail about scope within classes to the class chapter, where it will make more sense. - -* Add chapter on functions (before chapter 5 on classes) - * Decorators! -* Parameter passing -* Writing procedural code -* Writing functional code - * Nested functions - -* classes: a chapter or section about overriding str, comparison methods, iter, exceptions, etc.. - -* Split chapters more sensibly for Python - * group sequence types -* Discussion of .pyc files. -* Do we want something about C extensions? -* Do we want something about regular expressions? -* Mention version control? - -* one or two chapters about useful standard libraries: datetime, regex, csv parsing, os and sys (how system-agnostic can we make it?) including writing scripts and command-line parameters diff --git a/lib/sphinxcontrib/__init__.py b/lib/sphinxcontrib/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/lib/sphinxcontrib/blockdiag.py b/lib/sphinxcontrib/blockdiag.py deleted file mode 100755 index d9b0534..0000000 --- a/lib/sphinxcontrib/blockdiag.py +++ /dev/null @@ -1,337 +0,0 @@ -# -*- coding: utf-8 -*- -""" - blockdiag.sphinx_ext - ~~~~~~~~~~~~~~~~~~~~ - - Allow blockdiag-formatted diagrams to be included in Sphinx-generated - documents inline. - - :copyright: Copyright 2010 by Takeshi Komiya. - :license: BSDL. -""" - -import io -import os -import re -import posixpath -import traceback -from collections import namedtuple -try: - from hashlib import sha1 as sha -except ImportError: - from sha import sha - -from docutils import nodes -from sphinx.errors import SphinxError -from sphinx.util.osutil import ensuredir - -import blockdiag_sphinxhelper as blockdiag -u = blockdiag.utils.compat.u - - -class BlockdiagError(SphinxError): - category = 'Blockdiag error' - - -class Blockdiag(blockdiag.utils.rst.directives.BlockdiagDirective): - def run(self): - try: - return super(Blockdiag, self).run() - except blockdiag.core.parser.ParseException as e: - if self.content: - msg = '[%s] ParseError: %s\n%s' % (self.name, e, "\n".join(self.content)) - else: - msg = '[%s] ParseError: %s\n%r' % (self.name, e, self.arguments[0]) - - reporter = self.state.document.reporter - return [reporter.warning(msg, line=self.lineno)] - - def node2image(self, node, diagram): - return node - - -def get_image_filename(self, code, format, options, prefix='blockdiag'): - """ - Get path of output file. - """ - if format.upper() not in ('PNG', 'PDF', 'SVG'): - raise BlockdiagError('blockdiag error:\nunknown format: %s\n' % format) - - if format.upper() == 'PDF': - try: - __import__("reportlab") - except ImportError: - msg = 'blockdiag error:\n' + \ - 'could not output PDF format; Install reportlab\n' - raise BlockdiagError(msg) - - hashkey = (code + str(options)).encode('utf-8') - fname = '%s-%s.%s' % (prefix, sha(hashkey).hexdigest(), format.lower()) - if hasattr(self.builder, 'imgpath'): - # HTML - relfn = posixpath.join(self.builder.imgpath, fname) - outfn = os.path.join(self.builder.outdir, '_images', fname) - else: - # LaTeX - relfn = fname - outfn = os.path.join(self.builder.outdir, fname) - - if os.path.isfile(outfn): - return relfn, outfn - - ensuredir(os.path.dirname(outfn)) - - return relfn, outfn - - -def get_fontmap(self): - FontMap = blockdiag.utils.fontmap.FontMap - - try: - fontmappath = self.builder.config.blockdiag_fontmap - fontmap = FontMap(fontmappath) - except: - attrname = '_blockdiag_fontmap_warned' - if not hasattr(self.builder, attrname): - msg = ('blockdiag cannot load "%s" as fontmap file, ' - 'check the blockdiag_fontmap setting' % fontmappath) - self.builder.warn(msg) - setattr(self.builder, attrname, True) - - fontmap = FontMap(None) - - try: - fontpath = self.builder.config.blockdiag_fontpath - if isinstance(fontpath, blockdiag.utils.compat.string_types): - fontpath = [fontpath] - - if fontpath: - config = namedtuple('Config', 'font')(fontpath) - _fontpath = blockdiag.utils.bootstrap.detectfont(config) - fontmap.set_default_font(_fontpath) - except: - attrname = '_blockdiag_fontpath_warned' - if not hasattr(self.builder, attrname): - msg = ('blockdiag cannot load "%s" as truetype font, ' - 'check the blockdiag_fontpath setting' % fontpath) - self.builder.warn(msg) - setattr(self.builder, attrname, True) - - return fontmap - - -def get_anchor(self, refid, fromdocname): - for docname in self.builder.env.found_docs: - doctree = self.builder.env.get_doctree(docname) - for target in doctree.traverse(nodes.Targetable): - if target.attributes.get('refid') == refid: - targetfile = self.builder.get_relative_uri(fromdocname, docname) - return targetfile + "#" + refid - - -def resolve_reference(self, href, options): - if href is None: - return - pattern = re.compile(u("^:ref:`(.+?)`"), re.UNICODE) - matched = pattern.search(href) - if matched: - return get_anchor(self, matched.group(1), options.get('current_docname', '')) - else: - return href - - -def create_blockdiag(self, code, format, filename, options, prefix): - """ - Render blockdiag code into a PNG output file. - """ - draw = None - fontmap = get_fontmap(self) - try: - tree = blockdiag.core.parser.parse_string(code) - diagram = blockdiag.core.builder.ScreenNodeBuilder.build(tree) - for node in diagram.traverse_nodes(): - if node.href: - node.href = resolve_reference(self, node.href, options) - - antialias = self.builder.config.blockdiag_antialias - draw = blockdiag.core.drawer.DiagramDraw(format, diagram, filename, - fontmap=fontmap, antialias=antialias) - - except Exception as e: - if self.builder.config.blockdiag_debug: - traceback.print_exc() - - raise BlockdiagError('blockdiag error:\n%s\n' % e) - - return draw - - -def make_svgtag(self, image, relfn, trelfn, outfn, - alt, thumb_size, image_size): - svgtag_format = """%s - """ - - code = io.open(outfn, 'r', encoding='utf-8-sig').read() - - return (svgtag_format % - (alt, image_size[0], image_size[1], code)) - - -def make_imgtag(self, image, relfn, trelfn, outfn, - alt, thumb_size, image_size): - result = "" - - clickable_map = [] - for n in image.nodes: - if n.href: - cell = image.metrics.cell(n) - clickable_map.append((cell, n.href)) - - if clickable_map: - imgtag_format = '%s' % relfn) - result += (imgtag_format % - (trelfn, alt, thumb_size[0], thumb_size[1])) - result += ('') - else: - result += (imgtag_format % - (relfn, alt, image_size[0], image_size[1])) - - if clickable_map: - result += ('' % id(image)) - rect_format = '' - for m in clickable_map: - x1 = m[0].x1 - y1 = m[0].y1 - x2 = m[0].x2 - y2 = m[0].y2 - result += (rect_format % (x1, y1, x2, y2, m[1])) - - result += ('') - - return result - - -def render_dot_html(self, node, code, options, prefix='blockdiag', - imgcls=None, alt=None): - trelfn = None - thumb_size = None - try: - format = self.builder.config.blockdiag_html_image_format - relfn, outfn = get_image_filename(self, code, format, options, prefix) - - options['current_docname'] = self.builder.current_docname - image = create_blockdiag(self, code, format, outfn, options, prefix) - - if not os.path.isfile(outfn): - image.draw() - image.save() - - # generate thumbnails - image_size = image.pagesize() - if 'maxwidth' in options and options['maxwidth'] < image_size[0]: - thumb_prefix = prefix + '_thumb' - trelfn, toutfn = get_image_filename(self, code, format, - options, thumb_prefix) - - ratio = float(options['maxwidth']) / image_size[0] - thumb_size = (options['maxwidth'], image_size[1] * ratio) - if not os.path.isfile(toutfn): - image.filename = toutfn - image.save(thumb_size) - - except UnicodeEncodeError: - msg = ("blockdiag error: UnicodeEncodeError caught " - "(check your font settings)") - self.builder.warn(msg) - raise nodes.SkipNode - except BlockdiagError as exc: - self.builder.warn('dot code %r: ' % code + str(exc)) - raise nodes.SkipNode - - self.body.append(self.starttag(node, 'p', CLASS='blockdiag')) - if relfn is None: - self.body.append(self.encode(code)) - else: - if alt is None: - alt = node.get('alt', self.encode(code).strip()) - - if format.upper() == 'SVG': - tagfunc = make_svgtag - else: - tagfunc = make_imgtag - - self.body.append(tagfunc(self, image, relfn, trelfn, outfn, alt, - thumb_size, image_size)) - - self.body.append('

\n') - raise nodes.SkipNode - - -def html_visit_blockdiag(self, node): - render_dot_html(self, node, node['code'], node['options']) - - -def render_dot_latex(self, node, code, options, prefix='blockdiag'): - try: - format = self.builder.config.blockdiag_tex_image_format - fname, outfn = get_image_filename(self, code, format, options, prefix) - - image = create_blockdiag(self, code, format, outfn, options, prefix) - if not os.path.isfile(outfn): - image.draw() - image.save() - - except BlockdiagError as exc: - self.builder.warn('dot code %r: ' % code + str(exc)) - raise nodes.SkipNode - - if fname is not None: - self.body.append('\\par\\includegraphics{%s}\\par' % fname) - raise nodes.SkipNode - - -def latex_visit_blockdiag(self, node): - render_dot_latex(self, node, node['code'], node['options']) - - -def on_doctree_resolved(self, doctree, docname): - if self.builder.format in ('html', 'latex'): - return - - for node in doctree.traverse(blockdiag.utils.rst.nodes.blockdiag): - code = node['code'] - prefix = 'blockdiag' - format = 'PNG' - options = node['options'] - relfn, outfn = get_image_filename(self, code, format, options, prefix) - - image = create_blockdiag(self, code, format, outfn, options, prefix) - if not os.path.isfile(outfn): - image.draw() - image.save() - - candidates = {'image/png': relfn} - image = nodes.image(uri=outfn, candidates=candidates) - node.parent.replace(node, image) - - -def setup(app): - app.add_node(blockdiag.utils.rst.nodes.blockdiag, - html=(html_visit_blockdiag, None), - latex=(latex_visit_blockdiag, None)) - app.add_directive('blockdiag', Blockdiag) - app.add_config_value('blockdiag_fontpath', None, 'html') - app.add_config_value('blockdiag_fontmap', None, 'html') - app.add_config_value('blockdiag_antialias', False, 'html') - app.add_config_value('blockdiag_debug', False, 'html') - app.add_config_value('blockdiag_html_image_format', 'PNG', 'html') - app.add_config_value('blockdiag_tex_image_format', 'PNG', 'html') - app.connect("doctree-resolved", on_doctree_resolved) diff --git a/python_notes/Classes.rst b/python_notes/Classes.rst index 1af642a..9ee2d69 100644 --- a/python_notes/Classes.rst +++ b/python_notes/Classes.rst @@ -455,7 +455,7 @@ Here are some examples of special object properties: * ``__init__``: the initialisation method of an object, which is called when the object is created. * ``__str__``: the string representation method of an object, which is called when you use the ``str`` function to convert that object to a string. -* ``__class__``: an attribute which stores the the class (or type) of an object -- this is what is returned when you use the ``type`` function on the object. +* ``__class__``: an attribute which stores the class (or type) of an object -- this is what is returned when you use the ``type`` function on the object. * ``__eq__``: a method which determines whether this object is equal to another. There are also other methods for determining if it's not equal, less than, etc.. These methods are used in object comparisons, for example when we use the equality operator ``==`` to check if two objects are equal. * ``__add__`` is a method which allows this object to be added to another object. There are equivalent methods for all the other arithmetic operators. Not all objects support all arithemtic operations -- numbers have all of these methods defined, but other objects may only have a subset. * ``__iter__``: a method which returns an iterator over the object -- we will find it on strings, lists and other iterables. It is executed when we use the ``iter`` function on the object. diff --git a/python_notes/Collections.rst b/python_notes/Collections.rst index 68590cc..9e5ac22 100644 --- a/python_notes/Collections.rst +++ b/python_notes/Collections.rst @@ -628,7 +628,7 @@ You might think of using this method to construct our timetable. We can certain But what happens if we repeat a day seven times to make a week? :: - timetable = day * 7 + timetable = [day] * 7 print(timetable) Everything looks fine so far, so what's the problem? Well, let's see what happens when we try to schedule a meeting for Monday afternoon:: diff --git a/python_notes/Object_Oriented_Programming.rst b/python_notes/Object_Oriented_Programming.rst index 1983be8..252889c 100644 --- a/python_notes/Object_Oriented_Programming.rst +++ b/python_notes/Object_Oriented_Programming.rst @@ -575,13 +575,13 @@ Answer to exercise 3 break box1 = ListBox() - box1.add(Item(str(i), i) for i in range(20)) + box1.add(*(Item(str(i), i) for i in range(20))) box2 = ListBox() - box2.add(Item(str(i), i) for i in range(9)) + box2.add(*(Item(str(i), i) for i in range(100, 109))) - box1 = DictBox() - box1.add(Item(str(i), i) for i in range(5)) + box3 = DictBox() + box3.add(*(Item(str(i), i) for i in range(200, 205))) repack_boxes(box1, box2, box3) @@ -613,4 +613,4 @@ Answer to exercise 4 if not hasattr(self, "teacher"): raise NotImplementedError() - self.teacher.assign_teaching(course) \ No newline at end of file + self.teacher.assign_teaching(course) diff --git a/python_notes/Packaging_and_Testing.rst b/python_notes/Packaging_and_Testing.rst index f01e111..51c2f13 100644 --- a/python_notes/Packaging_and_Testing.rst +++ b/python_notes/Packaging_and_Testing.rst @@ -185,7 +185,7 @@ Selecting test cases How do we select test cases? There are two major approaches that we can follow: *black-box* or *glass-box* testing. We can also use a combination of the two. -In black-box testing, we treat our function like an opaque "black box". We don't use our knowledge of how the function is written to pick test cases -- we only think about what the function is supposed to do. A strategy commonly used in black-box testing is is *equivalence testing* and *boundary value analysis*. +In black-box testing, we treat our function like an opaque "black box". We don't use our knowledge of how the function is written to pick test cases -- we only think about what the function is supposed to do. A strategy commonly used in black-box testing is *equivalence testing* and *boundary value analysis*. An *equivalence class* is a set of input values which should all produce similar output, and there are *boundaries* between neighbouring equivalence classes. Input values which lie near these boundaries are the most likely to produce incorrect output, because it's easy for a programmer to use ``<`` instead of ``<=`` or start counting from ``1`` instead of ``0``, both of which could cause an *off-by-one* error. If we test an input value from inside each equivalence class, and additionally test values just before, just after and on each boundary, we can be reasonably sure that we have covered all the bases. diff --git a/python_notes/Sorting_and_Searching_Algorithms.rst b/python_notes/Sorting_and_Searching_Algorithms.rst index 4c7f772..61311a0 100644 --- a/python_notes/Sorting_and_Searching_Algorithms.rst +++ b/python_notes/Sorting_and_Searching_Algorithms.rst @@ -261,7 +261,7 @@ Python. "..." denotes missing code that should be filled in:: def selection_sort(items): """Sorts a list of items into ascending order using the - selection sort algoright. + selection sort algorithm. """ for step in range(len(items)): # Find the location of the smallest element in diff --git a/requirements.pip b/requirements.pip index 317d163..1a34f22 100644 --- a/requirements.pip +++ b/requirements.pip @@ -1,2 +1,2 @@ Sphinx -blockdiag \ No newline at end of file +sphinxcontrib-blockdiag