programmedpatterns

Practice exercises in pattern recognition, ideal for beginner and intermediate programmers.

This uses the patterns at https://www.visualpatterns.org/ by Fawn Nguyen. The site and this module are licensed under a Creative Commons Attribution license.

The patterns are not in order of difficulty. Many are simple, some are incredibly hard.

THIS MODULE IS CURRENTLY UNDER CONSTRUCTION AND NOT WORKING YET.

Installation

To install with pip, from the Command Prompt/terminal run:

python -m pip install programmedpatterns

Contribute

Currently a lot of basic programming work is needed (in Python and other languages) to make Programmed Patterns work.

First, we need the solutions for all 468 patterns. Each solution is comprised of a visX(n) function that returns a multiline string for pattern X at iteration n, and a numX(n) function that returns a numeric count of the number of shapes in pattern X at iteration n.

For example, here’s pattern #5 which has a medium level of difficulty:

 OO    OOO     OOOO
O O     OO      OOO
OOO  O  OO      OOO
     OOOO   O   OOO
     OOO    OOOOO
            OOOO
            OOOO
Number of Os:
7    15     27

The vis5() function you write should take an integer n and return a multiline string for the pattern at iteraton n:

def vis5(n):
    result = ''
    result += (' ' * n) + ('O' * (n + 1)) + '\n'
    for i in range(n - 1):
        result += (' ' * (n + 1)) + ('O' * n) + '\n'
    result += 'O' + (' ' * n) + ('O' * n) + '\n'
    result += 'O' * (n + 2) + '\n'
    for i in range(n - 1):
        result += 'O' * (n + 1) + '\n'
    return result

The num5() function you write should take an integer n and return the number of 'O' characters in the pattern at iteration n:

def num5(n):
    return 3 + (2 * ((n + 1) * n))

These functions will be used to check student solutions. Each pattern puzzle has a visual string-manipulation component and a mathematical algebra component. This provides a lot of practice for intermediate-level programmers who have learned language syntax but need to become more skillful at writing code.

Where you can help is by writing the solution functions for the unsolved patterns. Check out https://visualpatterns.org and find a pattern to write function solutions for. To avoid working on patterns that other people may be working on, pick patterns to solve randomly by running random.randint(1, 468) in Python (or some other random selection method) and then check the GitHub repo to make sure it hasn’t already been solved.

The source code file has boilerplate visX() and numX() functions that you can fill in with your solution. You can then run getPatternMultilineString(X, 1, 10) (where X is the pattern number) to verify that the solution looks correct for iterations 1 through 10.

While the strings returned by the visX() functions have multiple lines (that is, they contain \n newline charactrs) each line should remove all trailing whitespace for their canonical answer. For example, this pattern:

O
OO
OOO

….should be represented as 'O\nOO\nOOO' and not 'O \nOO \nOOO\n'.

You should also draw each pattern as far up and to the left as possible. For example, pattern #22’s 2nd iteration should be 'O\nOO' and not '\n\nO\nOO'.

Special Case Patterns

Most of the patterns involve a progressive growth of generic shapes which are represented by 'O' strings. For example:

Pattern #9:

O    OO    OOO    OOOO    OOOOO
OO   OOO   OOOO   OOOOO   OOOOOO
OOO  OOOO  OOOOO  OOOOOO  OOOOOOO
Number of Os:
6    9     12     15      18

Pattern #11:

O   O    O     O      O
OO  O    O     O      O
    OOO  O     O      O
         OOOO  O      O
               OOOOO  O
                      OOOOOO
Number of Os:
3   5    7     9      11

Pattern #14:

O       O       O       O       O
OOOOOO  OOOOOO  OOOOOO  OOOOOO  OOOOOO
        OOOOOO  OOOOOO  OOOOOO  OOOOOO
                OOOOOO  OOOOOO  OOOOOO
                        OOOOOO  OOOOOO
                                OOOOOO
Number of Os:
7       13      19      25      31

But some patterns have multiple kinds of shapes. For example, pattern #15:

 O    O O    O O O    O O O O    O O O O O
OXO  OXOXO  OXOXOXO  OXOXOXOXO  OXOXOXOXOXO
 O    O O    O O O    O O O O    O O O O O
Number of Os, Xs:
(4, 1)(7, 2) (10, 3)  (13, 4)    (16, 5)

In these cases, other letters such as 'X' are used in addition to 'O' for the visual component. For the numerical component, the numX() function doesn’t return a simple integer but a tuple of integers. For pattern #15, the tuple returned is in the format (number of Os, number of Xs).

Other patterns have line drawings rather than discreet shapes. For example, pattern #44 looks like this:

    __          __    __          __    __    __
 __/##\__    __/##\__/##\__    __/##\__/##\__/##\__
/##\##/##\  /##\##/##\##/##\  /##\##/##\##/##\##/##\
\##/  \##/  \##/  \##/  \##/  \##/  \##/  \##/  \##/
/##\__/##\  /##\__/##\__/##\  /##\__/##\__/##\__/##\
\##/##\##/  \##/##\##/##\##/  \##/##\##/##\##/##\##/
   \##/        \##/  \##/        \##/  \##/  \##/
Number of filled hexagons:
6           10                14

These patterns often use /, \, _, and | for line-drawing characters. In many programming languages, the \ forward slash must be escaped as \\ when written in string literals in your code. In Python, raw strings are a helpful shortcut that allows you to write forward slashes without escaping them: print(r'Hello\\world') will print Hello\\world and not Hello\world.

However, Python has a slight bug in its language design where \ slashes cannot be the last character in a raw string. The code print(r'\Hello\') produces a syntax error instead of displaying \Hello\. You cannot use raw strings in these cases and instead must use normal strings with escape characters: print('\\Hello\\')

Please contact me at [email protected] or on Twitter @AlSweigart if you’d like to contribute to this git repo.

Support

If you find this project helpful and would like to support its development, consider donating to its creator on Patreon.

GitHub

View Github