i0C6e

~/sketchbook/7seg$ cat /usr/local/bin/unoup
#!/bin/bash

FIRMW=.pioenvs/uno/firmware.hex
avrdude -v -v -v -v -p atmega328p -c arduino -P /dev/ttyUSB0 \
        -b 115200 -D -U flash:w:$FIRMW:i

~/sketchbook/7seg$ cat src/main.cpp

/*
        -0-     ---     -0-     -0-     ---     -0-     -0-     -0-
      5   1   /   1   /   1   /   1   5   1   5   /   5   /   /   1
      ---     ---     -6-     -6-     -6-     -6-     -6-     ---
    4   2   /   2   4   /   /   2   /   2   /   2   4   2   /   2
    -3-     ---     -3-     -3-     ---     -3-     -3-     ---

    435-201 ----2-1 43-6-01 -3-6201 --562-1 -35620- 435620- ----201
  * ---6--- 4356-0- --5-2-- 4-5---- 43---0- 4-----1 ------1 4356---
    1000000 1111001 0100100 0110000 0011001 0010010 0000010 1111000
         C0      F9      A4      B0      99      92      82      F8

        -0-     -0-     -0-     ---     ---     ---     -0-     -0-
      5   1   5   1   5   1   5   /   /   /   /   1   5   /   5   /
      -6-     -6-     -6-     -6-     -6-     -6-     -6-     -6-
    4   2   /   2   4   2   4   2   4   /   4   2   4   /   4   /
    -3-     -3-     ---     -3-     -3-     -3-     -3-     ---

    4356201 -356201 4-56201 43562-- 43-6--- 43-62-1 4356-0- 4-56-0-
  * ------- 4------ -3----- -----01 --5-201 --5--0- ----2-1 -3--2-1
    0000000 0010000 0001000 0000011 0100111 0100001 0000110 0001110
         80      90      88      83      A7      A1      86      8E

        -0-     ---     -0-     -0-     ---     ---     ---     ---
      5   /   5   /   /   /   /   /   5   1   5   /   5   1   /   /
      ---     -6-     ---     ---     -6-     ---     ---     -6-
    4   2   4   2   4   /   /   2   4   2   4   /   4   2   4   2
    -3-     ---     -3-     -3-     ---     -3-     ---     ---

    435-20- 4-562-- 43----0 -3--2-0 4-562-1 435---- 4-5-2-1 4--62--
  * ---6--1 -3---01 --562-1 4-56--1 -3---0- ---6201 -3-6-0- -35--01
    1000010 0001011 1100110 1110010 0001001 1000111 1001001 0101011
         C2      8B      E6      F2      89      C7      C9      AB

        ---     -0-     -0-     ---     ---     ---     ---     ---
      /   /   5   1   5   1   /   /   5   /   5   /   5   1   /   /
      -6-     -6-     -6-     -6-     -6-     -6-     ---     ---
    4   2   4   /   /   2   4   /   /   2   4   /   4   2   4   2
    -3-     ---     ---     ---     -3-     -3-     -3-     -3-

    43-62-- 4-56-01 --56201 4--6--- -3562-- 4356--- 435-2-1 43--2--
  * --5--01 -3--2-- 43----- -35-201 4----01 ----201 ---6-0- --56-01
    0100011 0001100 0011000 0101111 0010011 0000111 1000001 1100011
         A3      8C      98      AF      93      87      C1      E3

        ---     ---     ---     -0-     ---     ---     ---     ---
      5   1   /   /   5   1   /   /   /   /   /   /   /   /   /   /
      -6-     ---     -6-     -6-     ---     ---     ---     ---
    4   2   4   2   /   2   /   /   /   /   /   /   /   /   /   /
    -3-     ---     -3-     -3-     ---     ---     ---     ---

    43562-1 4---2-- -3562-1 -3-6-0- 4356201 4356201 4356201 4356201
  * -----0- -356-01 4----0- 4-5-2-1 ------- ------- ------- -------
    0000001 1101011 0010001 0110110 0000000 0000000 0000000 0000000
         81      EB      91      B6      00      00      00      00
*/

#include <Arduino.h>

/* Define shift register pins used for seven segment display */

#define LATCH_DIO 4
#define CLK_DIO 7
#define DATA_DIO 8

/* Segment byte maps for numbers 0 to 9 */
const byte SEGMENT_MAP[] =
    {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
     0x80,0x90,0x88,0x83,0xA7,0xA1,0x86,0x8E,
     0xC2,0x8B,0xE6,0xF2,0x89,0xC7,0xC9,0xAB,
     0xA3,0x8C,0x98,0xAF,0x93,0x87,0xC1,0xE3,
     0x81,0xEB,0x91,0xB6};

/* Byte maps to select digit 1 to 4 */
const byte SEGMENT_SELECT[] = {0xF1,0xF2,0xF4,0xF8};

/* Write a decimal number between 0 and F to
   one of the 4 digits of the display */
void WriteNumberToSegment(byte Segment, byte Value) {
  digitalWrite(LATCH_DIO,LOW);
  shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_MAP[Value]);
  shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_SELECT[Segment] );
  digitalWrite(LATCH_DIO,HIGH);
}

void setup ()
{
  /* Set DIO pins to outputs */
  pinMode(LATCH_DIO,OUTPUT);
  pinMode(CLK_DIO,OUTPUT);
  pinMode(DATA_DIO,OUTPUT);
}

void loop() {
  /* Update the display with the current counter value */
  static int m = 0;
  static unsigned long time=millis();
  WriteNumberToSegment(0, m%36);
  WriteNumberToSegment(1, (m+1)%36);
  WriteNumberToSegment(2, (m+2)%36);
  WriteNumberToSegment(3, (m+3)%36);
  if (millis()-time>1000) {
    time=millis();
    if (m>=36) m = 1; else m++;
  }
}

~/sketchbook/7seg$ platformio run
~/sketchbook/7seg$ unoup

------------------------------------

check linux box

$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 003: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)
Bus 002 Device 002: ID 80ee:0021 VirtualBox USB Tablet
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

$ sudo cat /var/log/messages | grep 'USB ACM device'
Dec 12 06:59:34 RBOX kernel: [ 1375.024427] cdc_acm 2-2:1.0: ttyACM0: USB ACM device

$ cat ~/.profile | tail -n 4
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/.local/bin:$PATH"
fi

$ sudo apt-get install python-pip vim-tiny
$ sudo pip install -U platformio
$ sudo find / -name platformio
/usr/local/bin/platformio

$ platformio boards atmelavr 2>&1 | head -n 5 && platformio boards atmelavr | grep ^uno

Platform: atmelavr
----------------------------------------------------------------------
ID                MCU            Frequency  Flash   RAM    Name
----------------------------------------------------------------------
uno               ATMEGA328P     16Mhz     31kB    2kB    Arduino Uno

~/$ cd ~/sketchbook/
~/sketchbook$ mkdir blink
~/sketchbook$ cd blink
~/sketchbook/blink$ platformio init --board uno

~/sketchbook/blink$ cat src/main.cpp
#include <Arduino.h>

#define DLY 1000
#define LED 13

void setup() {
  pinMode(LED, OUTPUT);
}

void loop() {
  digitalWrite(LED, HIGH); delay(DLY);
  digitalWrite(LED, LOW); delay(DLY);
}

void loop() {
  digitalWrite(LED, HIGH); delay(DLY);
  digitalWrite(LED, LOW); delay(DLY);
}

# problems with '-v -v -v -v' voodoo {3}
~/sketchbook/blink$ platformio run --target upload

~/sketchbook/blink$ platformio run --target clean

Links:
------

  {1} Тулчейн разработки под Arduino для ценителей командной строки
      https://geektimes.ru/post/273852/
      http://docs.platformio.org/en/latest/installation.html
      http://docs.platformio.org/en/latest/quickstart.html
  {2} https://www.arduino.cc/en/Tutorial/ShiftOut
      https://www.arduino.cc/en/uploads/Tutorial/595datasheet.pdf
  {3} ..but there is some voodoo-talk in the answers
      https://stackoverflow.com/questions/19765037
          /arduino-sketch-upload-issue-avrdude-stk500-
          recv-programmer-is-not-respondi
  {4} http://hintshop.ludvig.co.nz/show
          /persistent-names-usb-serial-devices/

HBSiF

Problem with Flowgorithm 2.10 under Mono (Debian Stretch):

  1. Load sum.fprg
  2. Make minor changes
  3. Rotate wheel to scroll down: Aborted. You still have a chance to prevent exit by reading warning message:

  Discard changes? [OK] [Cancel] Certainly, choose "Cancel"

sum.fprg

  function main returns void
    int CNT
    CNT = 0
    int SUM
    SUM = 0
    int X
    do
      output "enter X:"
      input X
    while X > 10
    do
      CNT = CNT + 1
      SUM = SUM + CNT
    while CNT < X
    output "SUM = " & tostring(SUM)
  end

Connect to Raspberry Pi (Raspbian Stretch)
------------------------------------------

Limit logins to 2 (one for autologin, second for remote access via ssh)

  $ cat /etc/security/limits.conf | tail -n 3
  # End of file
  *               hard    maxlogins       2
  $ sudo

!!! do not run this as a root !!!

  $ tightvncserver :1 -geometry 1280x960 -depth 24 -dpi 96
  New 'X' desktop is raspberrypi:1
  Starting applications specified in /home/pi/.vnc/xstartup
  Log file is /home/pi/.vnc/raspberrypi:1.log
  $ service --status-all | grep vnc
  $ ps -a | grep vnc
   1176 pts/0    00:00:00 Xtightvnc

Note: tightvnc doesn't care about /etc/security/limits.conf

Flash Arduino from CLI (Putty -> Raspberry PI -> Arduino UNO)
-------------------------------------------------------------

flash.sh

  #!/bin/bash

  /usr/share/arduino/hardware/tools/avrdude \
  -C/usr/share/arduino/hardware/tools/avrdude.conf -v -v -v -v \
  -patmega328p -carduino -P/dev/ttyACM0 -b115200 -D \
  -Uflash:w:/home/pi/sketchbook/$1:i

[1] http://arduinolearning.com/code/multi-function-shield-examples.php
[2] http://www.cohesivecomputing.co.uk/hackatronics
         /arduino-multi-function-shield/

Arduino Multifunctional Shield Examples
---------------------------------------

Features

  4 digit 7-segment LED display module driven by two serial 74HC595’s
  4 red LED’s
  10K potentiometer
  3 x push buttons
  Piezo buzzer
  DS18B20 temperature sensor interface (not included)
  Infrared receiver interface
  Serial interface header for connection to serial modules

Board:      Arduino/Genuino Uno
Port:       /dev/ttyACM0
Programmer: AVRISP mkII

Flashing example (blink.ino):

  1. Build with arduino
     File -> Preferences -> show verbose output during
             [v] compilation [v] upload
     Sketch -> Verify/Compile
  2. > pscp Sweep.ino.hex pi@192.168.1.204:/home/pi/sketchbook/blink.hex
  3. $ flash blink.hex (must be in /home/pi/sketchbook/)

  $ cat flash.sh
  #!/bin/bash

  /usr/share/arduino/hardware/tools/avrdude \
  -C/usr/share/arduino/hardware/tools/avrdude.conf -v -v -v -v \
  -patmega328p -carduino -P/dev/ttyACM0 -b115200 -D \
  -Uflash:w:/home/pi/sketchbook/$1:i

Blinking LED
............

  #define DLY 1000
  #define LED 13

  void setup() {
    pinMode(LED, OUTPUT);
  }

  void loop() {
    digitalWrite(LED, HIGH); delay(DELAY);
    digitalWrite(LED, LOW); delay(DELAY);
  }

All LEDS blinking
.................

  #define DLY 600
  const byte LED[] = {13,12,11,10};
  byte ONOFF = 1;

  void setup() {
    for (int i=0; i<=3; i++)
      pinMode(LED[i], OUTPUT);
  }

  void loop() {
    for (int i=0; i<=3; i++)
      digitalWrite(LED[i], ONOFF);
    delay(DLY);
    ONOFF=ONOFF?0:1;
  }

Switches example
................

  const byte LED[] = {13,12,11,10};

  #define BUTTON1 A1
  #define BUTTON2 A2

  void setup() {
    for (int i=0; i<=3; i++)
      pinMode(LED[i], OUTPUT);
  }

  /* Write a decimal number between 0 and 9 to
     one of the 4 digits of the display */
  void WriteNumberToSegment(byte Segment, byte Value) {
    digitalWrite(LATCH_DIO,LOW);
    shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_MAP[Value]);
    shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_SELECT[Segment] );
    digitalWrite(LATCH_DIO,HIGH);
  }

  void loop() {
    if(!digitalRead(BUTTON1))
      for (int i=0; i<=3; i++)
        digitalWrite(LED[i], HIGH);

    if(!digitalRead(BUTTON2))
      for (int i=0; i<=3; i++)
        digitalWrite(LED[i], LOW);
  }

Potentiometer 1
...............

  #define Pot1 0

  void setup() {
    Serial.begin(9600);
  }

  void loop() {
    Serial.print("Potentiometer reading: ");
    Serial.println(analogRead(Pot1));
    /* Wait 0.5 seconds before reading again */
    delay(500);
  }

Pot and led
...........

  const byte LED[] = {13,12,11,10};
  #define Pot1 0

  void setup() {
    Serial.begin(9600);
    for (int i=0; i<=3; i++)
      pinMode(LED[i], OUTPUT);
  }

  void loop() {
    int PotValue;
    //Serial.print("Potentiometer reading: ");
    PotValue = analogRead(Pot1);
    for (int i=0; i<=3; i++)
      digitalWrite(LED[i], PotValue>100*i+100?LOW:HIGH);
    Serial.print("Potentiometer: ");
    Serial.println(PotValue);
    delay(500);
  }

segment display
...............

  /* Define shift register pins used for seven segment display */
  #define LATCH_DIO 4
  #define CLK_DIO 7
  #define DATA_DIO 8

  /* Segment byte maps for numbers 0 to 9 */
  const byte SEGMENT_MAP[] =
      {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
  /* Byte maps to select digit 1 to 4 */
  const byte SEGMENT_SELECT[] = {0xF1,0xF2,0xF4,0xF8};

  void setup ()
  {
    /* Set DIO pins to outputs */
    pinMode(LATCH_DIO,OUTPUT);
    pinMode(CLK_DIO,OUTPUT);
    pinMode(DATA_DIO,OUTPUT);
  }

  void loop() {
    /* Update the display with the current counter value */
    WriteNumberToSegment(0 , 0);
    WriteNumberToSegment(1 , 1);
    WriteNumberToSegment(2 , 2);
    WriteNumberToSegment(3 , 3);
  }

Read pot and display value on display
.....................................

  /* Define shift register pins used for seven segment display */
  #define LATCH_DIO 4
  #define CLK_DIO 7
  #define DATA_DIO 8

  #define Pot1 0

  /* Segment byte maps for numbers 0 to 9 */
  const byte SEGMENT_MAP[] =
      {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0X80,0X90};
  /* Byte maps to select digit 1 to 4 */
  const byte SEGMENT_SELECT[] = {0xF1,0xF2,0xF4,0xF8};

  void setup () {
    pinMode(LATCH_DIO,OUTPUT);
    pinMode(CLK_DIO,OUTPUT);
    pinMode(DATA_DIO,OUTPUT);
  }

  void loop() {
    int PotValue;
    PotValue = analogRead(Pot1);
    /* Update the display with the current counter value */
    WriteNumberToSegment(0 , PotValue / 1000);
    WriteNumberToSegment(1 , (PotValue / 100) % 10);
    WriteNumberToSegment(2 , (PotValue / 10) % 10);
    WriteNumberToSegment(3 , PotValue % 10);
  }

  /* Write a decimal number between 0 and 9 to one
     of the 4 digits of the display */
  void WriteNumberToSegment(byte Segment, byte Value)
  {
    digitalWrite(LATCH_DIO,LOW);
    shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_MAP[Value]);
    shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_SELECT[Segment] );
    digitalWrite(LATCH_DIO,HIGH);
  }

SSH
---

Lookup

  $ ip addr show | grep -A 1 enp0

Setup remote

  $ cat /etc/security/limits.conf | tail -n 3

  ##@student       -       maxlogins       4
  *                hard    maxlogins       2
  ## End of file

  $ cat /etc/ssh/sshd_config | grep 'Port '
  ##Port 22

Setup local

  $ cat /etc/hosts | head -n 3
  127.0.0.1       localhost
  127.0.1.1       RBOX
  192.168.1.192   blackboard

Use

  ssh -p 2222 virtu@blackboard
  ssh -p 2222 virtu@blackboard 'DISPLAY=:0.0 python3' < try.py
  scp -P 2222 virtu@blackboard:/home/virtu/remote.py .
  scp -P 2222 local.py virtu@blackboard:/home/virtu/

try.py

  #!/usr/bin/python
  import turtle
  turtle.width(5)
  for x in ['Blue','Aqua','Green','Yellow','Red','Purple']:
    turtle.color( x)
    turtle.right( 60)
    turtle.circle(100)

Raspberry Pi. Remote Control
----------------------------

Prepare

  $ mkdir other
  $ cd other
  $ vi other.c
  $ gcc other.c -o other
  $ sudo cp other /usr/local/bin

  cat /etc/security/limits.conf | tail -n 3
  *                hard    maxlogins       2

  $ who -a
  $ w       # w is not who

Use

  $ sudo echo blah > /dev/pts/1
  $ sudo other -n /dev/pts/1 echo "Hello!"
  $ sudo other -n /dev/pts/1 firefox &
  $ DISPLAY=:0.0 firefox &

Build SimulIDE
--------------

  svn checkout https://svn.code.sf.net/p/simulide/svnrepo/branches/simulide_0.1.5/
  cd simulide_0.1.5/build_L64
  apt-get install qt5-default
  qmake
  make  #(~5min)
  cd ~/si/simulide_0.1.5/build_L64/release/SimulIDE_0.1.5-Lin64/bin
  ./SimulIDE_0.1.5 &

Flashing Arduino
----------------

On Stretch VM:

>> Locate[1] the preferences.txt file that Arduino IDE reads to determine its settings. At the bottom of this file, add the following two lines:

  virtu@RBOX:~$ sudo find / -name preferences.txt
  cat /home/virtu/.arduino/preferences.txt
  ..
  build.verbose=true
  ..
  upload.verbose=true
  ..

  dmesg | grep ttyUSB*

  avrdude -v -p atmega328p -c arduino -P /dev/ttyUSB0 -b 57600 -D -U flash:w:blink.hex:i

Links

[1] https://www.openhub.net/p/simulide
[2] https://svn.code.sf.net/p/simulide/svnrepo/branches/simulide_0.1.5/
[3] https://stackoverflow.com/questions/24725051
          /execute-a-command-in-another-terminal-via-dev-pts

Going Python
------------

  https://pythonworld.ru/moduli/modul-random.html

Модуль random предоставляет функции для генерации случайных чисел, букв, случайного выбора элементов последовательности.

  random.seed([X], version=2)

инициализация генератора случайных чисел. Если X не указан, используется системное время.

Oneliners {2}
-------------

  >>> print [i for i in range(20) if i%2 == 0]
  >>> print [(i, f) for i in nums for f in fruit]

Example: 32 hours clock
-----------------------

  font=['0','1','2','3','4','5','6','7','8','9',
        'A','B','C','D','E','F','G','H','I','J',
        'K','L','M','N','O','P','Q','R','S','T',
        'U','V','W','X','Y','Z','a','b','c','d',
        'e','f','g','h','_']

  def t24to32( ah, am):
    return (font[(ah*60+am)//45], font[(ah*60+am)%45])

  for h in range(0, 24):
    for m in range(0, 60, 5):
      print() if m%30==0 else ...
      vh, vm = t24to32( h, m)
      print( '{0:02d}:{1:02d}->{2}  '.format(h,m,vh+vm), end='')

Links:

  {1} https://www.python-course.eu/python3_formatted_output.php
  {2} https://www.python.org/dev/peps/pep-0202/

Output:

>>> %Run 32.py

  00:00->00  00:05->05  00:10->0A  00:15->0F  00:20->0K  00:25->0P
  00:30->0U  00:35->0Z  00:40->0e  00:45->10  00:50->15  00:55->1A
  01:00->1F  01:05->1K  01:10->1P  01:15->1U  01:20->1Z  01:25->1e
  01:30->20  01:35->25  01:40->2A  01:45->2F  01:50->2K  01:55->2P
  02:00->2U  02:05->2Z  02:10->2e  02:15->30  02:20->35  02:25->3A
  02:30->3F  02:35->3K  02:40->3P  02:45->3U  02:50->3Z  02:55->3e
  03:00->40  03:05->45  03:10->4A  03:15->4F  03:20->4K  03:25->4P
  03:30->4U  03:35->4Z  03:40->4e  03:45->50  03:50->55  03:55->5A
  04:00->5F  04:05->5K  04:10->5P  04:15->5U  04:20->5Z  04:25->5e
  04:30->60  04:35->65  04:40->6A  04:45->6F  04:50->6K  04:55->6P
  05:00->6U  05:05->6Z  05:10->6e  05:15->70  05:20->75  05:25->7A
  05:30->7F  05:35->7K  05:40->7P  05:45->7U  05:50->7Z  05:55->7e
  06:00->80  06:05->85  06:10->8A  06:15->8F  06:20->8K  06:25->8P
  06:30->8U  06:35->8Z  06:40->8e  06:45->90  06:50->95  06:55->9A
  07:00->9F  07:05->9K  07:10->9P  07:15->9U  07:20->9Z  07:25->9e
  07:30->A0  07:35->A5  07:40->AA  07:45->AF  07:50->AK  07:55->AP
  08:00->AU  08:05->AZ  08:10->Ae  08:15->B0  08:20->B5  08:25->BA
  08:30->BF  08:35->BK  08:40->BP  08:45->BU  08:50->BZ  08:55->Be
  09:00->C0  09:05->C5  09:10->CA  09:15->CF  09:20->CK  09:25->CP
  09:30->CU  09:35->CZ  09:40->Ce  09:45->D0  09:50->D5  09:55->DA
  10:00->DF  10:05->DK  10:10->DP  10:15->DU  10:20->DZ  10:25->De
  10:30->E0  10:35->E5  10:40->EA  10:45->EF  10:50->EK  10:55->EP
  11:00->EU  11:05->EZ  11:10->Ee  11:15->F0  11:20->F5  11:25->FA
  11:30->FF  11:35->FK  11:40->FP  11:45->FU  11:50->FZ  11:55->Fe
  12:00->G0  12:05->G5  12:10->GA  12:15->GF  12:20->GK  12:25->GP
  12:30->GU  12:35->GZ  12:40->Ge  12:45->H0  12:50->H5  12:55->HA
  13:00->HF  13:05->HK  13:10->HP  13:15->HU  13:20->HZ  13:25->He
  13:30->I0  13:35->I5  13:40->IA  13:45->IF  13:50->IK  13:55->IP
  14:00->IU  14:05->IZ  14:10->Ie  14:15->J0  14:20->J5  14:25->JA
  14:30->JF  14:35->JK  14:40->JP  14:45->JU  14:50->JZ  14:55->Je
  15:00->K0  15:05->K5  15:10->KA  15:15->KF  15:20->KK  15:25->KP
  15:30->KU  15:35->KZ  15:40->Ke  15:45->L0  15:50->L5  15:55->LA
  16:00->LF  16:05->LK  16:10->LP  16:15->LU  16:20->LZ  16:25->Le
  16:30->M0  16:35->M5  16:40->MA  16:45->MF  16:50->MK  16:55->MP
  17:00->MU  17:05->MZ  17:10->Me  17:15->N0  17:20->N5  17:25->NA
  17:30->NF  17:35->NK  17:40->NP  17:45->NU  17:50->NZ  17:55->Ne
  18:00->O0  18:05->O5  18:10->OA  18:15->OF  18:20->OK  18:25->OP
  18:30->OU  18:35->OZ  18:40->Oe  18:45->P0  18:50->P5  18:55->PA
  19:00->PF  19:05->PK  19:10->PP  19:15->PU  19:20->PZ  19:25->Pe
  19:30->Q0  19:35->Q5  19:40->QA  19:45->QF  19:50->QK  19:55->QP
  20:00->QU  20:05->QZ  20:10->Qe  20:15->R0  20:20->R5  20:25->RA
  20:30->RF  20:35->RK  20:40->RP  20:45->RU  20:50->RZ  20:55->Re
  21:00->S0  21:05->S5  21:10->SA  21:15->SF  21:20->SK  21:25->SP
  21:30->SU  21:35->SZ  21:40->Se  21:45->T0  21:50->T5  21:55->TA
  22:00->TF  22:05->TK  22:10->TP  22:15->TU  22:20->TZ  22:25->Te
  22:30->U0  22:35->U5  22:40->UA  22:45->UF  22:50->UK  22:55->UP
  23:00->UU  23:05->UZ  23:10->Ue  23:15->V0  23:20->V5  23:25->VA
  23:30->VF  23:35->VK  23:40->VP  23:45->VU  23:50->VZ  23:55->Ve

Graphics
--------

  a. turtle graphics {1}
  b. adding graphics.py{2} to your project folder
  {1} https://opentechschool.github.io/python-beginners/en
            /simple_drawing.html
  {2} http://mcsp.wartburg.edu/zelle/python/
      http://mcsp.wartburg.edu/zelle/python/graphics/graphics/
      http://mcsp.wartburg.edu/zelle/python/graphics/graphics.pdf
      http://anh.cs.luc.edu/python/hands-on/3.1/examples.zip

Annex A. Simple drawing with turtle
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Introduction
............

“Turtle” is a python feature like a drawing board, which lets you command a turtle to draw all over it!

You can use functions like turtle.forward(...) and turtle.left(...) which can move the turtle around.

Before you can use turtle, you have to import it. We recommend playing around with it in the interactive interpreter first, as there is an extra bit of work required to make it work from files. Just go to your terminal and type:

  import turtle

Note

Do you work with Ubuntu and get the error message “No module named _tkinter”? Install the missing package with sudo apt-get install python3-tk

  turtle.forward(25)
  turtle.left(30)

The turtle.forward(...) function tells the turtle to move forward by the given distance. turtle.left(...) takes a number of DEGREES which you want to rotate to the left. There is also turtle.backward(...) and turtle.right(...), too.

Just learned

  turtle.forward(...)
  turtle.backward(...)
  turtle.left(...)
  turtle.right(...)

Note

Want to start fresh? You can type turtle.reset() to clear the drawing that your turtle has made so far. We’ll go into more detail on turtle.reset() in just a bit.

The standard turtle is just a triangle. That’s no fun! Let’s make it a turtle instead with the turtle.shape() command:

  turtle.shape("turtle")

If you put the commands into a file, you might have recognized that the turtle window vanishes after the turtle finished its movement. (That is because Python exits when your turtle has finished moving. Since the turtle window belongs to Python, it goes away as well.) To prevent that, just put

  turtle.exitonclick()

at the bottom of your file. Now the window stays open until you click on it:

  import turtle

  turtle.shape("turtle")
  turtle.forward(25)
  turtle.exitonclick()

Drawing a square
................

For a square you will probably need a right angle, which is 90 degrees.

  import turtle
  turtle.forward(50)
  turtle.left(90)
  turtle.forward(50)
  turtle.left(90)
  turtle.forward(50)
  turtle.left(90)
  turtle.forward(50)
  turtle.left(90)
  turtle.exitonclick()

If you want to get creative, you can modify your shape with the turtle.width(...) and turtle.color(...) functions. How do you use these functions? Before you can use a function you need to know its signature (for example what to put between the parentheses and what those things mean.) To find this out you can type help(turtle.color) into the Python shell. If there is a lot of text, Python will put the help text into a pager, which lets you page up and down. Press the q key to exit the pager.

If you want to set an RGB value, make sure to run turtle.colormode(255) first. Then for instance you could run turtle.color(215, 100, 170) to set a pink colour.

Just learned

  turtle.width(...)
  turtle.colormode(255)
  turtle.color(...)     # turtle.color("red")
                        # turtle.color(215, 100, 170)

Tip

In a new Python interactive shell you’ll need to import turtle before help(turtle.color) will work.

Tip

Undo the most recent step with turtle.undo().

Drawing a rectangle
...................

  import turtle
  turtle.forward(100)
  turtle.left(90)
  turtle.forward(50)
  turtle.left(90)
  turtle.forward(100)
  turtle.left(90)
  turtle.forward(50)
  turtle.left(90)
  turtle.exitonclick()

More squares
............

  import turtle

  turtle.left(20)

  turtle.forward(50)
  turtle.left(90)
  turtle.forward(50)
  turtle.left(90)
  turtle.forward(50)
  turtle.left(90)
  turtle.forward(50)
  turtle.left(90)

  turtle.left(30)

  turtle.forward(50)
  turtle.left(90)
  turtle.forward(50)
  turtle.left(90)
  turtle.forward(50)
  turtle.left(90)
  turtle.forward(50)
  turtle.left(90)

  turtle.left(40)

  turtle.forward(50)
  turtle.left(90)
  turtle.forward(50)
  turtle.left(90)
  turtle.forward(50)
  turtle.left(90)
  turtle.forward(50)
  turtle.left(90)

  turtle.exitonclick()

Overview of available Turtle and Screen methods
...............................................

  https://docs.python.org/3.3/library/turtle.html

Turtle methods. Turtle motion

    Move and draw
        forward() | fd()
        backward() | bk() | back()
        right() | rt()
        left() | lt()
        goto() | setpos() | setposition()
        setx()
        sety()
        setheading() | seth()
        home()
        circle()
        dot()
        stamp()
        clearstamp()
        clearstamps()
        undo()
        speed()
    Tell Turtle’s state
        position() | pos()
        towards()
        xcor()
        ycor()
        heading()
        distance()
    Setting and measurement
        degrees()
        radians()

Turtle methods. Pen control

    Drawing state
        pendown() | pd() | down()
        penup() | pu() | up()
        pensize() | width()
        pen()
        isdown()
    Color control
        color()
        pencolor()
        fillcolor()
    Filling
        filling()
        begin_fill()
        end_fill()
    More drawing control
        reset()
        clear()
        write()

Turtle methods. Turtle state

    Visibility
        showturtle() | st()
        hideturtle() | ht()
        isvisible()
    Appearance
        shape()
        resizemode()
        shapesize() | turtlesize()
        shearfactor()
        settiltangle()
        tiltangle()
        tilt()
        shapetransform()
        get_shapepoly()

Using events
    onclick()
    onrelease()
    ondrag()

Special Turtle methods
    begin_poly()
    end_poly()
    get_poly()
    clone()
    getturtle() | getpen()
    getscreen()
    setundobuffer()
    undobufferentries()

Methods of TurtleScreen/Screen

Window control
    bgcolor()
    bgpic()
    clear() | clearscreen()
    reset() | resetscreen()
    screensize()
    setworldcoordinates()
Animation control
    delay()
    tracer()
    update()
Using screen events
    listen()
    onkey() | onkeyrelease()
    onkeypress()
    onclick() | onscreenclick()
    ontimer()
    mainloop() | done()
Settings and special methods
    mode()
    colormode()
    getcanvas()
    getshapes()
    register_shape() | addshape()
    turtles()
    window_height()
    window_width()
Input methods
    textinput()
    numinput()
Methods specific to Screen
    bye()
    exitonclick()
    setup()
    title()

Example.

  # importing * into the current namespace is discouraged
  from math import *
  # Imports the turtle module into its own namespace.
  # This means that function names have to be prefixed with turtle.
  import turtle

  turtle.shape("turtle")
  turtle.speed(1)
  turtle.color("red")
  turtle.width(50)

  turtle.up()
  turtle.left(45); turtle.backward(200*sqrt(2)); turtle.right(45)
  # or just turtle.goto(-200,-200)
  turtle.down();

  turtle.forward(400)
  turtle.left(90)
  turtle.forward(400)
  turtle.left(90)
  turtle.forward(400)
  turtle.left(90)
  turtle.forward(400)
  turtle.left(90)

  turtle.exitonclick()

Annex B. Graphics Reference (graphics.py v5)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Contents
--------

    Overview
    GraphWin Objects
    Graphics Objects
        Point Methods
        Line Methods
        Circle Methods
        Rectangle Methods
        Oval Methods
        Polygon Methods
        Text Methods

    Entry Objects
    Displaying Images
    Generating Colors
    Controlling Display Updates (Advanced)
    About this document ...

Overview
--------

The package graphics.py is a simple object oriented graphics library designed to make it very easy for novice programmers to experiment with computer graphics in an object oriented fashion. It was written by John Zelle for use with the book ``Python Programming: An Introduction to Computer Science'' (Franklin, Beedle & Associates). The most recent version of the library can obtained at http://mcsp.wartburg.edu/zelle/python. This document is a reference to the functionality provided in the library. See the comments in the file for installation instructions.

There are two kinds of objects in the library. The GraphWin class implements a window where drawing can be done, and various graphics objects are provided that can be drawn into a GraphWin. As a simple example, here is a complete program to draw a circle of radius 10 centered in a 100x100 window:

  from graphics import *

  def main():
      win = GraphWin("My Circle", 100, 100)
      c = Circle(Point(50,50), 10)
      c.draw(win)
      win.getMouse() # pause for click in window
      win.close()

  main()

GraphWin objects support coordinate transformation through the setCoords method and input via mouse or keyboard. The library provides the following graphical objects: Point, Line, Circle, Oval, Rectangle, Polygon, Text, Entry (for text-based input), and Image. Various attributes of graphical objects can be set such as outline-color, fill-color, and line-width. Graphical objects also support moving and undrawing for animation effects.

GraphWin Objects
----------------

A GraphWin object represents a window on the screen where graphical images may be drawn. A program may define any number of GraphWins. A GraphWin understands the following methods:

GraphWin(title, width, height)
``````````````````````````````
Constructs a new graphics window for drawing on the screen. The parameters are optional; the default title is ``Graphics Window,'' and the default size is 200 x 200 pixels.

Example:

  win = GraphWin("Investment Growth", 640, 480)

plot(x, y, color)
`````````````````
Draws the pixel at $(x,y)$ in the window. Color is optional; black is the default.

Example:

  win.plot(35, 128, "blue")

plotPixel(x, y, color)
``````````````````````
Draws the pixel at the ``raw'' position $(x,y)$, ignoring any coordinate transformations set up by setCoords.

Example:

  win.plotPixel(35, 128, "blue")

setBackground(color)
````````````````````

Sets the window background to the given color. The default background color depends on your system. See Section 4.8.5 for information on specifying colors.

Example:

  win.setBackground("white")

close()
```````

Closes the on-screen window.

Example:

  win.close()

getMouse()
``````````
Pauses for the user to click a mouse in the window and returns where the mouse was clicked as a Point object.

Example:

  clickPoint = win.getMouse()

checkMouse()
````````````
Similar to getMouse, but does not pause for a user click. Returns the last point where the mouse was clicked or None if the window has not been clicked since the previous call to checkMouse or getMouse. This is particularly useful for controlling animation loops (see Chapter 8).

Example:

  clickPoint = win.checkMouse()

Note: clickPoint may be None.

getKey()
````````
Pauses for the user to type a key on the keyboard and returns a string representing the key that was pressed.

Example:

  keyString = win.getKey()

checkKey()
``````````
Similar to getKey, but does not pause for the user to press a key. Returns the last key that was pressed or "" if no key was pressed since the previous call to checkKey or getKey. This is particularly useful for controlling simple animation loops (see Chapter 8).

Example:

  keyString = win.checkKey()

Note: keyString may be the empty string ""

setCoords(xll, yll, xur, yur)
`````````````````````````````

Sets the coordinate system of the window. The lower-left corner is $(xll, yll)$ and the upper-right corner is $(xur, yur)$. Currently drawn objects are redrawn and subsequent drawing is done with respect to the new coordinate system (except for plotPixel).

Example:

  win.setCoords(0, 0, 200, 100)

Graphics Objects
----------------

The module provides the following classes of drawable objects: Point, Line, Circle, Oval, Rectangle, Polygon, and Text. All objects are initially created unfilled with a black outline. All graphics objects support the following generic set of methods:

setFill(color)
``````````````
Sets the interior of the object to the given color.

Example:

  someObject.setFill("red")

setOutline(color)
`````````````````

Sets the outline of the object to the given color.

Example:

  someObject.setOutline("yellow")

setWidth(pixels)
````````````````

Sets the width of the outline of the object to the desired number of pixels. (Does not work for Point.)

Example:

  someObject.setWidth(3)

draw(aGraphWin)
```````````````

Draws the object into the given GraphWin and returns the drawn object.

Example:

  someObject.draw(someGraphWin)

undraw()
````````

Undraws the object from a graphics window. If the object is not currently drawn, no action is taken.

Example:

  someObject.undraw()

move(dx,dy)
```````````
Moves the object dx units in the $x$ direction and dy units in the $y$ direction. If the object is currently drawn, the image is adjusted to the new position.

Example:

  someObject.move(10, 15.5)

clone()
```````
Returns a duplicate of the object. Clones are always created in an undrawn state. Other than that, they are identical to the cloned object.

Example:

  objectCopy = someObject.clone()

Subsections

  -- Point Methods
  -- Line Methods
  -- Circle Methods
  -- Rectangle Methods
  -- Oval Methods
  -- Polygon Methods
  -- Text Methods

Point Methods
.............

Point(x,y)
``````````
Constructs a point having the given coordinates.

Example:

  aPoint = Point(3.5, 8)

getX()
``````
Returns the $x$ coordinate of a point.

Example:

  xValue = aPoint.getX()

getY()
``````
Returns the $y$ coordinate of a point.

Example:

  yValue = aPoint.getY()

Line Methods
............

Line(point1, point2)
````````````````````
Constructs a line segment from point1 to point2.

Example:

  aLine = Line(Point(1,3), Point(7,4))

setArrow(endString)
```````````````````

Sets the arrowhead status of a line. Arrows may be drawn at either the first point, the last point, or both. Possible values of endString are "first", "last", "both", and "none". The default setting is "none".

Example:

  aLine.setArrow("both")

getCenter()
```````````
Returns a clone of the midpoint of the line segment.

Example:

  midPoint = aLine.getCenter()

getP1(), getP2()
````````````````
Returns a clone of the corresponding endpoint of the segment.

Example:

  startPoint = aLine.getP1()

Circle Methods
..............

Circle(centerPoint, radius)
```````````````````````````

Constructs a circle with the given center point and radius.

Example:

  aCircle = Circle(Point(3,4), 10.5)

getCenter()
```````````
Returns a clone of the center point of the circle.

Example:

  centerPoint = aCircle.getCenter()

getRadius()
```````````
Returns the radius of the circle.

Example:

  radius = aCircle.getRadius()

getP1(), getP2()
````````````````
Returns a clone of the corresponding corner of the circle's bounding box. These are opposite corner points of a square that circumscribes the circle.

Example:

  cornerPoint = aCircle.getP1()

Rectangle Methods
.................

Rectangle(point1, point2)
`````````````````````````
Constructs a rectangle having opposite corners at point1 and point2.

Example:

  aRectangle = Rectangle(Point(1,3), Point(4,7))

getCenter()
```````````
Returns a clone of the center point of the rectangle.

Example:

  centerPoint = aRectangle.getCenter()

getP1(), getP2()
````````````````
Returns a clone of the corresponding point used to construct the rectangle.

Example:

  cornerPoint = aRectangle.getP1()

Oval Methods
............

Oval(point1, point2)
````````````````````
Constructs an oval in the bounding box determined by point1 and point2.

Example:

  anOval = Oval(Point(1,2), Point(3,4))

getCenter()
```````````
Returns a clone of the point at the center of the oval.

Example:

  centerPoint = anOval.getCenter()

getP1(), getP2()
````````````````

Returns a clone of the corresponding point used to construct the oval.

Example:

  cornerPoint = anOval.getP1()

Polygon Methods
...............

Polygon(point1, point2, point3, ...)
````````````````````````````````````
Constructs a polygon with the given points as vertices. Also accepts a single parameter that is a list of the vertices.

Example 1:

  aPolygon = Polygon(Point(1,2), Point(3,4), Point(5,6))

Example 2:

  aPolygon = Polygon([Point(1,2), Point(3,4), Point(5,6)])

getPoints()
```````````
Returns a list containing clones of the points used to construct the polygon.

Example:

  pointList = aPolygon.getPoints()

Text Methods
............

Text(anchorPoint, textString)
`````````````````````````````
Constructs a text object that displays textString centered at anchorPoint. The text is displayed horizontally.

Example:

  message = Text(Point(3,4), "Hello!")

setText(string)
```````````````
Sets the text of the object to string.

Example:

  message.setText("Goodbye!")

getText()
`````````
Returns the current string.

Example:

  msgString = message.getText()

getAnchor()
```````````

Returns a clone of the anchor point.

Example:

  centerPoint = message.getAnchor()

setFace(family)
```````````````
Changes the font face to the given family. Possible values are "helvetica", "courier", "times roman", and "arial".

Example:

  message.setFace("arial")

setSize(point)
``````````````

Changes the font size to the given point size. Sizes from 5 to 36 points are legal.

Example:

  message.setSize(18)

setStyle(style)
```````````````

Changes font to the given style. Possible values are: "normal", "bold", "italic", and "bold italic".

Example:

  message.setStyle("bold")

setTextColor(color)
```````````````````
Sets the color of the text to color. Note: setFill has the same effect.

Example:

  message.setTextColor("pink")

Entry Objects
.............

Objects of type Entry are displayed as text entry boxes that can be edited by the user of the program. Entry objects support the generic graphics methods move(), draw(graphwin), undraw(), setFill(color), and clone(). The Entry specific methods are given below.

Entry(centerPoint, width)
`````````````````````````

Constructs an Entry having the given center point and width. The width is specified in number of characters of text that can be displayed.

Example:

  inputBox = Entry(Point(3,4), 5)

getAnchor()
```````````
Returns a clone of the point where the entry box is centered.

Example:

  centerPoint = inputBox.getAnchor()

getText()
`````````

Returns the string of text that is currently in the entry box.

Example:

  inputStr = inputBox.getText()

setText(string)
```````````````
Sets the text in the entry box to the given string.

Example:

  inputBox.setText("32.0")

setFace(family)
```````````````
Changes the font face to the given family. Possible values are "helvetica", "courier", "times roman", and "arial".

Example:

  inputBox.setFace("courier")

setSize(point)
``````````````
Changes the font size to the given point size. Sizes from 5 to 36 points are legal.

Example:

  inputBox.setSize(12)

setStyle(style)
```````````````
Changes font to the given style. Possible values are: "normal", "bold", "italic", and "bold italic".

Example:

  inputBox.setStyle("italic")

setTextColor(color)
```````````````````
Sets the color of the text to color.

Example:

  inputBox.setTextColor("green")

Displaying Images
.................

The graphics module also provides minimal support for displaying and manipulating images in a GraphWin. Most platforms will support at least PPM and GIF images. Display is done with an Image object. Images support the generic methods move(dx,dy), draw(graphwin), undraw(), and clone(). Image-specific methods are given below.

Image(anchorPoint, filename)
````````````````````````````
Constructs an image from contents of the given file, centered at the given anchor point. Can also be called with width and height parameters instead of filename. In this case, a blank (transparent) image is created of the given width and height (in pixels).

Example 1:

  flowerImage = Image(Point(100,100), "flower.gif")

Example 2:

  blankImage = Image(320, 240)

getAnchor()
```````````
Returns a clone of the point where the image is centered.

Example:

  centerPoint = flowerImage.getAnchor()

getWidth()
``````````

Returns the width of the image.

Example:

  widthInPixels = flowerImage.getWidth()

getHeight()

Returns the height of the image.

Example:

  heightInPixels = flowerImage.getHeight()

getPixel(x, y)
``````````````
Returns a list [red, green, blue] of the RGB values of the pixel at position (x,y). Each value is a number in the range 0-255 indicating the intensity of the corresponding RGB color. These numbers can be turned into a color string using the color_rgb function (see next section).

Note that pixel position is relative to the image itself, not the window where the image may be drawn. The upper-left corner of the image is always pixel (0,0).

Example:

  red, green, blue = flowerImage.getPixel(32,18)

setPixel(x, y, color)
`````````````````````
Sets the pixel at position (x,y) to the given color.

Note: This is a slow operation.

Example:

  flowerImage.setPixel(32, 18, "blue")

save(filename)
``````````````
Saves the image to a file. The type of the resulting file (e.g., GIF or PPM) is determined by the extension on the filename.

Example:

  flowerImage.save("mypic.ppm")

Generating Colors
.................

Colors are indicated by strings. Most normal colors such as "red", "purple", "green", "cyan", etc. should be available. Many colors come in various shades, such as "red1", "red2","red3", "red4", which are increasingly darker shades of red. For a full list, look up X11 color names on the web.

The graphics module also provides a function for mixing your own colors numerically. The function color_rgb(red, green, blue) will return a string representing a color that is a mixture of the intensities of red, green and blue specified. These should be ints in the range 0-255. Thus color_rgb(255, 0, 0) is a bright red, while color_rgb(130, 0, 130) is a medium magenta.

Example:

  aCircle.setFill(color_rgb(130, 0, 130))

Controlling Display Updates (Advanced)
......................................

Usually, the visual display of a GraphWin is updated whenever any graphics object's visible state is changed in some way. However, under some circumstances, for example when using the graphics library inside some interactive shells, it may be necessary to force the window to update in order for changes to be seen. The update() function is provided to do this.

update()
````````
Causes any pending graphics operations to be carried out and the results displayed.

For efficiency reasons, it is sometimes desirable to turn off the automatic updating of a window every time one of the objects changes. For example, in an animation, you might want to change the appearance of multiple objects before showing the next ``frame'' of the animation. The GraphWin constructor includes a special extra parameter called autoflush that controls this automatic updating. By default, autoflush is on when a window is created. To turn it off, the autoflush parameter should be set to False, like this:

  win = GraphWin("My Animation", 400, 400, autoflush=False)

Now changes to the objects in win will only be shown when the graphics system has some idle time or when the changes are forced by a call to update().

The update() method also takes an optional parameter that specifies the maximum rate (per second) at which updates can happen. This is useful for controlling the speed of animations in a hardware-independent fashion. For example, placing the command update(30) at the bottom of a loop ensures that the loop will \"spin" at most 30 times per second. The update command will insert an appropriate pause each time through to maintain a relatively constant rate. Of course, the rate throttling will only work when the body of the loop itself executes in less than 1/30th of a second.

Example: 1000 frames at 30 frames per second

  win = GraphWin("Update Example", 320, 200, autoflush=False)
  for i in range(1000):
      # <drawing commands for ith frame>
      update(30)

Annex E. Run process as other user
----------------------------------

  /*
     sudo ./other -n /dev/pts/1 whoami
     https://stackoverflow.com/questions/24725051
     /execute-a-command-in-another-terminal-via-dev-pts
   */
  #include <unistd.h>

  void print_help(char *prog_name) {
          printf("Usage: %s [-n] DEVNAME COMMAND\n", prog_name);
          printf("Usage: '-n' is an optional argument if you want "
                 "to push a new line at the end of the text\n");
          printf("Usage: Will require 'sudo' to run if the executable "
                 "is not setuid root\n");
          exit(1);
  }

  int main (int argc, char *argv[]) {
      char *cmd, *nl = "\n";
      int i, fd;
      int devno, commandno, newline;
      int mem_len;
      devno = 1; commandno = 2; newline = 0;
      if (argc < 3) {
          print_help(argv[0]);
      }
      if (argc > 3 && argv[1][0] == '-' && argv[1][1] == 'n') {
          devno = 2; commandno = 3; newline=1;
      } else if (argc > 3 && argv[1][0] == '-' && argv[1][1] != 'n') {
          printf("Invalid Option\n");
          print_help(argv[0]);
      }
      fd = open(argv[devno],O_RDWR);
      if(fd == -1) {
          perror("open DEVICE");
          exit(1);
      }
      mem_len = 0;
      for ( i = commandno; i < argc; i++ ) {
          mem_len += strlen(argv[i]) + 2;
          if ( i > commandno ) {
              cmd = (char *)realloc((void *)cmd, mem_len);
          } else { //i == commandno
              cmd = (char *)malloc(mem_len);
          }

          strcat(cmd, argv[i]);
          strcat(cmd, " ");
      }
    if (newline == 0)
          usleep(225000);
      for (i = 0; cmd[i]; i++)
          ioctl (fd, TIOCSTI, cmd+i);
      if (newline == 1)
          ioctl (fd, TIOCSTI, nl);
      close(fd);
      free((void *)cmd);
      exit (0);
  }

Annex F. Calendar
-----------------

  // https://www.codingunit.com/source-code/calendar.c
  // mod: day 0 month 0

  #include<stdio.h>

  #define TRUE    1
  #define FALSE   0

  int days_in_month[]={31,31,28,31,30,31,30,31,31,30,31,30,31};
  char *months[]={
    "\n\n\nDecember",
    "\n\n\nJanuary",
    "\n\n\nFebruary",
    "\n\n\nMarch",
    "\n\n\nApril",
    "\n\n\nMay",
    "\n\n\nJune",
    "\n\n\nJuly",
    "\n\n\nAugust",
    "\n\n\nSeptember",
    "\n\n\nOctober",
    "\n\n\nNovember",
    "\n\n\nDecember"
  };

  int inputyear(void) {
    int year;

    printf("Please enter a year (example: 2018) : ");
    scanf("%d", &year);
    return year;
  }

  int determinedaycode(int year)
  {
    int daycode;
    int d1, d2, d3;

    d1 = (year - 1.)/ 4.0;
    d2 = (year - 1.)/ 100.;
    d3 = (year - 1.)/ 400.;
    daycode = (year + d1 - d2 + d3 + 2) % 7;
    return daycode;
  }

  int determineleapyear(int year) {
    if(year% 4 == FALSE && year%100 != FALSE || year%400 == FALSE) {
      days_in_month[2] = 29;
      return TRUE;
    }
    else {
      days_in_month[2] = 28;
      return FALSE;
    }
  }

  void calendar(int year, int daycode) {
    int month, day;
    for ( month = 0; month <= 11; month++ ) {
      printf("%s", months[month]);
      printf("\n\nMon  Tue  Wed  Thu  Fri  Sat  Sun\n" );

      // Correct the position for the first date
      for ( day = 1; day <= 1 + daycode * 5; day++ ) printf(" ");

      // Print all the dates for one month
      for ( day = 1; day <= days_in_month[month]; day++ ) {
        printf("%2d", day-1 );
        // Is day before Sun? Else start next line Sun.
        if ( ( day + daycode ) % 7 > 0 ) printf("   " );
        else printf("\n " );
      }
        // Set position for next month
        daycode = ( daycode + days_in_month[month] ) % 7;
    }
  }

  int main(void) {
    int year, daycode, leapyear;

    year = inputyear();
    daycode = determinedaycode(year);
    determineleapyear(year);
    calendar(year, daycode);
    printf("\n");
  }

Output

  December

  Mon  Tue  Wed  Thu  Fri  Sat  Sun
                   0    1    2    3
    4    5    6    7    8    9   10
   11   12   13   14   15   16   17
   18   19   20   21   22   23   24
   25   26   27   28   29   30

  January

  Mon  Tue  Wed  Thu  Fri  Sat  Sun
                                  0
    1    2    3    4    5    6    7
    8    9   10   11   12   13   14
   15   16   17   18   19   20   21
   22   23   24   25   26   27   28
   29   30

  February

  Mon  Tue  Wed  Thu  Fri  Sat  Sun
              0    1    2    3    4
    5    6    7    8    9   10   11
   12   13   14   15   16   17   18
   19   20   21   22   23   24   25
   26   27

  March

  Mon  Tue  Wed  Thu  Fri  Sat  Sun
              0    1    2    3    4
    5    6    7    8    9   10   11
   12   13   14   15   16   17   18
   19   20   21   22   23   24   25
   26   27   28   29   30

  April

  Mon  Tue  Wed  Thu  Fri  Sat  Sun
                             0    1
    2    3    4    5    6    7    8
    9   10   11   12   13   14   15
   16   17   18   19   20   21   22
   23   24   25   26   27   28   29

  May

  Mon  Tue  Wed  Thu  Fri  Sat  Sun
    0    1    2    3    4    5    6
    7    8    9   10   11   12   13
   14   15   16   17   18   19   20
   21   22   23   24   25   26   27
   28   29   30

  June

  Mon  Tue  Wed  Thu  Fri  Sat  Sun
                   0    1    2    3
    4    5    6    7    8    9   10
   11   12   13   14   15   16   17
   18   19   20   21   22   23   24
   25   26   27   28   29

  July

  Mon  Tue  Wed  Thu  Fri  Sat  Sun
                             0    1
    2    3    4    5    6    7    8
    9   10   11   12   13   14   15
   16   17   18   19   20   21   22
   23   24   25   26   27   28   29
   30

  August

  Mon  Tue  Wed  Thu  Fri  Sat  Sun
         0    1    2    3    4    5
    6    7    8    9   10   11   12
   13   14   15   16   17   18   19
   20   21   22   23   24   25   26
   27   28   29   30

  September

  Mon  Tue  Wed  Thu  Fri  Sat  Sun
                        0    1    2
    3    4    5    6    7    8    9
   10   11   12   13   14   15   16
   17   18   19   20   21   22   23
   24   25   26   27   28   29

  October

  Mon  Tue  Wed  Thu  Fri  Sat  Sun
                                  0
    1    2    3    4    5    6    7
    8    9   10   11   12   13   14
   15   16   17   18   19   20   21
   22   23   24   25   26   27   28
   29   30

  November

  Mon  Tue  Wed  Thu  Fri  Sat  Sun
              0    1    2    3    4
    5    6    7    8    9   10   11
   12   13   14   15   16   17   18
   19   20   21   22   23   24   25
   26   27   28   29

Annex F. RPN calculator
-----------------------

  /* https://gist.github.com/jandk/1709771 */

  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <errno.h>

  typedef struct stack {
    int data;
    struct stack *next;
  } stack;

  void push( stack **head, int value ) {
    stack* node = malloc( sizeof(stack) );

    if( node == NULL ) {
      fputs( "Error: Out of memory\n", stderr );
      exit( 1 );
    } else {
      node->data = value;
      node->next = *head;
      *head = node;
    }
  }

  int pop( stack **head ) {
    if( *head == NULL ) {
      fputs( "Error: bottom of stack!\n", stderr );
      exit( 1 );
    } else {
      stack* top = *head;
      int value = top->data;
      *head = top->next;
      free( top );
      return value;
    }
  }

  int eval( char op, stack** head ) {
    int temp;
    switch( op ) {
      case '+': return pop(head) + pop(head);
      case '*': return pop(head) * pop(head);
      case '-': temp = pop(head); return pop(head) - temp;
      case '/': temp = pop(head); return pop(head) / temp;
    }
  }

  int need( char op ) {
    switch( op ) {
      case '+':
      case '*':
      case '-':
      case '/':
        return 2;
      default:
        fputs( "Invalid operand!", stderr );
        exit( 1 );
    }
  }

  int checknr( char* number ) {
    for( ; *number; number++ )
      if( *number < '0' || *number > '9' )
        return 0;

    return 1;
  }

  int main( int argc, char** argv ) {
    int i, temp, stacksize = 0;
    stack* head = NULL;

    if( argc == 1 ) {
      printf("Usage: %s <arg> [arg] ... \n", argv[0]);
      exit(1);
    }

    for( i = 1; i < argc; i++ ) {
      char* token = argv[i];
      char* endptr;
      char op;

      if( checknr( token ) ) {
        /* We have a valid number. */
        temp = atoi( token );
        push( &head, temp );
        ++stacksize;
      } else {
        /* We have an operand (hopefully) */
        if( strlen( token ) != 1 ) {
          fprintf( stderr, "Error: Token '%s' too large.\n", token );
          exit( 1 );
        }

        op = token[0];

        if( stacksize < need( op ) ) {
          fputs( "Too few arguments on stack.\n", stderr );
          exit( 1 );
        }

        push( &head, eval( op, &head ) );
        stacksize -= need( op ) - 1;
      }
    }

    if( stacksize != 1 ) {
      fputs( "Too many arguments on stack.\n", stderr );
      exit( 1 );
    }

    printf( "Result: %i\n", head->data );

    return 0;
  }

Annex G. strtok
---------------

  /* http://www.cyberforum.ru/cpp-beginners/thread98315.html */

  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>

  int main(void) {
    char str[] = "blah blah blah", **words = NULL, *p = NULL;
    int i, cnt = 0;

    for (p=strtok(str," "); p!=NULL; p=strtok(NULL," ")) {
      if ((words=(char**)realloc(words, sizeof(char*)*(cnt+1)))==NULL) {
        printf("No memory to new word!\n");
        exit(1);
      }
      if ( ( words[cnt] = strdup(p) ) == NULL ) {
        printf("Can't duplicate word!\n");
        exit(1);
      }
      ++cnt;
    }

    printf("Words count: %d\n", cnt);

    for ( i = 0; i < cnt; ++i )
      printf("%s\n", words[i]);

    for ( i = 0; i < cnt; ++i ) {
      if ( words[i] != NULL ) {
        free(words[i]);
        words[i] = NULL;
      }
    }
    free(words);
    words = NULL;

    exit(0);
  }
