# 2. Getting started

## 2.1. Installation

Transcrypt is currently tested under Windows and Linux, OS X will probably follow later. To be able to use it, Python 3.5 has to be installed. To install Transcrypt itself, make sure the Scrypts directory of your Python installation is in your system path. Then type

pip install transcrypt

from the command prompt.

Alternatively, for manual installation under Windows or Linux, follow the steps below:

1. Download the Transcrypt zip and unpack it anywhere you like
2. Add ../Transcrypt-<version>/Transcrypt to your system path

You can test your installation as follows:

1. Go to directory ../Transcrypt-<version>/Transcrypt/development/automated_tests/transcrypt
2. From the command prompt run transcrypt -b autotest.py. This will compile the autotests into file autotest.js and put it into the __javascript__ subdirectory. Do NOT go to that directory (there’s no need, stay where you went at point 4)
3. From the command prompt run transcrypt -r autotest.py. This will run the autotests with CPython creating file autotest.html that refers to the generated autotest.js file
4. Load the autotest.html into your browser, e.g. by clicking on it (tests were done with Chrome). It will load autotest.js, run it and compare the output with what was generated by CPython. It should report no errors

To experiment with Transcrypt yourself:

1. Create a directory for your experiments
2. Make your own thing there, e.g. experiment1.py
3. Compile with transcrypt -b experiment1.py
4. Make an HTML page that will load your code in the browser. Use the HTML file generated by the autotest as an example of how to do that
5. Load and run the HTML + JS

You may also want to try the demo’s.

### 2.1.1. Troubleshooting checklist

1. Transcrypt was installed using pip, but import transcrypt fails. Transcrypt isn’t a library but a compiler. Install and run it as described in this chapter.
2. Transcrypt reports an error containing the word ‘java’. Transcrypt produces both prettyfied and minified JavaScript output. For the minification it makes use of the Google Closure Compiler, which is included in the distribution and requires Java to run. You can check proper installation of Java by typing the word java on the command line. This should give you a list of options: Usage: java [-options] class []args...] and so on. If you can’t or won’t install Java, you can run Transcrypt without minification by using the -n command line switch.
3. The static checker doesn’t find all errors it could. The static checks, performed by the PyFlakes package that’s part of the distribution, are of a ‘light’ variety. Style checks and false positives are avoided. The accent is on finding undefined identifiers and unused variables.

## 2.2. Your first Transcrypt program

Open a command prompt in the demos/hello directory and type transcrypt hello.py. Then click on hello.html to load it into your browser.

After clicking on both buttons a few times, take a look at hello.html. As you can see, eventhandlers are connected to the buttons exactly as you would do with JavaScript.

Then look at hello.py. Note that JavaScript functions like document.getElementById can be called from Python exactly as you would call them from JavaScript, but with Python data.

The minified JavaScript file including the Transcrypt runtime is only 10kB. With non-trivial programs this overhead becomes negligible. Transcrypt applications in themselves don’t need any external files. Of course you can use extensive JavaScript libraries served by content delivery networks as you normally would. But you can also make very compact stand alone applications. The most efficient thing to do is pack all functionality for a page in a single Transcrypt program. Note that the source can consist of many modules if needed and many callback entrypoints can be provided. But it is one stateful application, just like it would be on the desktop.

In hello.html, Python handlers are attached directly to the onclick events

    <script src="__javascript__/hello.js"></script>
    <h2>Hello demo</h2>

    <p>
    <div id = "greet">...</div>
    <button onclick="hello.solarSystem.greet ()">Click me repeatedly!</button>

    <p>
    <div id = "explain">...</div>
    <button onclick="hello.solarSystem.explain ()">And click me repeatedly too!</button>

In hello.py, JavaScript function document.getElementById is called directly from Python, using plain Python values

    from itertools import chain

    class SolarSystem:
        planets = [chain (planet, (index + 1,)) for index, planet in enumerate ((
            ('Mercury', 'hot', 2240),
            ('Venus', 'sulphurous', 6052),
            ('Earth', 'fertile', 6378),
            ('Mars', 'reddish', 3397),
            ('Jupiter', 'stormy', 71492),
            ('Saturn', 'ringed', 60268),
            ('Uranus', 'cold', 25559),
            ('Neptune', 'very cold', 24766)
        ))]

        lines = (
            '{} is a {} planet',
            'The radius of {} is {} km',
            '{} is planet nr. {} counting from the sun'
        )

        def __init__ (self):
            self.lineIndex = 0

        def greet (self):
            self.planet = self.planets [int (Math.random () * len (self.planets))]
            document.getElementById ('greet') .innerHTML = 'Hello {}'.format (self.planet [0])
            self.explain ()

        def explain (self):
            document.getElementById ('explain').innerHTML = (
                self.lines [self.lineIndex] .format (self.planet [0], self.planet [self.lineIndex + 1])
            )
            self.lineIndex = (self.lineIndex + 1) % 3

    solarSystem = SolarSystem ()

## 2.3. Command line switches

The available command line switches will be shown if you run transcript -h. They are specified in the source code of Transcrypt as follows:

Transcrypt command line switches as specified in module/orgs/transcrypt/utils.py

    class CommandArgs:
        def parse (self):
            self.argParser = argparse.ArgumentParser ()

            self.argParser.add_argument ('source', nargs='?', help = ".py file containing source code of main module")
            self.argParser.add_argument ('-b', '--build', help = "rebuild all target files from scratch", action = 'store_true')
            self.argParser.add_argument ('-c', '--check', help = "perform static check as part of compilation", action = 'store_true')
            self.argParser.add_argument ('-f', '--fcall', help = "enable fastcall mechanism by default. You can also use __pragma__ ('fcal') and __pragma__ (\'nofcall\')", action = 'store_true')
            self.argParser.add_argument ('-i', '--iconv', help = "enable automatic conversion to iterable by default. DISADVISED, since it will result in a type check for each for-loop. Preferable use __pragma__ ('iconv') and __pragma__ (\'noiconv\') to enable automatic conversion locally", action = 'store_true')
            self.argParser.add_argument ('-j', '--jskeys', help = "interpret {key: 'value'} as {'key': 'value'} and forbid {key (): 'value'}, as JavaScript does. DISADVISED, since it's less flexible than the Python interpretation. Use {'key': 'value'} explicitly if you want literal keys", action = 'store_true')
            self.argParser.add_argument ('-k', '--kwargs', help = "enable keyword arguments by default. In general this is DISADVISED, use __pragma__ ('kwargs') and __pragma__('nokwargs') locally instead to prevent bloated code", action = 'store_true')
            self.argParser.add_argument ('-l', '--license', help = "show license", action = 'store_true')
            self.argParser.add_argument ('-n', '--nomin', help = "no minification", action = 'store_true')
            self.argParser.add_argument ('-o', '--opov', help = "enable operator overloading by default. In general this is DISADVISED, use __pragma__ ('opov') and __pragma__('noopov') locally instead to prevent slow code", action = 'store_true')
            self.argParser.add_argument ('-r', '--run', help = "run source file rather than compiling it", action = 'store_true')
            self.argParser.add_argument ('-v', '--verbose', help = "show all messages", action = 'store_true')

            self.__dict__.update (self.argParser.parse_args () .__dict__)

            if not (self.license or self.source):
                log (True,  self.argParser.format_usage () .capitalize ())
                sys.exit (1)

            global extraLines
            extraLines = [
                # Make identifier __pragma__ known to static checker
                # It was only known in JavaScript from __core__.mod.js, which the checker doesn't see
                # __pragma__ ('<all>') in JavaScript requires it to remain a function, as it was in the core
                # It can't be skipped, since it has to precede __pragma__ ('skip'), to make the checker accept that
                'def __pragma__ (): pass',

                # Make __include__ known to the static checker
                '__pragma__ (\'skip\')',
                '__new__ = __include__ = 0',
                '__pragma__ (\'noskip\')',
                ''
            ] if commandArgs.check else []
            global nrOfExtraLines
            nrOfExtraLines = max (len (extraLines) - 1, 0)  # Last line only serves to force linefeed
            extraLines = '\n'.join (extraLines)

If static checking is enabled, insert dummy definitions of global JavaScript variables between __pragma__ (‘skip’) and __pragma__ (‘noskip’) to prevent needless complaints of the checker. The static checks are geared towards avoiding false alarms, and mainly check undefined names and unused variables. Style checks are deliberately avoided.