# 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

    from org.transcrypt.stubs.browser import __pragma__
    import org.transcrypt.autotester

    import arguments
    import attribs_by_name
    import classes
    import complex_numbers
    import conditional_expressions
    import control_structures

    __pragma__ ('ifdef', '__py3.6__')   # Needed because Transcrypt imports are compile time
    if '__py3.6__' in __symbols__:      # Needed because CPython doesn't understand pragma's
        import dashed_numbers
    __pragma__ ('endif')

    import data_structures
    import decorators
    import dict_comprehensions
    import dictionaries
    import div_issues
    import div_pulls
    import docstrings
    import exceptions
    import extended_slices

    __pragma__ ('ifdef', '__py3.6__')   # Needed because Transcrypt imports are compile time
    if '__py3.6__' in __symbols__:      # Needed because CPython doesn't understand pragma's
        import fstrings
    __pragma__ ('endif')

    import general_functions
    import indices_and_slices

    __pragma__ ('ifdef', '__esv6__')
    if '__esv6__' in __symbols__:
        import iterators_and_generators
    __pragma__ ('endif')

    import lambda_functions
    import list_comprehensions
    import local_classes
    import metaclasses
    import module_builtin
    import module_cmath

    __pragma__ ('ifdef', '__esv6__')
    if '__esv6__' in __symbols__:
        import module_itertools
    __pragma__ ('endif')

    import module_math
    import modules
    import nonlocals
    import operator_overloading
    import properties
    import set_comprehensions
    import simple_and_augmented_assignment
    import truthyness
    import tuple_assignment

    autoTester = org.transcrypt.autotester.AutoTester ()

    autoTester.run (arguments, 'arguments')
    autoTester.run (attribs_by_name, 'attribs_by_name')
    autoTester.run (classes, 'classes')
    autoTester.run (complex_numbers, 'complex_numbers')
    autoTester.run (conditional_expressions, 'conditional_expressions')
    autoTester.run (control_structures, 'control_structures')

    __pragma__ ('ifdef', '__py3.6__')
    if '__py3.6__' in __symbols__:
        autoTester.run (dashed_numbers, 'dashed_numbers')
    __pragma__ ('endif')

    autoTester.run (data_structures, 'data_structures')
    autoTester.run (decorators, 'decorators')
    autoTester.run (dict_comprehensions, 'dict_comprehensions')
    autoTester.run (dictionaries, 'dictionaries')
    autoTester.run (div_issues, 'div_issues')
    autoTester.run (div_pulls, 'div_pulls')
    autoTester.run (docstrings, 'docstrings')
    autoTester.run (exceptions, 'exceptions')
    autoTester.run (extended_slices, 'extended_slices')

    __pragma__ ('ifdef', '__py3.6__')
    if '__py3.6__' in __symbols__:
        autoTester.run (fstrings, 'fstrings')
    __pragma__ ('endif')

    autoTester.run (general_functions, 'general_functions')
    autoTester.run (indices_and_slices, 'indices_and_slices')

    __pragma__ ('ifdef', '__esv6__')
    if '__esv6__' in __symbols__:
        autoTester.run (iterators_and_generators, 'iterators_and_generators')
    __pragma__ ('endif')

    autoTester.run (lambda_functions, 'lambda_functions')
    autoTester.run (list_comprehensions, 'list_comprehensions')
    autoTester.run (local_classes, 'local_classes')
    autoTester.run (metaclasses, 'metaclasses')
    autoTester.run (module_builtin, 'module_builtin')
    autoTester.run (module_cmath, 'module_cmath')

    __pragma__ ('ifdef', '__esv6__')
    if '__esv6__' in __symbols__:
        autoTester.run (module_itertools, 'module_itertools')
    __pragma__ ('endif')

    autoTester.run (module_math, 'module_math')
    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 (truthyness, 'truthyness')
    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. Attribute access by name: getattr, setattr, hasattr

Testlet: attribs_by_name

    class A:
        def __init__ (self):
            self.s = 'hello'

    a = A ()

    def run (autoTester):
        autoTester.check (a.s, getattr (a, 's'))

        setattr (a, 's', 'goodbye')
        autoTester.check (a.s, getattr (a, 's'))

        setattr (a, 't', 'exists')
        autoTester.check (hasattr (a, 't'), a.t, getattr (a, 't'))

        delattr (a, 't')
        autoTester.check (hasattr (a, 't'))

## 4.3. Classes: multiple inheritance and assignment of bound functions

Testlet: classes

    def run (autoTester):
        autoTester.check ('<br>General<br>')

        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')

        autoTester.check (hasattr (a, 'x'))
        autoTester.check (hasattr (a, 'y'))
        autoTester.check (hasattr (a, 'p'))
        autoTester.check (hasattr (a, 'q'))

        autoTester.check ('<br><br>Augmented isinstance<br>')
        # Augmented meaning: compatible with native JavaScript types

        simpleTypes = (dict, list, A, B, C, bool, str, float, int)
        tupleTypes = ((dict, list), (bool, int), (bool, A), (C, B))
        for i, types in enumerate ((simpleTypes, tupleTypes)):
            for j, aType in enumerate (types):
                for k, anObject in enumerate (({'a': 1}, [], a, C, c, C, b, True, 'a', 1, 1.2)):
                    autoTester.check (i, j, k, isinstance (anObject, aType))
                    if types == simpleTypes:
                        autoTester.check (i, j, k, isinstance (anObject, simpleTypes))

        autoTester.check ('<br><br>Method resolution order<br>')

        def mro (aClass, result = None):
            ''' Recursively assemble method resolution order from all base classes'''
            last = 0
            if result is None:
                result = [aClass]
                last = 1
            for aBase in aClass.__bases__:
                if not aBase in result and aBase != object:
                    result.append (aBase)
                    mro (aBase, result)
            if last and object in aClass.__bases__:
                aRoot.append (object)
            return result

        autoTester.check ([aClass.__name__ for aClass in mro (C)])

## 4.4. Complex numbers: Python's builtin complex datatype

Testlet: complex_numbers

    from org.transcrypt.stubs.browser import __pragma__

    def run (autoTester):
        x = 567
        y = -3
        z = 5 * x + 2 * y
        autoTester.check (x, y, z)

        __pragma__ ('opov')

        a = 234 + 3j
        b = 4 - 5j
        c = complex (-6, 7)
        autoTester.check (a, b, c)

        t = 6 * x - 3 * y + 7   # Just to check, faster with 'noopov'
        autoTester.check (t)

        d = 2 * a
        e = x * b
        f = z + d + e
        g = a / b
        h = a - b
        i = x - c
        j = a - x
        k = b + y

        autoTester.check (d, e, f, round (g.real, 2), round (g.imag, 2), h, i, j, k)

        __pragma__ ('noopov')

## 4.5. 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.6. Control structures: for...else, while...else, if...elif...else, break, continue

Testlet: control_structures

    def run (autoTester):
        for index in range (10):
            autoTester.check (index)

        for index in range (8, 16):
            autoTester.check (index)

        for index in range (8, 16, 2):
            autoTester.check (index)

        for index in range (10, 0, -1):
            autoTester.check (index)

        for index in range (16, 8, -2):
            autoTester.check (index)

        for animal in ('cat', 'dog', 'turtle', 'goldfish'):
            autoTester.check (animal)

        for index, square in enumerate ([x * x for x in range (10) if x % 2]):
            for y in (1, 2, 3):
                for z in (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.7. Data structures: tuple, list, dict, set

Testlet: data_structures

    def run (autoTester):
        aList = [1, 2, 3, 'moon', 'stars']
        autoTester.check (aList)
        aList.insert (3, 'sun')
        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)
        autoTester.check ('b' in anotherList)
        autoTester.check ('d' in 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))
        autoTester.check (2 in aSet)
        autoTester.check (4 in aSet)

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

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

        aString = 'c_cis_d_dis_e_f_fis_g_gis_a_ais_b_c'
        autoTester.check ('cis' in aString)
        autoTester.check ('g' in aString)
        autoTester.check ('bes'  in aString)
        autoTester.check ('z' in aString)

## 4.8. Decorators: function and class, with and without parameters

Transcrypt supports decorators on methods and classes. A decorator itself can be a function or an object with an overloaded __call__ operator. Parameterized decorator factories are also supported. Decorators on methods are not supported, except trivially for @classmethod. Methods decorated with @classmethod can be called on an object as demonstrated in the code below, not on a class. All flavours of properties are fully supported, though directly and not through decorator syntax. Extensive use of properties is demonstrated in the properties testlet.

Testlet: decorators

    from org.transcrypt.stubs.browser import __pragma__

    def run (autoTester):
        def repeat3 (bareFunc):
            __pragma__ ('kwargs')
            def innerFunc (*args, **kwargs):
                autoTester.check ('BEGIN repeat3')
                for i in range (3):
                    bareFunc (*args, **kwargs)
                autoTester.check ('END repeat3')
            __pragma__ ('nokwargs')
            return innerFunc

        def repeatN (n):
            def repeat (bareFunc):
                __pragma__ ('kwargs')
                def innerFunc (*args, **kwargs):
                    autoTester.check ('BEGIN repeatN ({})'.format (n))
                    for i in range (n):
                        bareFunc (*args, **kwargs)
                    autoTester.check ('END repeatN ({})'.format (n))
                __pragma__ ('nokwargs')
                return innerFunc
            return repeat

        class Repeater:
            def __init__ (self, n):
                self.n = n

            def __call__ (self, bareFunc):
                __pragma__ ('kwargs')
                def innerFunc (*args, **kwargs):
                    autoTester.check ('BEGIN repeat3')
                    for i in range (self.n):
                        bareFunc (*args, **kwargs)
                    autoTester.check ('END repeat3')
                __pragma__ ('nokwargs')
                return innerFunc

        @repeatN (4)
        @repeat3
        def funcNoArg ():
            autoTester.check ('spam')

        funcNoArg ()
        autoTester.check ()

        __pragma__ ('kwargs')
        @repeat3
        @repeatN (2)
        def funcArg (a):
            autoTester.check ('eggs', a)
        __pragma__ ('nokwargs')

        funcArg (3)
        autoTester.check ()

        funcArg (a = 4)
        autoTester.check ()

        __pragma__ ('opov')
        @Repeater (3)
        def funcNoArg2 ():
            autoTester.check ('toast')
        __pragma__ ('noopov')

        funcNoArg2 ()
        autoTester.check ()

        __pragma__ ('opov')
        __pragma__ ('kwargs')
        @Repeater (5)
        def funcArg2 (a):
            autoTester.check ('jam', a)
        __pragma__ ('nokwargs')
        __pragma__ ('noopov')

        funcArg2 (3)
        autoTester.check ()

        funcArg2 (a = 4)
        autoTester.check ()

        def next (bareFunc):
            def innerFunc (value):
                return bareFunc (value + 1)
            return innerFunc

        @next
        class Number:
            def __init__ (self, value):
                self.value = value

        autoTester.check ('two', Number (1) .value)

        class Test:
            @classmethod
            def f (cls, x, y):
                autoTester.check (cls.__name__, x, y)

            def g (self, x, y):
                autoTester.check (self.__class__.__name__, x, y)

        test = Test ()

        test.f (1, 2)
        test.g (3, 4)

## 4.9. 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.10. Diverse issues

Testlet: div_issues

    from org.transcrypt.stubs.browser import __pragma__, __new__, __envir__, __symbols__

    from div_issues.issue55 import *        # Names not exported from package's __init__.py

    def run (autoTester):
        autoTester.check ('Issue 24')   # Non keyword switch generates javascript SyntaxError
        switch = False
        autoTester.check (switch)

        autoTester.check ('Issue 27')   # Python list.index () not translated correctly
        autoTester.check (['zero', 'one', 'two', 'three', 'four'] .index ('three'))

        autoTester.check ('Issue 36')   # Bug in compiling lambda default argument values
        # Workaround for Python closures capturing variables rather than values
        # An extra enclosing scope is created to remember the value of the variable
        results = []
        for i in range (10):
            # results.append (lambda: i)                # Works nowhere
            # results.append (lambda j = i: j)          # Works only in Python
            results.append ((lambda j: lambda: j) (i))  # Works in Python and Transcrypt
        autoTester.check ([result () for result in results])

        autoTester.check ('Issue 37')   # Python integer division not translated correctly
        autoTester.check (15 // 7)

        autoTester.check ('Issue 40')   # Python parentheses dropped during translation
        autoTester.check (65 / (5 * 2))

        autoTester.check ('Issue 50')   # Wrong answer with parentheses moved during translation
        autoTester.check ((240 + 30 - 1) // 30 * 30)

        autoTester.check ('Issue 51')   # Wrong answer with set() compare
        a = 1
        b = 1
        autoTester.check (a, b, {a, b} == {1, 2})

        autoTester.check ('Issue 52')   # Non keyword 'default' generates javascript SyntaxError
        switch, case, default = 'switch', 'case', 'default'
        autoTester.check (switch, case, default)

        autoTester.check ('Issue 54')   # Type dict missing clear(), setdefault()
        aDict = {1: 11, 2: 22, 3: 33}
        autoTester.check (aDict)
        aDict.clear ()
        autoTester.check (aDict)

        autoTester.check ('Issue 60')   # Python bool() not translated
        three = 3
        one = three & 1
        seven = three | 4
        eight = one << 3
        four = eight >> 1
        aTrue = bool (three & one)
        aFalse = bool (three & four)
        autoTester.check (3, three, 1, one, 7, seven, 8, eight, 4, four, True, aTrue, False, aFalse)

        autoTester.check ('Issue 65')   # Adding two lists with + not supported
        __pragma__ ('opov')
        aList = [4, 5, 6]
        autoTester.check ([1, 2, 3,] + aList + [4, 5, 6])
        autoTester.check (3 * [1, 2, 3])
        autoTester.check ([1, 2, 3] * 3)
        aString = 'Crocodile'
        autoTester.check ('Tiger' + aString + 'Elephant')
        autoTester.check (3 * aString)
        autoTester.check (aString * 3)
        __pragma__ ('noopov')

        autoTester.check ('Issue 76')   # Python //= not translated correctly
        initially17 = 17
        autoTester.check (initially17)
        initially17 //= 2
        autoTester.check (initially17)
        initially17 //= 2
        autoTester.check (initially17)

        autoTester.check ('Issue 112')  # When using -e6, iterating TypedArrays or other non-list Iterables doesn't work
        try:
            if __envir__.executor_name == __envir__.transpiler_name: # CPython doesn't know Int8Array
                x = __new__ (Int8Array (2))
            else:
                x = [None, None]

            x [0] = 3
            x [1] = 2
            for i in x:
                autoTester.check (i)

            # Since JavaScript 5 gives no exception for a loop over a non-iterable, following code must only be executed for JavaScript 6
            # Since Transcrypt doesn't get to see all modules loaded by CPython, __ifdef__ cannot be made to do its thing for all modules in an efficient way for CPython
            # But a normal 'if' will work
            if '__esv6__' in __symbols__:
                y = 3
                for j in y:
                    autoTester.check (j)

        except: # No 'Exception' can be used behind this, since this is a JavaScript exception, and no subclass of Exception. ??? How desirable is this behaviour?
            pass
            # autoTester.check ('Detected iterating over non-iterable') # Minifier masks this exception, so we'll have to pass

        if '__esv6__' in __symbols__:   # "if" rather than "__pragma__ ('ifdef')" because CPython doesn't understand pragma's
            autoTester.check ('Issue 122')  # Problem with yield (or rather with slicing beyond list end)

            def chunks (aList, chunkLength):
                for index in range (0, len (aList), chunkLength):
                    yield aList [index : index + chunkLength]

            for chunk in chunks ([chr (index + 97) for index in range (26)], 10):
                autoTester.check (chunk)

        autoTester.check ('Issue 123')  # Python % shouldn't behave like JS %
        autoTester.check (10 % 3, 10 % -3, -10 % 3, -10 % -3, 10 % 10, 10 % -10, -10 % 10, -10 % -10)

        autoTester.check ('Issue 125')  # Strings not iterable
        abc = 'abc'

        for index in abc:
            autoTester.check (abc)

        autoTester.check ('Issue 127')  # Can't use the key 'keys' in a dict
        autoTester.check ({"include_docs": "true", "keys": ["key1", "key2"], "limit": 50})

        autoTester.check ('Issue 134')  # Operator %= translated incorrectly
        x0, x1, x2, x3, x4, x5 = 5, 12, -5, -5, 0, 0
        x0 %= 10; x1 %= 5; x2 %= 2; x3 %= -3; x4 %= 1; x5 %= -1000
        autoTester.check (x0, x1, x2, x3, x4)

        autoTester.check ('Issue 136')  # Method dict.get(key[, default]) not implemented
        aDict = {'a': 'ape', 'b': 'banana'}
        autoTester.check (aDict.get ('a', 'noApe'), aDict.get ('b'), aDict.get ('c', 'noCarot'), aDict.get ('d'))

        autoTester.check ('Issue 144')
        __pragma__('opov')
        aList = [x for x in [1, 2, 3]]
        autoTester.check (aList)
        __pragma__('noopov')

        autoTester.check ('<br><br>Issue 145<br>')  # List sorting incorrect in case of multiple columns

        class SortTest:
            def __init__ (self):
                self.alphabet = 'abcdefghijklmnopqrstuvwxyz'
                self.nChars = 10
                self.nCols = 10
                self.nRows = 30

                self.pseudoRandom = 0

                def randomWord ():
                    word = ''
                    for iChar in range (self.nChars):
                        self.pseudoRandom = (81212 * self.pseudoRandom + 28411) % 134456
    #                   self.pseudoRandom = (1234 * self.pseudoRandom + 57) % 137           # Deliberately short period
                        word += self.alphabet [self.pseudoRandom % 26]
                    return word

                self.rows = [[randomWord () for iCol in range (self.nCols)] for iRow in range (self.nRows)]

            def sort (self):
                for iCol in reversed (range (self.nCols)):
                    self.rows.sort (key = lambda row: row [iCol])

        sortTest = SortTest ()

        autoTester.check ('<br>Unsorted:<br>')
        for row in sortTest.rows:
            autoTester.check ('{}<br>'.format (','.join ([word for word in row])))

        sortTest.sort ()

        autoTester.check ('<br>Sorted:<br>')
        for row in sortTest.rows:
            autoTester.check ('{}<br>'.format (','.join ([word for word in row])))

        autoTester.check ('<br><br>Issue 169<br>')  # Add support for float('inf') and float('-inf')

        autoTester.check (int (1 / float ('inf')), int (1 / float ('-inf')))

## 4.11. Diverse pulls

Testlet: div_pulls

    # Also contains small enhancements

    'This is a single line docstring'
    class A:
        '''
        This
        is
        a
        multiline
        docstring
        '''
        def __init__ (self, x):
            'This is a single line comment'
            self.x = x
            '''
            This
            is
            a
            multiline
            docstring
            '''
        'This is a single line docstring'
    '''
    This
    is
    a
    multiline
    docstring
    '''

    a = A (5.5)

    def run (autoTester):
        autoTester.check ('Pull 56')
        s = 'abcdefghij'
        autoTester.check (s [2:3])
        autoTester.check (s [:3])
        autoTester.check (s [2:])
        autoTester.check (s [::2])

        autoTester.check ('Pull 59')
        autoTester.check (list (filter (lambda x: x % 2 == 0, range (10))))
        autoTester.check (list (map (lambda x: x*x, range (0, 31, 3))))

## 4.12. 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)

        tel = {'guido': 123}
        tel.update({'edsger': 42})
        autoTester.check (tel.setdefault ('linus', 456))
        autoTester.check (tel ['linus'])
        autoTester.check (tel.setdefault ('guido', 789))
        autoTester.check (tel.pop ('guido', 1))
        autoTester.check (tel.pop ('guido', 1))
        autoTester.check (tel.pop ('edsger', 2))
        autoTester.check (tel.pop ('foo', 'bar'))

## 4.13. Docstrings: __doc__ attribute generated optionally

To keep the generated code lean, generation of __doc__ attributes is controlled per module by __pragma__ ('docat') or by the -d / --docat command line switch, combined with user per module of __pragma__ ('nodocat')

Testlet: docstrings

    '''Just a module
    to test docstrings'''
    '''Not visible'''

    from org.transcrypt.stubs.browser import __pragma__
    __pragma__ ('docat')

    def run (autoTester):
        def f (p):
            '''Just a function
            called f'''
            '''Not visible'''
            autoTester.check (p)

        class C:
            '''Just a class
            called C'''
            '''Not visible'''
            def g (self, q):
                '''Just a method
                called g'''
                '''Not visible'''
                autoTester.check (q)

        autoTester.check (__doc__)
        autoTester.check ()

        autoTester.check (f.__doc__)
        autoTester.check ()

        autoTester.check (C.__doc__)
        autoTester.check ()

        autoTester.check (C.g.__doc__)
        autoTester.check ()

        f ('Doc')
        C () .g ('strings')

## 4.14. Exceptions: exception class hierarchy, finally

Testlet: exceptions

    from org.transcrypt.stubs.browser import __envir__, __new__, __pragma__

    if __envir__.executor_name == __envir__.transpiler_name:
        class BaseException:        # ??? Make part of __builtins__ for CPython compliance?
            pass

    class Ex1 (Exception):
        pass

    class Ex2 (Ex1):
        pass

    class Ex3 (Exception):
        pass

    class Table (BaseException):    # Any Python exception MUST inherit from BaseException
        def __init__ (self, *args):
            self.fields = args

        def __repr__ (self):
            return 'Table' + repr (self.fields) .replace (', ', ',') .replace ('\'', '')

    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)

        try:
            raise Ex3 ('that')
        except Ex1 as exception:
            autoTester.check ('mary')
            autoTester.check (exception)
        except:
            autoTester.check ('went')
        finally:
            autoTester.check ('the')

        autoTester.check (777)

        try:
            try:
                raise Ex3 ('lamb')
            except Ex1 as exception:
                autoTester.check ('was')
                autoTester.check (exception)
            finally:
                autoTester.check ('to')
        except Ex3 as exception:    # We should get here, exception not swallowed
            autoTester.check ('go')
            autoTester.check (exception)

        try:
            raise __new__ (Table ('he', 'followed', 'her'))
        except Ex1 as exception:
            autoTester.check ('to')
            autoTester.check (exception)
        except Table as exception:  # Pure JavaScript exception, if no Python __class__
            autoTester.check ('school')
            autoTester.check (exception)
        except Ex3 as exception:
            autoTester.check ('one')
            autoTester.check (exception)
        finally:
            autoTester.check ('day')

        try:
            assert 2 * 8 / 4 == 2, 'Assert error 1'
        except AssertionError as exception:
            autoTester.check (exception)

        try:
            assert 2 * 8 / 4 == 4, 'Assert error 2'
        except AssertionError as exception:
            autoTester.check (exception)

        try:
            assert 2 * 8 / 4 == 2
        except AssertionError as exception:
            autoTester.check (exception)

        try:
            assert 2 * 8 / 4 == 4
        except AssertionError as exception:
            autoTester.check (exception)

        autoTester.check (888)

        try:
            autoTester.check ("hello world 1")
        except:
            autoTester.check ("error 1")
        else:
            autoTester.check ("no error 1")

        i = 1 + 2
        try:
            autoTester.check ("hello world 2")
            if i == 3:  # Prevent unreachable code warning
                raise Exception ()
        except:
            autoTester.check ("error 2")
        else:
            autoTester.check ("no error 2")

## 4.15. Extended slices: facilitating NumScrypt and such

Testlet: extended_slices

    from org.transcrypt.stubs.browser import *
    from org.transcrypt.stubs.browser import __pragma__, __envir__

    def indices (key):
        if __envir__.executor_name == __envir__.transpiler_name:
            return tuple (key) if type (key) == list else key
        else:
            try:
                return key.indices (1000000000)
            except:
                try:
                    return tuple ([indices (subkey) for subkey in key])
                except:
                    return key

    class Test:
        def __init__ (self, autoTester):
            self.autoTester = autoTester

        def __getitem__ (self, key):
            self.autoTester.check ('getitem (', indices (key), ')')
            return 1234567

        def __setitem__ (self, key, value):
            self.autoTester.check ('setitem (', indices (key), ')', value)

    def run (autoTester):
        a = b = c = d = e = f = g = h = i = j = k = l = Test (autoTester)

        __pragma__ ('opov')

        a [1:2:3, 4:5:6] = b [7:8:9]
        c [1:2:3] = d [4:5:6, 7:8:9]
        e [1, 1:2:3, 3] = f [4, 4:5:6, 6]
        g [1, 2, 3] = h [1, 2, 3]
        i [1] = j [1]
        k [1:2:3] = l [1:2:3]

## 4.16. General functions: sort and sorted

Testlet: general_functions

    from org.transcrypt.stubs.browser import __pragma__

    class A:
        foo='bar'
        def __init__ (self):
            self.foo2 = 'bar2'

    class B (A):
        foo3='bar3'
        def __init__ (self):
            self.foo4 = 'bar4'

    def run (autoTester):
        autoTester.check ('sort and sorted<br>')
        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)

        autoTester.check ('<br><br>dir<br>')
        autoTester.check ([entry for entry in dir (A) if not entry.startswith ('__')])
        autoTester.check ([entry for entry in dir (A()) if not entry.startswith ('__')])
        autoTester.check ([entry for entry in dir (B) if not entry.startswith ('__')])
        autoTester.check ([entry for entry in dir (B()) if not entry.startswith ('__')])

        autoTester.check ('<br><br>any, all, sum<br>')
        list1 = ['ape', 'node', 'mice']
        list2 = ['vim', '', 'jet']
        list3 = ['', '', '']
        list4 = [[1, 2], [1], []]   # Truthyness into play
        autoTester.check (list1, any (list1), all (list1))
        autoTester.check (list2, any (list2), all (list2))
        autoTester.check (list3, any (list3), all (list3))
        autoTester.check (list4, any (list4), all (list4))

        autoTester.check (sum (range (5)))

        __pragma__ ('ifdef', '__esv6__')
        if '__esv6__' in autoTester.symbols:
            def generator1 ():
                for i in range (5):
                    yield i;

            def generator2 ():
                for i in range (5):
                    if i % 2:
                        yield 0
                    else:
                        yield i;

            def generator3 ():
                for i in range (5):
                    yield 0;

            autoTester.check (generator1 (), any (generator1 ()), all (generator1 ()))
            autoTester.check (generator2 (), any (generator2 ()), all (generator2 ()))
            autoTester.check (generator3 (), any (generator3 ()), all (generator3 ()))

            autoTester.check (sum (generator1 ()))
        __pragma__ ('endif')

## 4.17. 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.18. Iterators and generators

Testlet: iterators_and_generators

    from org.transcrypt.stubs.browser import __pragma__

    class Iterable:
        def __init__ (self, i):
            self.aList = range (0, 50, i)

        def __iter__ (self):
            return Iterator (self)

    class Iterator:
        def __init__ (self, iterable):
            self.iterable = iterable
            self.index = -1

        def __next__ (self):    # Should be auto-wrapped in a next (self) by the compiler
            self.index += 1

            if self.index > 5:
                raise StopIteration ()

            return self.iterable.aList [self.index]

        def __iter__ (self):
            return self

    def exhaustableGenerator (i):
        for i in range (5):
            yield 2 * i

    def run (autoTester):
        exhaustableGenExp = (a * a * a for a in [10, 20, 30])   # Currently still converted to iterator on list comprehension, must also be iterable
        # So becomes py_iter (aList).
        # List already has an __iter__ which it will return, it's a __PyIterator__
        # To that __PyIterator__, that will already have a __next__, py_iter first adds a next
        # So exhaustableGenExp is an iterator with a next and a __next__
        # If we call iter on that, py_iter is calle again py_iter, on an object with a next and a next __next__
        # For this reason py_iter needs a recursion prevention check

        iterables = [Iterable (7), exhaustableGenerator (5), [i * 3 for i in range (5)], exhaustableGenExp]

        for iterable in iterables:
            autoTester.check ('[1]')
            iterator = iter (iterable)
            try:
                while True:
                    autoTester.check (next (iterator))
            except Exception as exception:
                autoTester.check (exception.__class__.__name__)

            autoTester.check ('[2]')
            iterator = iter (iterable)
            try:
                while True:
                    autoTester.check (next (iterator))
            except Exception as exception:
                autoTester.check (exception.__class__.__name__)

        for iterable in iterables:
            autoTester.check ('[3]')
            for n in iterable:
                autoTester.check (n)

            autoTester.check ('[4]')
            for n in iterable:
                autoTester.check (n)

        __pragma__ ('gsend')

        def test0 ():
            r = 0
            while True:
                r = r + (yield r)

        gen0 = test0()
        next (gen0)
        autoTester.check (gen0.send (1))
        autoTester.check (gen0.send (2))

        def test1 ():
            r = 0
            while True:
                r = (yield r) + r

        gen1 = test1()
        next (gen1)
        autoTester.check (gen1.send (3))
        autoTester.check (gen1.send (4))

## 4.19. 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.20. 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.21. Local classes: inside other classes and functions

Testlet: local_classes

    def run (autoTester):
        class A:
            class B:
                class C:
                    def __init__ (self, x):
                        self.x = x

                    def tell (self):
                        autoTester.check (self.x)
                        autoTester.check (self.e)

                    # Limitation: no destructuring assignment inside nested classes
                    e = 3

                def __init__ (self, x):
                    self.x = x

                def tell (self):
                    autoTester.check (self.x)
                    autoTester.check (self.d)

                d = 2

            c = 1

            def __init__ (self, x):
                self.x = x

            def tell (self):
                autoTester.check (self.x)
                autoTester.check (self.c)

        def f (x):
            class G:
                class H:
                    def __init__ (self, x):
                        self.x = x

                    def tell (self):
                        autoTester.check (self.x)
                        autoTester.check (self.i)

                    i = 5

                def __init__ (self, x):
                    self.x = x

                def tell (self):
                    autoTester.check (self.x)

                k = 4

            g = G (6)
            g.tell ()
            autoTester.check (g.k)

            h = G.H (7)
            h.tell ()
            autoTester.check (h.i)

            class P (A.B):
                pass

            p = P (7)
            p.tell ()
            autoTester.check (p.d)

        a = A (8)
        b = a.B (9)
        c = b.C (10)

        a.tell ()
        b.tell ()
        c.tell ()

        autoTester.check (a.c)
        autoTester.check (b.d)

        f (7)

## 4.22. Metaclasses: overriding type.__new__ in a descendant metaclass

Testlet: metaclasses

    from org.transcrypt.stubs.browser import __pragma__

    class UppercaserMeta (type):
        def __new__ (meta, name, bases, attribs):
            __pragma__ ('jsiter')       # Translate for ... in directly to JavaScript for ... in ... and translate {} to bare {} rather than to dict {}
                                        # Using bare {} as attribs parameter to __new__ avoids dict attributes masking regular attributes
                                        # For more flexibility use __pragma__ ('js', '{}', '''...''')
            upperAttribs = {}

            for attribKey in attribs:   # Translates to 'for (var attribKey in attribs)' by virtue of __pragma__ ('jsiter'), to iterate over the attributes of a bare JavaScript {}
                upperAttribs [attribKey if  attribKey.startswith ('__') else attribKey.upper ()] = attribs [attribKey]

            __pragma__ ('nojsiter')

            return type.__new__ (meta, name, bases, upperAttribs)

    class Uppercaser (metaclass = UppercaserMeta):
        pass

    class Animal (Uppercaser):
        class Thoughts:
            quantity = 7

        # Limitation: no destructuring assignment if metaclass has to alter attributes
        color = 'Brown'
        state = 'Moving'

        def move (self):
            return 'Move'

    class Plant (Uppercaser):
        class Thoughts:
            quantity = 6

        color = 'Green'
        state = 'Growing'

        def grow (self):
            return 'Grow'

    class Stone:
        class Thoughts:
            quantity = 5

        color = 'Gray'

        def be (self):
            return ('Being')

    def run (autoTester):
        animal = Animal ()
        autoTester.check (animal.THOUGHTS.quantity, Animal.COLOR, animal.COLOR, animal.MOVE ())

        plant = Plant ()
        autoTester.check (plant.THOUGHTS.quantity, Plant.COLOR, plant.COLOR, plant.GROW ())

        stone = Stone ()
        autoTester.check (stone.Thoughts.quantity, Stone.color, stone.color, stone.be ())

## 4.23. Module builtin: a small part of it demo'ed

Testlet: module_builtin

    # coding: utf-8

    from org.transcrypt.stubs.browser import __envir__

    def canonizeString (aString):
        if __envir__.executor_name == 'transcrypt':
            return aString.replace ('\t', '\\t') .replace ('\n', '\\n')
        else:
            return aString

    def canonizeStringList (stringList):
        return [canonizeString (aString) for aString in stringList]

    def run (autoTester):
        autoTester.check ('min', min (-1.1, -1, -3))
        autoTester.check ('max', max (-1.1, -1, -3))
        autoTester.check ('abs', abs (-1), abs (1), abs (0), abs (-0.1), abs (0.1))
        autoTester.check ('ord', ord ('a'), ord ('e´'[0]))  # This is the 2 codepoint version

        autoTester.check ('round',
            round (4.006),
            round (4.006, 2),
            round (4060, -2),

            round (-4.006),
            round (-4.006, 2),
            round (-4060, -2),

            round (1/2.),
            round (1/2., 1),
            round (1/2, 1),
            round (1/3., 2),

            round (-1/2.),
            round (-1/2., 1),
            round (-1/2, 1),
            round (-1/3., 2),

            round (0.5),
            round (0.51),
            round (1.5),
            round (1.51),
            round (1.51),
            round (2.5),
            round (2.59),
            round (3.5),
            round (3.59),

            round (-0.5),
            round (-0.51),
            round (-1.5),
            round (-1.51),
            round (-1.51),
            round (-2.5),
            round (-2.59),
            round (-3.5),
            round (-3.59)
        )

        strings = [
            'der des dem den die der den die das des dem das',
            'an auf hinter ueber    neben vor   zwischen',
            '''
                durch
                fuer
                ohne
                um
                bis
                gegen
                entlang
            ''',
            'eins,zwei,drie,vier,fuenf,sechs,sieben'
        ]

        autoTester.check ('<br><br>split')
        for aString in strings:
            autoTester.check (
                canonizeString (aString),
                canonizeStringList (aString.split ()),
                canonizeStringList (aString.split (' ')),
                canonizeStringList (aString.split (' ', 4)),
                canonizeStringList (aString.split ('\t')),
                canonizeStringList (aString.split ('\t', 4)),
                canonizeStringList (aString.split ('\n')),
                canonizeStringList (aString.split ('\n', 4)),
                canonizeStringList (aString.split (',')),
                canonizeStringList (aString.split (',', 4)),
                '<br>'
            )

        autoTester.check ('<br>rsplit')
        for aString in strings:
            autoTester.check (
                canonizeString (aString),
                canonizeStringList (aString.rsplit ()),
                canonizeStringList (aString.rsplit (' ')),
                canonizeStringList (aString.rsplit (' ', 4)),
                canonizeStringList (aString.rsplit ('\t')),
                canonizeStringList (aString.rsplit ('\t', 4)),
                canonizeStringList (aString.rsplit ('\n')),
                canonizeStringList (aString.rsplit ('\n', 4)),
                canonizeStringList (aString.rsplit (',')),
                canonizeStringList (aString.rsplit (',', 4)),
                '<br>'
            )

## 4.24. Module cmath: allmost all of Python's cmath module

Testlet: module_cmath

    from org.transcrypt.stubs.browser import __pragma__
    from cmath import *

    twoPi = 2 * pi
    nDecs = 5

    __pragma__ ('opov')

    def run (autoTester):
        autoTester.check (phase (1 + 1j))

        aPolar = polar (3 + 5j)
        autoTester.check (round (aPolar [0], nDecs), aPolar [1])

        aRect = rect (*aPolar)
        autoTester.check (round (aRect.real), round (aRect.imag))

        anExp = exp (-2.2 - 3.3j)
        autoTester.check (round (anExp.real, nDecs), round (anExp.imag, nDecs))

        aLog = log (anExp)
        autoTester.check (round (aLog.real, nDecs), round (aLog.imag, nDecs))

        anExp10 = aLog ** 10
        autoTester.check (round (anExp10.real, nDecs), round (anExp10.imag, nDecs))

        aLog10 = log10 (anExp10)
        autoTester.check (round (aLog10.real, nDecs), round (aLog10.imag, nDecs))

        anExpRect = aLog ** aRect
        autoTester.check (round (anExpRect.real, nDecs), round (anExpRect.imag, nDecs))

        aLogRect = log (anExpRect, aRect)
        autoTester.check (round (aLogRect.real, nDecs), round (aLogRect.imag, nDecs))

        aSqrt = sqrt (1j)
        autoTester.check (round (aSqrt.real, nDecs), round (aSqrt.imag, nDecs))
        autoTester.check (sqrt (4))
        anotherSqrt = sqrt (-4)
        autoTester.check (round (anotherSqrt.real), round (anotherSqrt.imag))

        anAsin = asin (1 + 2j)
        autoTester.check (round (anAsin.real, nDecs), round (anAsin.imag, nDecs))

        anAcos = acos (-2 + 3j)
        autoTester.check (round (anAcos.real, nDecs), round (anAcos.imag, nDecs))

        anAtan = atan (3 - 4j)
        autoTester.check (round (anAtan.real, nDecs), round (anAtan.imag, nDecs))

        aSin = sin (anAsin)
        autoTester.check (round (aSin.real), round (aSin.imag))

        aCos = cos (anAcos)
        autoTester.check (round (aCos.real), round (aCos.imag))

        aTan = tan (anAtan)
        autoTester.check (round (aTan.real), round (aTan.imag))

        anAsinh = asinh (aCos)
        autoTester.check (round (anAsinh.real, nDecs), round (anAsinh.imag, nDecs))

        anAcosh = acosh (aSin)
        autoTester.check (round (anAcosh.real, nDecs), round (anAcosh.imag, nDecs))

        anAtanh = atanh (aTan)
        autoTester.check (round (anAtanh.real, nDecs), round (anAtanh.imag, nDecs))

        aSinh = sinh (anAsinh)
        autoTester.check (round (aSinh.real), round (aSinh.imag))

        aCosh = cosh (anAcosh)
        autoTester.check (round (aCosh.real), round (aCosh.imag))

        aTanh = tanh (anAtanh)
        autoTester.check (round (aTanh.real), round (aTanh.imag))

## 4.25. Module itertools: allmost all of Python's itertools module

Testlet: module_itertools

    from itertools import *
    from math import pow

    def fibonacci():
        a, b = 0, 1
        for i in range (10):
            yield a
            a, b = b, a + b

    squares = [i * i for i in range (10)]

    chars = 'thequickbrownfoxjumpsoverthelazydog'

    def run (autoTester):
        autoTester.check ('islice count', list (islice (count (10, 2), 4, 40, 3)))
        autoTester.check ('islice cycle', list (islice (cycle (fibonacci ()), 15)))
        autoTester.check ('repeat', list (repeat (3.14, 15)))
        autoTester.check ('islice repeat', list (islice (repeat (2.74), 15)))
        autoTester.check ('accumulate', list (accumulate (range (5))))

        def add (total, element):
            return total + element

        autoTester.check ('accumulate', list (accumulate (['alamak', 'mirach', 'sirrah'], add)))

        autoTester.check ('chain', list (chain (fibonacci (), squares, chars)))
        autoTester.check ('chain.from_iterable', list (chain.from_iterable (['ape', 'node', 'mice', 'vim', 'sus', 'jet'])))

        selectors = [True, True, False, True, False, False, True, True, False, True]

        autoTester.check ('compress', list (compress (
            ['{}{}'.format (('take' if selector else 'leave'), index) for index, selector in enumerate (selectors)],
            selectors
        )))

        autoTester.check ('dropwhile', list (dropwhile (lambda x: x < 5, [1, 4, 6, 4, 1])))
        autoTester.check ('filterfalse', list (filterfalse (lambda x: x % 2, range (10))))

        things = [('animal', 'bear'), ('animal', 'duck'), ('plant', 'cactus'), ('vehicle', 'speed boat'), ('vehicle', 'school bus')]

        for key, group in groupby (things, lambda x: x [0]):
            for thing in group:
                autoTester.check ('A {} is a {}.' .format (thing[1], key))
            autoTester.check (' ')

        autoTester.check ('islice', list (islice ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2, 9, 2)))

        autoTester.check ('starmap', [int (x) for x in starmap (pow, [(2, 5), (3, 2), (10, 3)])])
        autoTester.check ('takewhile', list (takewhile (lambda x: x < 5, [1, 4, 6, 4, 1])))

        i1, i2 = tee (islice (count (), 5))
        autoTester.check ('tee', list (i1), list (i1), list (i2))

        autoTester.check ('product', list (product ('ABCD', 'xy')), list (product (range (2), repeat = 3)))

        autoTester.check ('permutations', list (permutations ('ABCD')), list (permutations ('ABCD', 2)))

        autoTester.check ('combinations',
            list (combinations ('ABCD', 2)),
            list (combinations ([1, 2, 3, 4, 5], 3)),
            list (combinations (islice (count (), 6), 4))
        )

        autoTester.check ('combinations_with_replacement',
            list (combinations_with_replacement ('ABCD', 2)),
            list (combinations_with_replacement ([1, 2, 3, 4, 5], 3)),
            list (combinations_with_replacement (islice (count (), 6), 4))
        )

## 4.26. Module math: allmost all of Python's math module

Testlet: module_math

    from math import *

    def run (autoTester):
        autoTester.check (pi)
        autoTester.check (e)

        autoTester.check (exp (3))
        autoTester.check (int (expm1 (5)))

        autoTester.check (log (0.2))
        autoTester.check (round (log (1024, 2)))
        autoTester.check (log1p (5))
        autoTester.check (int (log2 (257)))
        autoTester.check (int (log10 (1001)))

        autoTester.check (pow (3, 4.5))
        autoTester.check (sqrt (25.1))

        autoTester.check (sin (10))
        autoTester.check (cos (10))
        autoTester.check (tan (10))

        autoTester.check (asin (0.5))
        autoTester.check (acos (0.5))
        autoTester.check (atan (0.5))
        autoTester.check (atan2 (1, 2))

        autoTester.check (int (hypot (3, 4.1)))

        autoTester.check (degrees (pi/2.1))
        autoTester.check (radians (90))

        autoTester.check (sinh (1))
        autoTester.check (cosh (1))
        autoTester.check (tan (1))

        autoTester.check (asinh (70))
        autoTester.check (acosh (70))
        autoTester.check (atan (70))

        autoTester.check (floor (3.5))
        autoTester.check (ceil (3.5))
        autoTester.check (trunc (3.5))

## 4.27. Module random: most important functions of Python's random module

Manual_test: module_random

    from random import *

    result = ''

    def output (any):
        result += any + '<br>\n'

    for fixedSeed in (False, True):
        if fixedSeed:
            seed (3)
        else:
            seed ()

        output ('------ {} ------'.format ('fixed seed' if fixedSeed else 'auto seed'))

        output ('--- randint ---')
        for i in range (20):
            output (randint (10, 20))

        output ('<br>\n--- choice ---')
        for i in range (20):
            output (choice ([1, 2, 3, 4, 5]))

        output ('<br>\n--- random ---')
        for i in range (20):
            output (random ())

        output ('<br>\n')

    document.getElementById ('output') .innerHTML = result

## 4.28. Modules: hierarchical, 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.29. Nonlocals

Testlet: nonlocals

    def run (autoTester):
        test1 = 1
        test2 = 2

        def f ():
            test1 = 10

            nonlocal test2
            test2 = 20

            autoTester.check (test1, test2)

        f ()
        autoTester.check (test1, test2)

## 4.30. 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))

        autoTester.check (set ((1, 2, 3)) == set ((3, 2, 1)))
        autoTester.check (set ((1, 2, 3)) != set ((3, 2, 1)))
        autoTester.check (set ((1, 3)) == set ((3, 2, 1)))
        autoTester.check (set ((1, 3)) != set ((3, 2, 1)))
        autoTester.check (set ((1, 2)) < set ((3, 2, 1)))
        autoTester.check (set ((1, 2, 3)) <= set ((3, 2, 1)))
        autoTester.check (set ((1, 2, 3)) > set ((2, 1)))
        autoTester.check (set ((1, 2, 3)) >= set ((3, 2, 1)))

        autoTester.check ((1, 2, 3) == (1, 2, 3))
        autoTester.check ([1, 2, 3] == [1, 2, 3])
        autoTester.check ((1, 2, 3) != (1, 2, 3))
        autoTester.check ([1, 2, 3] != [1, 2, 3])
        autoTester.check ((2, 1, 3) == (1, 2, 3))
        autoTester.check ([2, 1, 3] == [1, 2, 3])
        autoTester.check ((2, 1, 3) != (1, 2, 3))
        autoTester.check ([2, 1, 3] != [1, 2, 3])
        __pragma__ ('noopov')

## 4.31. 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.32. 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.33. 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.34. Truthyness: optional Python-style evaluation of truthyness, falsyness and non-empty container selection

Testlet: truthyness

    from org.transcrypt.stubs.browser import __pragma__

    __pragma__ ('tconv')

    def run (autoTester):
        autoTester.check (len ({1:2}))

        autoTester.check ('Select nonemtpy container, if any<br>')

        autoTester.check ((0) or (1, 2, 3))
        autoTester.check (() or (1, 2, 3))
        autoTester.check (() or ())

        autoTester.check ((-1) or (0) or (1, 2, 3))
        autoTester.check (() or (0) or (1, 2, 3))
        autoTester.check (() or () or (1, 2, 3))
        autoTester.check (() or () or ())

        autoTester.check ([0] or [1, 2, 3])
        autoTester.check ([] or [1, 2, 3])
        autoTester.check ([] or [])

        autoTester.check ([-1] or [0] or [1, 2, 3])
        autoTester.check ([] or [0] or [1, 2, 3])
        autoTester.check ([] or [] or [1, 2, 3])
        autoTester.check ([] or [] or [])

        autoTester.check ({0} or {1, 2, 3, 4})
        autoTester.check (set () or {1, 2, 3, 4})
        autoTester.check (set () or set ())

        autoTester.check ({-1} or {0} or {1, 2, 3, 5})
        autoTester.check (set () or {0} or {1, 2, 3, 6})
        autoTester.check (set () or set () or {1, 2, 3, 7})
        autoTester.check (set () or set () or set ())

        autoTester.check ({0:10} or {1:11, 2:12, 3:13})
        autoTester.check ({} or {1, 2, 3, 8})
        autoTester.check ({} or {})

        autoTester.check ({-1:-11} or {0:10} or {1:11, 2:12, 3:13})
        autoTester.check ({} or {0:10} or {1:11, 2:12, 3:13})
        autoTester.check ({} or {} or {1:11, 2:12, 3:13})
        autoTester.check ({} or {} or {})

        autoTester.check ('<br><br>')
        autoTester.check ('Boolean evaluations')
        for expression in (
            '<br> -- falsy -- <br>',
            (),
            [],
            set (),
            {},
            0,
            '',
            3 > 5,
            False,
            '<br> -- truthy -- <br>',
            (1, 2, 3),
            [1, 2, 3],
            {1, 2, 3},
            {'a': 1, 'b': 2, 'c': 3},
            3,
            'hello',
            5 > 3,
            True
        ):
            if expression in ('<br> -- falsy -- <br>', '<br> -- truthy -- <br>'):
                autoTester.check (expression)
            else:
                autoTester.check (expression, ' . . . ')
                autoTester.check ('operators')
                autoTester.check (not not expression)
                autoTester.check (not not (True and expression))
                autoTester.check (not not (False or expression))
                autoTester.check (not not (expression and True))
                autoTester.check (not not (expression and False))

                autoTester.check ('if')
                if expression:
                    autoTester.check (True)
                else:
                    autoTester.check (False)

                if expression or expression:
                    autoTester.check (True)
                else:
                    autoTester.check (False)

                if False:
                    autoTester.check ('if')
                elif expression:
                    autoTester.check ('elif')
                else:
                    autoTester.check ('else')

                autoTester.check ('while')
                while expression:
                    autoTester.check (True)
                    break

                autoTester.check ('condex')
                autoTester.check (True if expression else False)

        if (0.0):
            autoTester.check ('0.0')
        elif (0.1):
            autoTester.check ('0.1')
        else:
            autoTester.check ('Shouldn\'t be here...')

        class A:
            pass

        autoTester.check (not not A ())

## 4.35. 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)