4. Systematic code examples: a guided tour of Transcrypt

One ready-to-run code example is worth more than ten lengthy descriptions. The autotest and demo suite, that is part of the distribution, is a collection of sourcecode fragments called testlets. These testlets are used for automated regression testing of Transcrypt against CPython. Since they systematically cover all language constructs, they are also very effective as a learning tool. The testlets are arranged alphabetically by subject.

Autotest: Transcrypt autotest demo suite
import org.transcrypt.autotester

import arguments
import classes
import conditional_expressions
import control_structures
import data_structures
import dict_comprehensions
import dictionaries
import exceptions
import general_functions
import indices_and_slices
import lambda_functions
import list_comprehensions
import modules
import nonlocals
import operator_overloading
import properties
import set_comprehensions
import simple_and_augmented_assignment
import tuple_assignment

autoTester = org.transcrypt.autotester.AutoTester ()

autoTester.run (arguments, 'arguments')
autoTester.run (classes, 'classes')
autoTester.run (conditional_expressions, 'conditional_expressions')
autoTester.run (control_structures, 'control_structures')
autoTester.run (data_structures, 'data_structures')
autoTester.run (dict_comprehensions, 'dict_comprehensions')
autoTester.run (dictionaries, 'dictionaries')
autoTester.run (exceptions, 'exceptions')
autoTester.run (general_functions, 'general_functions')
autoTester.run (indices_and_slices, 'indices_and_slices')
autoTester.run (lambda_functions, 'lambda_functions')
autoTester.run (list_comprehensions, 'list_comprehensions')
autoTester.run (modules, 'modules')
autoTester.run (nonlocals, 'nonlocals')
autoTester.run (operator_overloading, 'operator_overloading')
autoTester.run (properties, 'properties')
autoTester.run (set_comprehensions, 'set_comprehensions')
autoTester.run (simple_and_augmented_assignment, 'simple_and_augmented_assignment')
autoTester.run (tuple_assignment, 'tuple_assignemt')

autoTester.done ()

4.1. Arguments: **kwargs, *args, defaults, at call and def time, also for lambda’s

Testlet: arguments
from org.transcrypt.stubs.browser import __pragma__

__pragma__ ('kwargs')

class A:
    def __init__ (self, x = 123, y = 456, *args, m, n = 456, **kwargs):
        self.x = x
        self.y = y
        self.args = args
        self.m = m
        self.n = n
        self.kwargs = kwargs
        self.extra = 'hello'

    def f (self, autoTester):
        autoTester.check (self.x, self.y, self.args, self.m, self.n, self.kwargs, self.extra)
        
class B (A):
    def __init__ (self, x, y = -1, *args, m = -2, n, **kwargs):
        A.__init__ (self, y, x, *args, m = n, n = m, **kwargs)
        
class C:
    __pragma__ ('nokwargs')
    def tricky (self, *args):
        return args
    __pragma__ ('kwargs')
    
def run (autoTester):
    def f (x, y = -1, *args, m = -2, n, **kwargs):
        def f2 (x, y = -3, *args, m = -4, n, **kwargs):
            autoTester.check (x, y, args, m, n, kwargs)
        f2 (11, 22, 1010, 2020, m = 100100, n = 200200, p = 10001000, q = 20002000)
        autoTester.check (x, y, args, m, n, kwargs)
        
    f (1, 2, 10, 20, m = 100, n = 200, p = 1000, q = 2000)
    
    b = B (3, 4, 30, 40, m = 300, n = 400, p = 3000, q = 4000)
    b.f (autoTester)
    
    def g (*args, **kwargs):
        autoTester.check (args, kwargs)
        
    g (*(1, 2, 3), **{'p': 'aP', 'q': 'aQ', 'r': 'anR'})
    
    (lambda x, y = -1, *args, m = -2, n, **kwargs: autoTester.check (x, y, args, m, n, kwargs)) (1, 2, 8, 16, m = 128, n = 256.3, p = 1024.3, q = 2048.3)
    
    autoTester.check (C () .tricky (* range (4)))
    autoTester.check ('{}-{}'.format (1, 3, 5, 7, 9))
    autoTester.check ('{}-{}'.format (* range (4)))

4.2. Classes: multiple inheritance and assignment of bound functions

Testlet: classes
def run (autoTester):
    class A:
        p = 123
        def __init__ (self, x):
            self.x = x
            autoTester.check (self.p)

        def show (self, label):
            autoTester.check ('A.show', label, self.x)
            
        def show2 (self, label):
            autoTester.check ('A.show2', label, self.x)
        
    class B:
        p, q = 456, 789
        def __init__ (self, y):
            autoTester.check ('In B constructor')
            self.y = y
            autoTester.check (self.p)
            
        def show (self, label):
            autoTester.check ('B.show', label, self.y)
            
    class C (A, B):
        def __init__ (self, x, y):
            autoTester.check ('In C constructor')
            A.__init__ (self, x)
            B.__init__ (self, y)
            
        def show (self, label):
            A.show (self, label)
            B.show (self, label)
            autoTester.check ('C.show', label, self.x, self.y)
        
    a = A (1001)
    a.show ('america')
    autoTester.check (A.p)
    autoTester.check (a.p)

    b = B (2002)
    b.show ('russia')
    autoTester.check (B.p)
    autoTester.check (b.p)
    autoTester.check (b.q)

    autoTester.check (A.p)
    autoTester.check (a.p)

    c = C (3003, 4004)
    c.show ('netherlands')
    autoTester.check (C.p)
    autoTester.check (c.p)
    autoTester.check (c.q)

    c.show2 ('amsterdam')
    A.show2 (c, 'rotterdam')

    show3 = c.show
    show3 ('copy')

4.3. Conditional expressions: simple and nested

Testlet: conditional_expressions
def f (x, b):
    return x * x if b else x + x

def run (autoTester):
    bools = (False, True)
    for a in bools:
        for b in bools:
            autoTester.check (f (10 if a else 100, b))
            
    for p in bools:
        for q in bools:
            for r in bools:
                autoTester.check ('a' if p else 'b' if q else 'c' if r else 'd')
                
                a = ((('e' if p else 'f') if q else 'g') if r else 'h')
                b = ('i' if p else ('j' if q else ('k' if r else 'l')))
                c = 'm' if (p if q else r) else 'n'
                d = 'o' if p < q <= r else 'p'
                autoTester.check (a, b, c, d)
                
    odd = [x if x % 2 else x + 1 for x in range (10)]
    noDuplicates = set (odd)
    autoTester.check (odd, noDuplicates)

4.4. Control structures: for...else, while...else, if...elif...else, break, continue

Testlet: control_structures
def run (autoTester):
    for index, square in enumerate ([x * x for x in range (10) if x % 2]):
        for y in range (1, 2, 3):
            for z in range (10, 20, 30):
                autoTester.check (square + y, z )

    vehicles = ['bike', 'train', 'boat', 'car', 'plane', 'bus']
                
    for doBreak in (False, True):
        for doContinue in (False, True):
            for index in range (10):
                for index2 in range (0, 100, 10):
                    if doBreak and index2 == 50:
                        autoTester.check ('break2')
                        break
                    if doContinue and index2 == 50:
                        autoTester.check ('continue2')
                        continue
                else:
                    autoTester.check ('noBreak2')
                    
                if doBreak and index == 5:
                    autoTester.check ('break')
                    break
                if doContinue and index == 5:
                    autoTester.check ('continue')
                    continue
            else:
                autoTester.check ('noBreak')
                
            index = 0
            while index < len (vehicles) and vehicles [index] != 'bus':
                autoTester.check (index, vehicles [index])
                if doBreak and vehicles [index] == 'car':
                    autoTester.check ('breakWhile')
                    break
                if doContinue and vehicles [index] == 'car':
                    autoTester.check ('continueWhile')
                    index += 1
                    continue
                index += 1
            else:
                autoTester.check ('noBreakWhile')
                
        for vehicle in vehicles:
            if vehicle == 'bike':
                autoTester.check ('netherlands')
            elif vehicle == 'car':
                autoTester.check ('america')
            elif vehicle == 'boat':
                autoTester.check ('oceania')
            else:
                autoTester.check ('anywhere')

4.5. Data structures: tuple, list, dict, set

Testlet: data_structures
def run (autoTester):
    aList = [1, 2, 3, 'sun', 'moon', 'stars']
    autoTester.check (aList)
    autoTester.check (aList [2:4:1])
    autoTester.check (aList [:])
    autoTester.check (aList [2:])
    autoTester.check (len (aList))
    aList.append ('milkyway')
    autoTester.check (aList)
    aList.extend (['m1', 'm31'])
    autoTester.check (aList)

    anotherList = list (('a', 'b', 'c'))
    autoTester.check (anotherList)

    aDict = {1: 'plant', 'animal': 2}
    autoTester.check (aDict)
    autoTester.check (aDict [1], aDict ['animal'])
    

    def p ():
        return 3
        
    q = 4
    
    autoTester.check ({p (): 'three', q: 'four'})
    
    aTuple = (1, 2, 3, 4, 5)
    autoTester.check(aTuple)
    autoTester.check (len (aTuple))

    anotherTuple = (1,)
    autoTester.check (anotherTuple)

    aSet = {1, 2, 2, 3}
    autoTester.check    (aSet)
    autoTester.check (len (aSet))

    anotherSet = set ((4, 5, 5, 6))
    autoTester.check (anotherSet)

    emptySet = set ()
    autoTester.check (emptySet)
    autoTester.check (len (emptySet))

4.6. Dict comprehensions

Testlet: dict_comprehensions
from org.transcrypt.stubs.browser import __pragma__

__pragma__ ('iconv')    # Convert dict to key list without using keys () method

def run (autoTester):
    original = {'Isaac': 'Newton', 'Albert': 'Einstein', 'Paul': 'Dirac'}
    autoTester.check (original)

    inverted = {original [key]: key for key in original}
    autoTester.check (inverted)

4.7. Dictionaries: dict revisited

Testlet: dictionaries
from org.transcrypt.stubs.browser import __pragma__
__pragma__ ('iconv')

def run (autoTester):
    tel = {'guido': 4127, 'jack': 4098}
    tel ['sape'] = 4139

    autoTester.check (tel)
    autoTester.check (tel ['jack'])

    del tel ['sape']
    tel ['irv'] = 4127
    autoTester.check (tel)

    autoTester.check (sorted (list (tel.keys ())), False)
    autoTester.check (sorted (tel.keys ()))

    autoTester.check ('guido' in tel)
    autoTester.check ('jack' not in tel)

    autoTester.check (dict ([('guido', 4127), ('jack', 4098), ('sape', 4139)]))

    knights = {'robin': 'the brave', 'gallahad': 'the pure'}

    for k, v in sorted (knights.items ()):
        autoTester.check (k, v)

    if 'gallahad' in knights:
        autoTester.check ('gallahad is a knight') 

    for k in sorted (knights):
        autoTester.check (k)
        
    knight = {'rudolph': 'the righteous'}
    for k in knight:    # Autotest automatic conversion with one knight, since sort order of dict undefined
        autoTester.check (k)

4.8. Exceptions: exception class hierarchy, finally

Testlet: exceptions
class Ex1 (Exception):
    pass
        
class Ex2 (Ex1):
    pass
    
class Ex3 (Exception):
    pass
    
def test1 ():
    raise (Exception ('mary'))
    
def test2 (autoTester):
    try:
        test1 ()
    except Ex1 as exception:
        autoTester.check (111)
        autoTester.check (exception)
    except Exception as exception:
        autoTester.check (222)
        autoTester.check (exception)
        
def run (autoTester):
    test2 (autoTester)
    
    try:
        raise Ex2 ('had')
    except Ex1 as exception:
        autoTester.check ('a')
    except Exception as exception:
        autoTester.check ('little')
        autoTester.check (exception)
        
    autoTester.check (333)
        
    try:
        raise Ex1 ('lamb')
    except Ex2 as exception:
        autoTester.check ('his')
        autoTester.check (exception)
    except Ex1 as exception:
        autoTester.check ('fleece')
        autoTester.check (exception)
    except Exception as exception:
        autoTester.check ('was')
        autoTester.check (exception)
    finally:
        autoTester.check ('white')
        
    autoTester.check (444)

    def test3 ():
        raise Ex3 ('as')
        
    autoTester.check (555)

    try:
        test3 ()
    except Ex1 as exception:
        autoTester.check ('snow')
        autoTester.check (exception)
    except Exception as exception:
        autoTester.check ('and')
        autoTester.check (exception)
    finally:
        autoTester.check ('everywhere')
        
    autoTester.check (666)

4.9. General functions: sort and sorted

Testlet: general_functions
def run (autoTester):
    a = [1, 5, 3, 2, -1]
    b = ['sun', 'earth', 'moon']
    
    autoTester.check (sorted (a))
    autoTester.check (sorted (b))
    
    a.sort ()
    autoTester.check (a)
    
    b.sort ()
    autoTester.check (b)

    autoTester.check (sorted (a, reverse = True))
    autoTester.check (sorted (b, reverse = True))
    
    a.sort (reverse = True)
    autoTester.check (a)
    
    b.sort (reverse = True)
    autoTester.check (b)
    
    b.sort (key = lambda x: len (x)) 
    autoTester.check (b)

    b.sort (key = lambda x: len (x), reverse = True) 
    autoTester.check (b)

4.10. Hierarchical modules: both local to the project and global url-based

Testlet: modules
import modules.mod1.mod11.mod111
import modules.mod3
import modules.mod1.mod11.mod112
import modules.mod1
import modules.mod1.mod11
import modules.mod2
import modules.mod2.mod21
import modules.mod2.mod22

import modules.mod1.mod11.mod111 as aliasMod111
import modules.mod1 as aMod1

from modules.mod1.mod11 import mod111, mod112

from modules.mod2 import mod21 as aMod21, mod22 as aMod22

from modules.mod3 import *

from modules.mod1.mod11.mod111 import A

a = modules.mod1.mod11.mod111.A (12345)
pi = modules.mod1.pi
f = modules.mod2.f

def run (autoTester):
    # Import without 'as'
    autoTester.check ('modules')
    autoTester.check (a.f ())
    autoTester.check (modules.mod1.mod11.mod112.f ())
    autoTester.check (modules.mod1.mod11.e)
    autoTester.check (pi)
    autoTester.check (f (102030))
    autoTester.check (modules.mod2.mod21.f ())
    B = modules.mod2.mod22.B
    b = B ()
    autoTester.check (b.x)
    autoTester.check (modules.mod3.x)
    
    # Import with 'as'
    a2 = aliasMod111.A (6789101112)
    autoTester.check (a2.f ())
    autoTester.check (aMod1.pi)
    
    # From ... import without 'as'
    a3 = mod111.A (100.001)
    autoTester.check (a3.f ())
    autoTester.check (mod112.f ())
    
    # From ... import with 'as'
    autoTester.check (aMod21.f ())
    autoTester.check (aMod22.B () .x)
    
    # From ... import *
    autoTester.check (mod3Hundred)
    autoTester.check (mod3GetTwoHundred ())
    autoTester.check (A (123.321) .f ())

4.11. Indices and slices: LHS, RHS, basic and extended

Testlet: indices_and_slices
def run (autoTester):
    # Right hand side slices
    all = range (32)
    autoTester.check (all)
    
    autoTester.check (all [8 : 24])
    autoTester.check (all [8 : 24 : 2]) 
    
    # Left hand side slices
    aList = [3, 4, 7, 8]
    autoTester.check (aList)
    
    aList [4 : 4] = [9, 10]
    autoTester.check (aList)
    
    aList [2 : 2] = [5, 6]
    autoTester.check (aList)
    
    aList [0 : 0] = [1, 2]
    autoTester.check (aList)
    
    aList [ : : 2] = [x + 0.001 for x in range (10) if x % 2]
    autoTester.check (aList)

4.12. Lambda functions with all types of args

Testlet: lambda_functions
def run (autoTester):
    z = 1000
    autoTester.check ((lambda x, y: x + y + z) (111, 222))

    def f (list0, list1, aFunc):
        return [aFunc (*elem) for elem in zip (list0, list1)]

    x = f (range (10), range (0, 100, 10), lambda x, y: x + y + z)
    autoTester.check (x)
    
    autoTester.check (f (range (10, 20), range (100, 200, 10), lambda x, y: x * y + 100 * z))
    autoTester.check (f (range (10, 20), range (100, 200, 10), lambda *args: args [0] * args [1] + 100 * z))

4.13. List comprehensions: multi-loop and nested with multiple if’s

Testlet: list_comprehensions
def run (autoTester):
    squares = [i * i for i in range (10) if i % 2]
    autoTester.check (squares)
    
    tuples = [
        (x, y, z)
        for x in (100, 200, 300, 400, 500, 600, 700)
            for y in (10, 20, 30, 40, 50, 60, 70) if 20 < y  < 60
                for z in (1, 2, 3, 4, 5, 6, 7) if 200 < x < 600 if 2 < z < 6
    ]
    autoTester.check (tuples)
    
    tricky = [(2 * x, 3 * y) for x, y in ((10, 11), (20, 21))]
    autoTester.check (tricky)
    
    nested = [2 * x for x in [x * x for x in range (3)]]
    autoTester.check (nested)
    
    a = 100
    x = 5
    scopeTest = [x + a for x in range (5)]
    autoTester.check (x)
    autoTester.check (scopeTest)

4.14. Operator overloading

Testlet: operator_overloading
from org.transcrypt.stubs.browser import __pragma__

class Matrix:
    def __init__ (self, nRows, nCols, elements = []):
        self.nRows = nRows
        self.nCols = nCols
        
        if len (elements):
            self._ = elements
        else:
            self._ = [[0 for col in range (nCols)] for row in range (nRows)]
        
    def __mul__ (self, other):
        if type (other) == Matrix:
            result = Matrix (self.nRows, other.nCols)
            for iTargetRow in range (result.nRows):
                for iTargetCol in range (result.nCols):
                    for iTerm in range (self.nCols):
                        result._ [iTargetRow][iTargetCol] += self._ [iTargetRow][iTerm] * other._ [iTerm][iTargetCol]
            return result
        else:   # other is a scalar
            return self.__rmul__ (other)
                
    def __rmul__ (self, scalar):    # Only called if left operand is scalar, all other cases will call __mul__
        result = Matrix (self.nRows, self.nCols)
        for iRow in range (self.nRows):
            for iCol in range (self.nCols): 
                result._ [iRow][iCol] = scalar * self._ [iRow][iCol]
        return result
    
    def __add__ (self, other):
        result = Matrix (self.nRows, self.nCols)
        for iRow in range (self.nRows):
            for iCol in range (self.nCols):
                result._ [iRow][iCol] = self._ [iRow][iCol] + other._ [iRow][iCol]
        return result
        
    def __getitem__ (self, index):
        return self._ [index]

    def __setitem__ (self, index, value):
        self._ [index] = value
        
    def __repr__ (self):
        return repr (self._)
        
class Functor:
    def __init__ (self, factor):
        self.factor = factor
        
    __pragma__ ('kwargs')
    def __call__ (self, x, y = -1, *args, m = -2, n, **kwargs):
        return (
            self.factor * x,
            self.factor * y,
            [self.factor * arg for arg in args],
            self.factor * m,
            self.factor * n,
            # !!! [self.factor * kwargs [key] for key in sorted (kwargs.keys ())] Add supoprt for keys () on kwargs
        )
    __pragma__ ('nokwargs')
    
f = Functor (10)

__pragma__ ('kwargs')
def g (x, y = -1, *args, m = -2, n, **kwargs):
    return (x, y, args, m, n) # !!! , [kwargs [key] for key in sorted (kwargs.keys ())]) Add support for keys () on kwargs
__pragma__ ('nokwargs')
        
def run (autoTester):
    m0 = Matrix (3, 3, [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 10]
    ])
    
    m1 = Matrix (3, 3, [
        [10, 20, 30],
        [40, 50, 60],
        [70, 80, 90]
    ])
    
    x = 3
    y = x * 4 * x
    fast = 2 * 3
    
    __pragma__ ('opov')
    
    m1 [1][2] = m0 [1][2]
    slow = 2 + 3
    m2 = m0 * m1  + m1 * (m0 + m1)
    m3 = 2 * (2 * m0 * 3 * m1 + m2 * 4) * 2
    autoTester.check (m0 [1][1], m0 [1][2], m1 [1][1], m1 [1][2])
    
    __pragma__ ('noopov')
    
    fast2 = 16 * y + 1
    
    autoTester.check (m0, m1)
    autoTester.check (x, y)
    autoTester.check (m2)
    autoTester.check (m3)
    autoTester.check (fast, slow, fast2)
    
    x = 'marker'
    
    __pragma__ ('opov')
    autoTester.check (f (3, 4, 30, 40, m = 300, n = 400, p = 3000, q = 4000))
    autoTester.check (g (3, 4, 30, 40, m = 300, n = 400, p = 3000, q = 4000))
    __pragma__ ('noopov')

4.15. Properties

Testlet: properties
class A:
    p = 1234
    def getX (self):
        return self._x

    def setX (self, value):
        self._x = value
            
    def getY (self):
        return self._y

    def setY (self, value):
        self._y = 1000 + value  # Weird but should be possible
        
    def getY2 (self):
        return self._y

    def setY2 (self, value):
        self._y = value
        
    def getT    (self):
        return self._t

    def setT (self, value):
        self._t = value
        
    def getU (self):
        return self._u + 10000

    def setU (self, value):
        self._u = value - 5000
            
    x, y, y2 = property (getX, setX), property (getY, setY), property (getY2, setY2)
    t = property (getT, setT)
    u = property (getU, setU)
    
A.q = 5678

class B:
    def getZ (self):
        return self.z_
    
    def setZ (self, value):
        self.z_ = value
        
    z = property (getZ, setZ)
    
class C:
    def __init__ (self):
        self.offset = 1234

    def getW (self):
        return self.w_ + self.offset
        
    def setW (self, value):
        self.w_ = value - self.offset
        
    w = property (getW, setW)
    
def run (autoTester):
    a1 = A ()
    a2 = A ()

    a1.y2 = 1000
    a2.y2 = 2000
    
    a1.x = 5
    a1.y = 6
    
    a2.x = 7
    a2.y = 8

    a1.t = 77
    a1.u = 88
        
    autoTester.check (a1.x, a1.y, a1.y2)
    autoTester.check (a2.x, a2.y, a2.y2)
    autoTester.check (a1.p, a2.p, a1.q, a2.q)
    
    autoTester.check (a1.t, a1.u)
    
    b = B ()
    c = C ()
    
    b.z = 100100
    c.z = 200200
    c.w = 300300
    
    autoTester.check (a1.x, b.z, c.z, c.w)
    
    c.w = 400400
    c.z = 500500
    b.z = 600600
    
    autoTester.check (a1.x, b.z, c.z, c.w)

4.16. Set comprehensions

Testlet: set_comprehensions
def run (autoTester):
    even = {2 * i for i in [0, 9, 1, 7, 2, 8, 3, 6, 4, 5]}
    autoTester.check (even)
    
    odd = {2 * i + 1 for i in [5, 6, 7, 8, 9, 4, 3, 1, 2, 0]}
    autoTester.check (odd)
    
    even.add (12)
    even.add (12)
    autoTester.check (even)
    
    even.discard (12)
    even.discard (12)
    autoTester.check (even)
    
    uni = even.union (odd)
    autoTester.check (uni)
    
    autoTester.check (odd.isdisjoint (even))
    autoTester.check (uni.isdisjoint (even))
        
    autoTester.check (even.issuperset (uni))
    autoTester.check (uni.issuperset (even))
    
    autoTester.check (even.issubset (uni))
    autoTester.check (uni.issubset (even))
    
    first = {4, 1, 0, 5, 3, 2, 6}
    autoTester.check (first)
    
    second = {3, 5, 6, 9, 4, 7, 8}
    autoTester.check (second)
    
    inter = first.intersection (second)
    autoTester.check (inter)
    
    diff = first.difference (second)
    autoTester.check (diff)
    
    symDiff = first.symmetric_difference (second)
    autoTester.check (symDiff)
    
    aSet = {200, 4, 5, 100}
    aSet.update (first, symDiff, second)
    autoTester.check (aSet)
    

4.17. Simple and augmented assignment

Testlet: simple_and_augmented_assignment
class A:
    def __init__ (self):
        self.i = 0
        
    def f (self):
        return self.i

a = A ()
        
def run (autoTester):
    x = 3
    y = 5
    z = x + y
    autoTester.check (z)
    
    l = [1, 2, 3]
    l [1] = l [2]
    autoTester.check (l)
    
    # Should generate x++
    x += 1
    autoTester.check (x)
    x += +1
    autoTester.check (x)
    x -= -1
    autoTester.check (x)
    
    # Should generate y--
    y -= 1
    autoTester.check (y)
    y -= +1
    autoTester.check (y)
    y += -1
    autoTester.check (y)
    
    x += -3
    autoTester.check (x)
    
    x += 6
    autoTester.check (x)
    
    y -= 3
    autoTester.check (y)
    
    l [1] += l [1]
    autoTester.check (l)
    
    x += y
    y += x
    
    autoTester.check (x, y)
    
    f = a.f
    
    a.i += 1
    autoTester.check (f ())
    
    a.i += 10
    autoTester.check (f ())
    
    a.i += a.i
    autoTester.check (f ())

4.18. Tuple assignment: recursive and in for-headers using enumerate

Testlet: tuple_assignment
def run (autoTester):
    ((a, b), santa, [c, d], e) = ((1, 2), 'santa-claus', {3, 4}, 5)
    autoTester.check (a, b, c, d, e, santa)
    
    for i, x in enumerate ((0.5, 1.5, 2.5, 3.5)):
        autoTester.check (i, x)
    
    e, pi = 3.14, 2.74
    e, pi = pi, e
    autoTester.check (e, pi)
    
    def f ():
        return [(i, 2 * i) for i in range (7000, 10000, 1000)]
        
    def g ():
        return f
        
    [k, l], [m, n], (o, p) = g () ()
    
    autoTester.check (k, l, m, n, o, p)