Example of usage of an Erlang port
(April 2011)

Table of contents

Overview

Getting Started

Erlang port

Data

test_port.erl

test_port.py

Overview

This page gives an example, designed as follows:

design

The Erlang program (test_port.erl), that is in charge of the computing, sends data via a port to the Python program (test_port.py), that is in charge of the display.

The result is like this:
display

The dots are some moving bodies, and each dot is linked to the three nearest dots.

Getting Started

In order to run this example, you need at least:
Then run:
erlc +debug_info test_port.erl
erl -run test_port start

If you want to test only the Python part, you may download sample_data.log and run this:
cat sample_data.log | python test_port.py

# or if you want profiling:
cat sample_data.log | python -m cProfile test_port.py

# or if you want to debug
python -m pdb test_port.py -i sample_data.log

Erlang port

The Erlang port is technically achieved as follows:

Data

Data sent via the port to the Python displayer looks like this:
...
<0.39.0>: x=300.48, y=489.93, pid1=<0.36.0>, pid2=<0.37.0>, pid3=<0.35.0>
<0.45.0>: x=372.63, y=154.37, pid1=<0.38.0>, pid2=<0.46.0>, pid3=<0.34.0>
<0.49.0>: x=674.50, y=127.33, pid1=<0.53.0>, pid2=<0.56.0>, pid3=<0.41.0>
<0.61.0>: x=910.48, y=264.60, pid1=<0.62.0>, pid2=<0.57.0>, pid3=<0.53.0>
<0.54.0>: x=545.77, y=359.24, pid1=<0.47.0>, pid2=<0.55.0>, pid3=<0.50.0>
<0.40.0>: x=152.31, y=348.52, pid1=<0.35.0>, pid2=<0.36.0>, pid3=<0.37.0>
<0.52.0>: x=496.86, y=579.55, pid1=<0.48.0>, pid2=<0.44.0>, pid3=<0.55.0>
...

test_port.erl

The present example runs 32 moving bodies.
The bodies move around randomly, except that we try to keep them close to their original position.
Download test_port.erl

Excerpt of test_port.erl
Port = open_port({spawn, "python test_port.py"}, [stream]),
...
Data = io_lib:format("~p: x=~.2f, y=~.2f, pid1=~p, pid2=~p, pid3=~p\n", [ self(), X, Y, Pid1, Pid2, Pid3 ]),
port_command(Port, Data),

test_port.py

The present example uses Tkinter for the display.
Download test_port.py

Excerpt of test_port.py
line = sys.stdin.readline()
...
matchingObject = re.match("(.*): x=([0-9\.]*), y=([0-9\.]*), pid1=(.*), pid2=(.*), pid3=(.*)", line)
if matchingObject is not None:
    pid = matchingObject.group(1)
    x = matchingObject.group(2)
    y = matchingObject.group(3)
    pid1 = matchingObject.group(4)
    pid2 = matchingObject.group(5)
    pid3 = matchingObject.group(6)