# Welcome at MicroData!

This is the Handbook page of CEU MicroData. If you are here for the first time, welcome to the team! If you are revisiting something or upgrading this page it's at least as good!

The site consists of three main parts:

* **Onboarding** covers the basics to get you ready
* **Tools** includes materials that is useful in our day-to-day work
* **About us** tells you who we are and what we do

This is how this page works: We have lessons designed for you that are going to guide you through some of the most important tools, data and procedures we work with. It is designed to help you throughout your time here at the MicroData. Hopefully it contains information that you will often revisit and learn from. Nevertheless, it definitely doesn't replace learning from your peers. Whenever you run into any questions that a quick google search / Stack Overflow can't answer, make sure that you ask them on Slack. Even better: If you find out the answer you may want to add it here, so that others will find it more easily.

Enjoy both the lessons and your time at MicroData!

> ## License
>
> The content of this Handbook is provided under a Creative Commons Attribution-NonCommercial license (CC BY-NC 4.0). You are free to share and adapt this material under the restrictions described at <https://creativecommons.org/licenses/by-nc/4.0/>. Full license documentation is available [here](https://creativecommons.org/licenses/by-nc/4.0/legalcode).&#x20;


# Code of conduct

This page describes our policies on behavior and scientific integrity. Please read it carefully.

## Behavior

CEU MicroData is a workplace free of any sort of discrimination or harassment. Each member has to comply with the relevant University policies (see the [CEU Code of Ethics](https://documents.ceu.edu/documents/p-1009-1v2106) and the [CEU Policy on Harassment](https://documents.ceu.edu/documents/p-1402-1v2103)). To sum up, you must avoid uninvited or unwelcome physical, verbal or non-verbal conduct directed at an individual's or a group of individuals' supposed or actual nationality, race, ethnicity, language, age, sex, sexual orientation, gender identity and expression, religion, cultural identity, social origin, socioeconomic status, educational level, disability, genetic trait, mental or physical health condition, or any similar ground. We are committed to the principles of free inquiry and free expression, the pursuit of truth wherever it may lead, and to creating an environment that encourages the active exploration and exchange of ideas. We do not intend to impair this freedom. Prohibited harassment, however, is neither protected expression nor the proper exercise of academic freedom.

### Privacy

In general, you should comply with GDPR and the local privacy protection laws. You should ask for explicit consent of each affected person before taking any photos or recordings. You should  ask for explicit consent again in case you intend to share data of any kind on a person with anyone else in any way (e.g. posting to social media, sending it to a colleague or a friend etc.).&#x20;

## Confidentiality

As a rule of thumb consider any information, research data and material to be confidential unless it has already been made publicly available by MicroData. Any personal data or dataset containing personal information is strictly confidential and should be stored on encrypted medium. In case you intend to share any information or data with any person or organization outside MicroData make sure to obtain a written approval of a Principal Investigator first.

## Scientific Integrity

You must avoid any academic misconduct (see details in the Code of Ethics, but basically you should report your results honestly and make proper attributions to other people's research and ideas). You should make sure that any result you report can be reproduced. The best practice is to work in beads. Mistakes are a part of the research process. You will at some point likely make a mistake. The important part is to acknowledge it and to never try to hide it. The integrity of our science is our top priority. Reporting any mistake immediately helps us fixing it sooner and avoiding making similar mistakes in the future. &#x20;

## Reporting

If you notice or experience any violation of the basic rules outlined above, please notify Miklos immediately. If Miklos is the cause of your concern, please notify Adam. If you have any suggestions on how we should operate or further improve our culture you are always welcome to share it on the meetings or privately with any PI or Project Manager.


# Checklist

To-dos before starting the onboarding process

> ## Prerequisites
>
> Make sure that you have a signed contract. Even though some lessons are useful in general, it is best if you have full access to the microdata resources (e.g. server, slack, github, etc.) first. To gain access to every resource, you need a CEU-issued e-mail address, which you should receive shortly after signing your contract.

A project manager should go through the checklist below to make sure you have access to every resource.

* Add new member to the ceumicrodata Slack. You can follow [these steps.](https://slack.com/intl/en-hu/help/articles/201330256-Invite-new-members-to-your-workspace)
* Send invitation to GitHub team. This has to be done by a GitHub team owner. You can find the owners of the team [here.](https://github.com/orgs/ceumicrodata/people)
* Invite member to Project Management Trello board. Any member can do this. Follow [this guide.](https://help.trello.com/article/717-adding-people-to-a-board)
* Include them in the weekly meeting calendar event (if needed). Any member with access to the event can do this. If unsure, follow [these steps.](https://support.google.com/calendar/answer/37161)
* Add them to the Political Connections dropbox folder (if needed). Any member can do this. If you need help, [follow this guide.](https://help.dropbox.com/files-folders/share/share-with-others)
* Request a CEU-issued e-mail address. Ask a project administrator for help with this.
* Request CEU VPN access. Ask a project administrator for help with this.
* Once the VPN access is ready, request server access to haflinger. Write to the admin Slack channel with the VPN username and an e-mail address that the new member uses.
* Invite them to the microdata stackoverflow (requires CEU e-mail address). To invite, direct them to [this page.](https://stackoverflow.com/c/ceu-microdata) They can auto-join after registering with a CEU-issued e-mail address.


# Setup

This is a comprehensive list of what you are going to need throughout these lessons. To participate in the MicroData workflow, you will need access to the software described below. In addition, you will need an up-to-date web browser. The Carpemtries maintain a list of common issues that occur during installation as a reference for instructors that may be useful on the [Configuration Problems and Solutions wiki page](https://github.com/swcarpentry/workshop-template/wiki/Configuration-Problems-and-Solutions).We will go into details after a quick overview:

> ### Key requirements
>
> * Python 3 installation with pip3 and virtualenv
> * BEAD executable
> * Git installation, Git Bash on Windows

A useful script to install required programs on Linux can be found here: <https://github.com/ceumicrodata/handbook/blob/master/post_install.sh>. Let's go through them one by one.

## The Bash Shell

Bash is a commonly-used shell that gives you the power to do simple tasks more quickly.

{% tabs %}
{% tab title="Windows" %}
[Video Tutorial](https://www.youtube.com/watch?v=339AEqk9c-8)

1. Download the Git for Windows [installer](https://git-for-windows.github.io/).
2. Run the installer and follow the steps below:
   1. Click on "Next" four times (two times if you've previously installed Git). You don't need to change anything in the Information, location, components, and start menu screens.
   2. **Select "Use the nano editor by default" and click on "Next".**
   3. Keep "Git from the command line and also from 3rd-party software" selected and click on "Next". If you forgot to do this programs that you need for the workshop will not work properly. If this happens rerun the installer and select the appropriate option.
   4. Click on "Next".
   5. Select "Use the native Windows Secure Channel library", and click "Next".
   6. Keep "Checkout Windows-style, commit Unix-style line endings" selected and click on "Next".
   7. **Select "Use Windows' default console window" and click on "Next".**
   8. Leave all three items selected, and click on "Next".
   9. Do not select the experimental option. Click "Install".
   10. Click on "Finish".
3. If your "HOME" environment variable is not set (or you don't know what this is): 1. Open command prompt (Open Start Menu then type `cmd` and press \[Enter]) 2. Type the following line into the command prompt window exactly as shown:

   `setx HOME "%USERPROFILE%"`

   1. Press \[Enter], you should see `SUCCESS: Specified value was saved.`
   2. Quit command prompt by typing `exit` then pressing \[Enter]

This will provide you with both Git and Bash in the Git Bash program.
{% endtab %}

{% tab title="MacOS" %}
The default shell in all versions of macOS is Bash, so no need to install anything. You access Bash from the Terminal (found in `/Applications/Utilities`). See the Git installation [video tutorial](https://www.youtube.com/watch?v=9LQhwETCdwY) for an example on how to open the Terminal. You may want to keep Terminal in your dock.
{% endtab %}

{% tab title="Linux" %}
The default shell is usually Bash, but if your machine is set up differently you can run it by opening a terminal and typing `bash`. There is no need to install anything.
{% endtab %}
{% endtabs %}

## Git

Git is a version control system that lets you track who made changes to what when and has options for easily updating a shared or public version of your code on [github.com](https://github.com/). You will need a [supported web browser](https://help.github.com/articles/supported-browsers/).

You will need an account at [github.com](https://github.com/) for parts of the Git lesson. Basic GitHub accounts are free. We encourage you to create a GitHub account if you don't have one already. Please consider what personal information you'd like to reveal. For example, you may want to review these [instructions for keeping your email address private](https://help.github.com/articles/keeping-your-email-address-private/) provided at GitHub.

{% tabs %}
{% tab title="Windows" %}
Git should be installed on your computer as part of your Bash install (described above).
{% endtab %}

{% tab title="MacOS" %}
[Video Tutorial](https://www.youtube.com/watch?v=9LQhwETCdwY)

**For OS X 10.9 and higher**, install Git for Mac by downloading and running the most recent "mavericks" installer from [this list](http://sourceforge.net/projects/git-osx-installer/files/). Because this installer is not signed by the developer, you may have to right click (control click) on the .pkg file, click Open, and click Open on the pop up window. After installing Git, there will not be anything in your `/Applications` folder, as Git is a command line program. **For older versions of OS X (10.5-10.8)** use the most recent available installer labelled "snow-leopard" [available here](http://sourceforge.net/projects/git-osx-installer/files/).
{% endtab %}

{% tab title="Linux" %}
If Git is not already available on your machine you can try to install it via your distro's package manager. For Debian/Ubuntu run `sudo apt-get install git` and for Fedora run `sudo dnf install git`.
{% endtab %}
{% endtabs %}

After installation, the further steps are recommended:

* Configure installation   &#x20;
  * `git config --global user.name "your-full-name"`   &#x20;
  * `git config --global user.email "your-email-address"`    &#x20;
* SSH key: for faster usage (no password will be needed afterwards)   &#x20;
  * Check if you already have: Is it anything in .ssh? `ls .ssh`   &#x20;
    * if no, create a new one and [add to ssh agent](https://help.github.com/en/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)                            &#x20;
    * if yes, go to next step       &#x20;
  * [Add new SSH key](https://help.github.com/en/articles/adding-a-new-ssh-key-to-your-github-account) to your github account          &#x20;
* Download [Sublime Merge](https://www.sublimemerge.com/download) (recommended git client)

## Text Editor

When you're writing code, it's nice to have a text editor that is optimized for writing code, with features like automatic color-coding of key words. The default text editor on macOS and Linux is usually set to Vim, which is not famous for being intuitive. If you accidentally find yourself stuck in it, hit the `Esc` key, followed by `:`+`Q`+`!` (colon, lower-case 'q', exclamation mark), then hitting `Return` to return to the shell.

{% tabs %}
{% tab title="Windows" %}
nano is a basic editor and the default that we use, it is installed along with Git.

Other editors that you can use are [Notepad++](https://notepad-plus-plus.org/) or [Sublime Text](https://www.sublimetext.com/). **Be aware that you must add its installation directory to your system path.** Please ask your instructor to help you do this.
{% endtab %}

{% tab title="MacOS" %}
nano is a basic editor and the default that we use. See the Git installation [video tutorial](https://www.youtube.com/watch?v=9LQhwETCdwY) for an example on how to open nano. It should be pre-installed.

Other editors that you can use are [BBEdit](https://www.barebones.com/products/bbedit/) or [Sublime Text](https://www.sublimetext.com/).
{% endtab %}

{% tab title="Linux" %}
nano is a basic editor and the default that instructors use in the workshop. It should be pre-installed.

Other editors that you can use are [Gedit](https://wiki.gnome.org/Apps/Gedit), [Kate](https://kate-editor.org/) or [Sublime Text](https://www.sublimetext.com/).
{% endtab %}
{% endtabs %}

## Stata

In MicroData we use the statistical package [Stata](https://www.stata.com/products/)[™](https://korenmiklos.github.io/2020-08-23-eea/license.html), version Stata 17 MP. If you do not have a single user Stata license, please let your instructor know so that they can request one for you. We prefer to use the server version of the Stata. You can start Stata from VNC bash command line by the help of `xstata-mp` command.

If you are newly installing single user Stata on your computer, follow these instructions.

{% tabs %}
{% tab title="Windows" %}

1. Go to <https://download.stata.com/download/>
2. Log in using your username and password.
3. Download and launch the installer: SetupStata17.exe version 64.bit.
4. Once the installation is done, start Stata from the Start Menu. The first time you do this, you will have to activate your licence.
5. Choose version StataMP.
6. Enter the serial number provided and press enter.
7. Enter the code and press enter.
8. Enter the authorization and press enter.
9. It should return “Good. The serial number, code, and authorization make sense. Shall we continue?” Type Y and press enter.
10. When it asks for the first line, it should say “CEU”.
11. When it asks for the second line, it should say “CEU”.
12. It will ask for confirmation. Type “Y” and press enter.
    {% endtab %}

{% tab title="MacOS" %}

1. Go to <https://download.stata.com/download/>
2. Download and launch the installer: Stata17.dmg
3. Once the installation is done, start Stata from the Start Menu. The first time you do this, you will have to activate your licence.
4. Choose version StataMP.
5. Enter the serial number provided and press enter.
6. Enter the code and press enter.
7. Enter the authorization and press enter.
8. It should return “Good. The serial number, code, and authorization make sense. Shall we continue?” Type Y and press enter.
9. When it asks for the first line, it should say “CEU”.
10. When it asks for the second line, it should say “CEU”.
11. It will ask for confirmation. Type “Y” and press enter.
    {% endtab %}

{% tab title="Linux" %}

1. Go to <https://download.stata.com/download/>
2. Download Stata17Linux64.tar.gz.
3. Open a terminal and navigate to the directory where your downloaded file is located (e.g. cd \~/Downloads/)
4. Get superuser rights (sudo su)
5. Create a new directory (e.g. mkdir stata\_install)
6. Move the downloaded file to this new directory (mv Stata17Linux64.tar.gz. stata\_install/)
7. Enter the directory (cd stata\_install)
8. Extract the installation files using tar xzf Stata17Linux64.tar.gz
9. Create a directory for your stata installation (mkdir /usr/local/stata17)
10. Navigate to the stata directory (cd /usr/local/stata17)
11. Start the installation by executing the extracted install file (e.g. /home/username/Downloads/stata\_install/install)
12. Choose version StataMP.
13. Whenever the installer asks if you want to proceed type “y” and press enter
14. Once the installation is done, type ./stinit to activate your licence
15. Whenever it asks you if you want to continue, type “Y” and press enter
16. Enter the serial number provided and press enter
17. Enter the code and press enter
18. Enter the authorization and press enter
19. It should return “Good. The serial number, code, and authorization make sense. Shall we continue?” Type Y and press enter.
20. When it asks for the first line, it should say “CEU”
21. When it asks for the second line, it should say “CEU”
22. It will ask for confirmation. Type “Y” and press enter.
23. Try to start stata by ./xstata. If it gives you the following error message (./stata: error while loading shared libraries: libpng12.so.0: cannot open shared object file: No such file or directory), continue with the steps below:

`Issue the following commands one by one in your terminal window: apt-get install zlib1g-dev wget http://mirrors.kernel.org/ubuntu/pool/main/libp/libpng/libpng12-0_1.2.54-1ubuntu1_amd64.deb dpkg -i libpng12-0_1.2.54-1ubuntu1_amd64.deb`
{% endtab %}
{% endtabs %}

## Python 3

If you use Ubuntu 20.04 LTS or newer, you are good to go. Otherwise you should visit [Python's official page](https://www.python.org/downloads/) and download the latest python version for your operating system. Always follow the installation guide on Python's website.

## Bead

1. (windows only:) Install Git Bash
2. Install python if not already installed.

Latest release depends on Python 3.8.5., Python 3 only (requires at least 3.7). You can check the version of your Python from the terminal with `python -V`.

1. Download latest version from <https://github.com/e3krisztian/bead/releases/tag/v0.8.1>

   you will need only the platform specific binary: `bead`
2. Put the downloaded file in a location, that is on the PATH
   * `$HOME/bin`  (single-user, laptop, desktop, traditional location)
   * `$HOME/.local/bin` (single-user, laptop, desktop, new XDG standard?)
   * `/usr/local/bin` (system, servers, multi-user)
3. (linux and mac only): make the file executable

E.g. the following commands would install version v0.8.1 (latest release at the time of writing) on linux and mac:

```
# ensure user bin directory existst (for user specific scripts)
mkdir -p ~/.local/bin
# download bead
cd ~/.local/bin
curl -sLo bead https://github.com/e3krisztian/bead/releases/download/v0.8.1/bead
# make executable
chmod +x bead
```

At the end, you can check whether your installation was successful by typing `bead version` to the terminal, then it should show v0.8.1.

(source: <https://stackoverflow.com/c/ceu-microdata/questions/18>)

## Make

Linux and Mac users don't have to install it. Windows users should follow the next steps:

1. Install chocolatey

   We are going to install make through the package manager chocolatey, therefore first we have to install chocolatey. Follow the instructions on: [chocolatey website](https://chocolatey.org/install)

   * search for powershell in the windows start menu and run it as administrator
   * run the command in the field under the second point (install with powershell.exe)
2. Install gnu-make
   * type in the powershell `choco install make`.


# Using the terminal

> ### Overview
>
> Questions
>
> * How to navigate in the terminal?
> * How to execute commands and start applications?
> * What are some of the most important command line tools?
>
> Objectives
>
> * Understanding how the command line interface works.
> * Learn the most important command line operations.

## The Command Line Interface

You probably mostly use your computer via something called a GUI, or Graphical User Interface. Practically any modern operating system comes with a GUI. It is the GUI that, for example, allows you to instruct your computer to run applications by double clicking on an application's icon instead of issuing your commands in writing.

However, it is not the only way to use your computer. Before the quick rise in computing capacity and memory, graphical interfaces were impossible to develop. Originally computers are instructed via written commands in something called a CLI, or Command Line Interface. Practically anything that is feasible using a GUI can be done using the CLI, even though it might be much more difficult. Then why bother with using the CLI at all? - you might ask. There are two main reasons for familiarizing yourself with the CLI at MicroData:

1. The servers that we use have very limited graphical support, and you will mostly use an Ubuntu terminal when you work on the servers.
2. Most freshly developed tools for data analysis simply do not have a GUI. It takes a lot of resources to develop GUIs, and most open source developers focus their attention to the core performance of the tools instead of a GUI. If you want to use these, you have to familiarize yourself with the CLI of your computer.

### How are commands interpreted?

Every operating system comes with a command line interface. The CLI, just like the GUI is, however, different on each operating system. Most modern Windows operating systems use a CLI called Windows PowerShell, while Unix-like systems like MacOS, Ubuntu and other Linux distributions usually use a CLI called Terminal.

It is not only the name of the CLI that differs. The commands that you issue in the CLI have to be interpreted by the computer (translated to a long list of ones and zeros) in order to execute your commands. The way that commands are translated also differs across operating systems. Without going into too much details, it practically depends on something called the command line interpreter, which is a software that does this translation for you. On Windows, this is called cmd.exe, while on most Unix-like systems it's called Bash. The main problem with having mulitple CLIs and command line interpreters is that they understand different commands and translate these commands differently. Something that works on Ubuntu will very likely not work on Windows and vice-versa.

However, as mentioned before, the command line interpreter is just a software. Some of these interpreters have versions available for many different operating systems. The most widely used interpreter is probably Bash. If you are using MacOS or Ubuntu, you are good to go, you already have Bash installed on your computer. If you work with Windows, then you have already installed Git-bash, which, as it's name suggests, is a Bash interpreter. You will have to use this instead of the default Windows CLI throughout this episode.

### The Terminal

The CLI that we are going to use is called the Terminal (on Unix-like systems) or Git-bash (on Windows). From here on, they both will be referenced as the Terminal. If you open a Terminal window, you are supposed to see an almost-blank window with something like this written on it:

> `johndoe@haflinger:~$`

It should be followed by a blinking cursor. This is called the command prompt. It tells you some important information about where you are currently working. It is structured the following way:

> `username@machine:current_directory$`

These are possibly the most important pieces of information that you need to be aware of when using the CLI. What do they tell you?

1. username: This is your username on your computer. In most cases it will not change. In many systems you can switch to a user called root, that can do anything on the computer that a standard user cannot. You should only see your username there, if it changes you should close the Terminal and start a new session unless you are really sure about what you are doing.
2. machine: This is separated from the username by an `@` sign in most cases. It will change for example if you log in to the server. You will be able to control the MicroData servers using the Terminal as well. It is important to know whether you are controlling your own computer or the server in the Terminal window, always make sure that you are working on the proper machine.
3. current\_directory: This is usually separated from the name of the machine by a colon. In many operating systems you have something called your home folder or user folder. It is usually referenced in the Terminal by the `~` sign. If you change the working directory (which will be discussed in a second), it will change accordingly. For example on an other machine and in a different folder it might be something like this:

> `johndoe@johndoe-DELL:~/Documents/onboarding/_episodes`

In order to use your computer via the Terminal, you will have to type commands and press enter. They will be executed one-by-one. The rest of this episode will be about the most important commands in the Terminal.

## The most important Terminal commands

Terminal commands can be executed by pressing enter after typing them. The general structure of a command is the following: `command <positional arguments> <optional arguments>`. Some commands work by themselves, while others require arguments (for example if you want to change the working directory, you have to specify the new working directory). Positional arguments always have to be specified, while optional arguments are, as their name suggests, optional. You can almost always get a detailed explanation on the positional and optional arguments by opening up the manual of the command by executing `man <command>` or by calling the command with its help optional argument by `<command> --help` or `help <command>`

You can find the most commonly used commands with a short description below by categories. If you prefer, you can check out [this Carpentries page](https://datacarpentry.org/shell-economics/), which contains a more detailed walkthrough for each command.

### Navigation

* `pwd` returns the path to the current working directory. In most cases this is part of the command prompt, however, if you are deep down in the folder structure, the command prompt will only display a few parent directories.

{% tabs %}
{% tab title="Bash" %}

```bash
$ pwd
```

{% endtab %}

{% tab title="Output" %}

```bash
~/Documents/GitRepos/CEU_MD_Onboard/onboarding/
```

{% endtab %}
{% endtabs %}

Now, we are at the *\~/Documents/GitRepos/CEU\_MD\_Onboard/onboarding/* after typing the `pwd`. (Don't worry about the tilde ("\~") sign. You are going to learn about it in a minute.

* `cd` changes the working directory. It has a positional argument, which is the target directory. The target directory can be either given as an absolute path or a relative path.

  ```
  #absolute path
  $ cd /srv/sandbox/   

  #relative path
  $ cd ../../srv/sandbox/
  ```

  In relative paths you can reference the parent directory by two dots `..`, thus if you want to go to the parent directory, you should issue `cd ..`. Some more commonly used `cd` commands:

  ```
  #Going to your home directory
  $ cd  

  #going to the root folder
  $ cd /

  #going up to the parent directory
  $ cd ..

  #going to the Desktop directory in the home directory
  $ cd ~/Desktop
  ```

  The tilde ("\~") character in the last command is a shortcut for indicating the home directory.
* `start` will open a file in the default application associated with it on **Windows** (aka your default application on Windows).
* `open` will open a file in the default application associated with it on **MacOS** (aka your default application on MacOS).
* `xdg-open` will open a file in the default application associated with it on Ubuntu and many other **Linux** distributions (aka your default application on any Linux distros).

  The example is opening a picture in the default picture viewer.

  ```
  #On Windows
  $ start my-picture.png

  #On MacOS
  $ open my-picture.png

  #On (most) Linux distros
  $ xdg-open my-picture.png
  ```

### File System Exploration

* `ls` lists the content of the current working directory. It has a wide set of optional arguments that you can combine to get a listing you prefer. A few of these are:

  * `-l` will give you the list of files with one file in one line, and it will include additional information on file permissions, file owners, file size and modification date.
  * `-a` will list all files and folders including hidden ones.
  * `-S` will sort the files by size in descending order before listing them.
  * `-t` will sort the files by modification time (newest first) before listing them.
  * `-r` will revert the order of files before listing them.
  * `-h` will display the file sizes in a human-readable format.
  * You can combine these options, so for example `ls -ltrha` will list all files, including hidden ones, in a list where one file will be one line, and the oldest file will be the first (notice the revert option, that is why it's not the newest) and file sizes will be human-readable.

  ```
  $ ls -ltrha
  ```
* `less` will show you the content of a text file. It has one positional argument, the text file. It's worth noting that it can be any text file, for example `.py` python codes can be viewed as well as `.csv` data files.

  ```
  $ less trial.py
  ```

  You can scroll up and down using the arrows on your keyboard and exit by pressing `q`.

  FIXME: Adding a table of useful `less` associated keyboard combos
* `file` will determine file type. In fact, one of the common ideas in Unix-like operating systems such as Linux is that “everything is a file.”

{% tabs %}
{% tab title="Bash" %}

```bash
$ file picture.jpg
```

{% endtab %}

{% tab title="Output" %}

```
picture.jpg: JPEG image data, JFIF standard 1.01
```

{% endtab %}
{% endtabs %}

### Files and Directories Manipulation

* `cp` copies a file. It has two positional arguments, the source file and the target file.

  ```
  #Copy a file to the parent folder
  $ cp my-file.txt ../my-file.txt

  #Copy a folder to the parent folder by using -R recursive option
  $ cp -R my-folder/ ../
  ```
* `mv` moves a file or folder. It has two positional arguments, the source and the target path.

  ```
  #Move a file to the parent directory
  $ mv my-file.txt ../

  #Move the directory "my-folder" and its content to the parent directory
  $ mv my-folder ../
  ```

  It is also the way to rename files.

  ```
  #"old-filename.txt" will be renamed to "new-filename.txt"
  $ mv old-filename.txt new-filename.txt
  ```
* `mkdir` creates a new folder in the current working directory. It has a single positional argument, which is the name of the new folder.

  ```
  $ mkdir my-new-folder
  ```

  It can also have multiple optional arguments if you wish to create multiple folders.

  ```
  $ mkdir dir1 dir2 dir3
  ```

  It is even possible to create nested folder structures by providing the `-p` argument.

  ```
  $ mkdir -p dir4/dir5/dir6
  ```
* `rmdir` removes an empty directory. It's only positional argument is the folder to be removed. It only removes empty folders, you need to delete it's content first.
* `rm` removes a file. It has a positional argument, which is a list of files to be removed. You can give multiple files separated by spaces to remove.

  ```
  #Remove a single file
  $ rm my-text.txt

  #Remove multiple files
  $ rm my-text.txt my-data.dta
  ```

  **IMPORTANT**: If you remove a file by `rm` it will be **permanently** deleted, be careful with it!
* Recursive `rm` removes a directory with all of its subdirectories and files. It can be accessed with the `-r` optional argument.

  ```
  $ rm my_folder/ -r
  ```

  **IMPORTANT**: Recursive `rm` will remove the directory with all of it's content **permanently**.
* Recursive forced `rm` removes a directory with all of its subfolders and files even if the files are read-only. It can be executed using the `rf` optional argument.

  ```
  $ rm my_folder/ -rf
  ```

  **IMPORTANT**: deletion is **permanent**. You should not use it in general, it is only a last resort. The presence of read-only files strongly suggests that they should not be deleted using `rm`, but in some other ways (e.g. `bead nuke` in case of beads). There are some cases when this is useful, but use it with care and only if it is unavoidable.
* Some useful shortcuts which could be used with the some of the above-mentioned commands:

  * `?` , a question mark can be used to indicate "any single character".
  * `*`, an asterisk can be used to indicate "zero or more characters".

  ```
  #Instead of using
  $ cat test_1.txt test_2.txt test_3.txt

  #Better usage is
  $ cat test_?.txt

  #An even shorter solution is
  $ cat test_*
  ```

  You are going to learn about `cat` command in the next section.

### Redirection and some other useful commands

* `cat` will print the content of files on your terminal screen. It's positional argument is a file list separated by spaces.

  ```
  $ cat my-code.py
  ```

If you specify multiple files, it will con`cat`enate (its name comes from here), meaning that linking together and output each of them, one after the other, as a single block of text as it could be seen at the end of the **Files and Directories Manipulation** section.

* `head` and `tail` shows you the first and last few lines of a text file, respectively. It has one positional argument, the text file.

  ```
  $ head my-data.csv
  $ tail my-data.csv
  ```
* `echo` will print the value of its argument on your terminal screen.

{% tabs %}
{% tab title="Bash" %}

```bash
$ echo hello world!
```

{% endtab %}

{% tab title="Output" %}

```
hello world!
```

{% endtab %}
{% endtabs %}

* Some, other useful commands and shortcuts:

  * `>` redirection operator will redirect standard output to another file instead of the screen. However, using this will *ALWAYS* overwrite the content of that file
  * `>>` redirection operator will do the same as `>` does, **BUT** it will **not** overwrite the output file. Instead, it will append the content of that file.
  * `|` pipeline operator connects the ouput of one command with the input of a second command.
  * `sort` will sort lines of text.
  * `uniq` will report or omit repeated lines.
  * `wc` will print newline, word, and byte counts for each file. `wc -l` only counts the number of the lines.
  * `cut` will print selected parts of lines from each file to standard output.
  * `history` will display previous commands typed in the command line.
  * `nano` will open the Nano text editor.
  * `grep` will print lines matching a pattern.

  For more information, please consult the **Chapter 6 - Redirection** in "The Linux Command Line" book.

### File Permissions

For concise description, please visit the *File Permissions* section of the following link: <https://datacarpentry.org/shell-economics/03-working-with-files/index.html>

## Useful resources for learning Terminal:

* Introdutction to the Command Line for Economics: <https://datacarpentry.org/shell-economics>
* The Unix Shell: <https://swcarpentry.github.io/shell-novice/>
* Official Ubuntu tutorial: <https://ubuntu.com/tutorials/command-line-for-beginners#1-overview>
* The Linux Command Line by William Shotts: <http://linuxcommand.org/tlcl.php> (freely available)

> ### Key Points
>
> * The computer can be controlled using a GUI or a CLI.
> * Anything that you can do using the GUI can be done using a CLI.
> * In the CLI, you have to issue commands with possibly some positional and optional arguments.


# Git and GitHub

A quick introduction

> ### Overview
>
> Questions
>
> * What are the basic terms used by version control systems?
> * Which files are contained within the .git directory?
> * How to install git?
> * How does the basic collaborative workflow look like?
> * What are some of the most important git commands?
>
> Objectives
>
> * Understand the basic terminology of Git and Github
> * Install and setup git
> * Understand the collaborative workflow and commit message etiquette
> * List some of the most useful commands that can be easily accessed in your everyday work

## Version Control Basics

There are various Version Control Systems such as:

* [Git](https://git-scm.com/)
* [Subversion](https://subversion.apache.org/)
* [Mercurial](https://www.mercurial-scm.org/)

A version control system can be either:

* centralized - all users connect to a central, master repository
* distributed - each user has the entire repository on their computer

### Terminology

#### Version Control System / Source Code Manager

A version control system (or source code manager) is a tool that manages different versions of source code. It helps to create snapshots ("commits") of project files, thereby, supporting the tractability of a project.

#### Repository / repo

A repository is a directory which the version control system tracks and should contain all the files of your project. Besides your project files, a repository contains (hidden) files that git uses for configuration purposes. Git, by default, tracks all your files in a repository. If there are files you do not wish to track, you can include them in the manually created .gitignore file.

Repositories can be located either on a local computer or on the servers of an online version control platform (such as Github).

#### Staging Area / Staging Index / Index

Before committing changes to your project code, the files you want to snapshot need to be added to the Staging Index. Changes to these files can be captured in a commit.

#### Commit

A commit is a snapshot of the files that are added to the Staging Index. Creating a commit can help you to save a particular version of your project. When committing changes, you should also include a commit message that explains the changes of the project files since the previous commit. Therefore, commits track the evolution of your project and allows you to see the changes from one commit to another. It is also useful when experimenting with new code, as git makes it possible to jump back to a previous commit in case your code changes do not work out as planned.

#### SHA

A SHA("Secure Hash Algorithm") is an identification number for each commit. It is a 40-character string composed of characters (0–9 and a–f) such as `e2adf8ae3e2e4ed40add75cc44cf9d0a869afeb6`.

#### Branch

A branch is a line of development that diverges from the main line of development. It further allows you to experiment with the code without modifying the line of development in the master branch. When the project development in a branch turns out successful, it can be merged back to the master branch.

#### Checkout

Checkout allows you to point your working directory to a different commit. Therefore, you can jump to a particular SHA or to a different branch.

#### .Git Directory Contents

The .git directory contains:

* config file - it stores the configuration settings
* description file - file used by the GitWeb program
* hooks directory -  client-side or server-side scripts can be placed here to hook into Git's lifecycle events
* info directory - contains the global excludes file
* objects directory - stores all the commits
* refs directory - holds pointers to commits (e.g "branch" and "tag")&#x20;

### Git workflow

#### Making changes

* `git status`, `git init` (store all changes you commit in this folder), `git add` (except `.gitignore`)
* `git commit` often, to avoid conflict
  * commit message should be: If applied, this commit will “your message” (eg. `git commit -m "change label names"` or "update README").  &#x20;
  * commit message could also refer to Issues (eg. “close #3”) (issues are like to-do-s)
* `git log`: view the history of commits you’ve made

![](/files/-MT0S8XcSBmVm9M4gg_y)

#### Collaborate with others

In practice, it is good to be sure that you have an updated version of the repository you are collaborating on, so **you should git pull before making your changes**. The basic collaborative workflow would be:

* update your local repo with `git pull origin master`,
* make your changes and stage them with `git add`,
* commit your changes with `git commit -m`, and
* upload the changes to GitHub with `git push origin master`

It is better to **make many commits with smaller changes** rather than of one commit with massive changes: small commits are easier to read and review.

* fork: copy to origin / clone: copy remote repo to create local repo / pull: copies changes from a remote repository to a local repository. &#x20;
* .gitignore (eg. large files OR on Mac hidden .DS\_Store files OR data in ss-descriptives)

![](/files/-MT0S8Xd0hnmvLkHFk9j)

#### Branching, conflicts

Note, if someone pushes a commit to GitHub before you push your changes, you’ll need to integrate those into your code (and test them!) before pushing up to GitHub.

* `git diff` displays differences between commits.
* `git checkout` recovers old versions of files / `git revert` backs out commit

  Branching
* `git branch` creates a new branch
* `git checkout` switches to a different branch

  Merging
* `git merge` merges other\_branch into the current branch

**Conflicts occur when two or more people change the same file(s) at the same time.** The version control system does not allow people to overwrite each other’s changes blindly, but highlights conflicts so that they can be resolved.

* **Push**: You will not be able to push to GitHub if merging your commits into GitHub’s repo would cause a merge conflict. Git will instead report an error, telling you that you need to pull changes first and make sure that your version is “up to date”. Up to date in this case means that you have downloaded and merged all the commits on your local machine, so there is no chance of divergent changes causing a merge conflict when you merge by pushing.
* **Pull**: Whenever you pull changes from GitHub, there may be a merge conflict! These are resolved in the exact same way as when merging local branches: that is, you need to edit the files to resolve the conflict, then add and commit the updated versions.

![](/files/-MT0S8XeHrcN56DSbLW1)

### Git LFS

GitHub recommends repositories remain small, ideally less than 1 GB, and less than 5 GB is strongly recommended. Smaller repositories are faster to clone and easier to work with and maintain. Individual files in a repository are strictly limited to a 100 MB maximum size limit, and git gives a warning for updating files larger than 50 MB. Git Large File Storage (LFS) is a useful Git extension if someone has to version large files—even those as large as a couple GB in size—with Git. It replaces large files such as audio samples, videos, datasets, and graphics with text pointers inside Git, while storing the file contents on a remote server like GitHub.com or GitHub Enterprise. You can download the extension here: <https://git-lfs.github.com/>. Furhter informations about installation for Mac/Windows/Linux can be found here: <https://docs.github.com/en/github/managing-large-files/installing-git-large-file-storage>.

&#x20;To decide whether you need Git LFS or not, you can type in the command line: `find . -type f -size +1M`, it finds files greater than 1 MB in the given folder. Large files make fetching and pulling quite slow, so it is recommended to `git lfs install` in the repo with files larger than 1-10 MB size (depending on the project) and then `git lfs track` the given large files. For power users: `find . -size +1M | xargs -d '\n' git lfs track \"{}\"` finds and then tracks all files greater than 1 MB in a  given repository. LFS tracking modifies the .gitattributes file, so do not forget to commit that as well.

### Useful commands

| Code                                                  | Short description                                                                           |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| `git init`                                            | Initialize local git repository                                                             |
| `git status`                                          | Check the status of git repository (e.g. the branch, files to commit)                       |
| `git add`                                             | Add files to staging index                                                                  |
| `git add .`                                           | Add all modified files to staging index                                                     |
| `git commit -m"Text"`                                 | Commit changes with commit message                                                          |
| `git log`                                             | Check git commits specifying SHA, author, date and commit message                           |
| `git log --oneline`                                   | Check git commits specifying short SHA and commit message                                   |
| `git log --stat`                                      | Check git commits with additional information on the files changed and insertions/deletions |
| `git log -p`                                          | Shows detailed information on lines inserted/ deleted in commits                            |
| `git log -p --stat`                                   | Combines information from previous two commands                                             |
| `git log -p -w`                                       | Shows detailed information on commits ignoring whitespace changes                           |
| `git show`                                            | Show only last commit                                                                       |
| `git show <options> <object>`                         | View expanded details on git objects                                                        |
| `git diff`                                            | See the changes that haven’t been committed yet                                             |
| `git diff <SHA> <SHA>`                                | Shows changes between commits                                                               |
| `git tag`                                             | Show existing tags                                                                          |
| `git tag -a "tagname"`                                | Tag current commit                                                                          |
| `git tag -d "tagname`                                 | Delete tag                                                                                  |
| `git tag -a "tagname" "SHA pattern"`                  | Tag commit with given SHA pattern                                                           |
| `git branch "name_of_branch" "SHA pattern(optional)"` | Create new branch – at SHA pattern                                                          |
| `git branch “name_of_branch” master`                  | Start new branch at the latest commit of master branch                                      |
| `git checkout “name_of_branch”`                       | Move pointer to the latest commit of the specified branch                                   |
| `git branch -d “name_of_branch`                       | Delete branch, use -D to force deletion                                                     |
| `git checkout -b “name_of_branch”`                    | Create branch and checkout in one command                                                   |
| `git log --oneline --graph --all`                     | Show branches in a tree                                                                     |
| `git merge “name_of_branch_to_merge_in”`              | Merge in current branch to another                                                          |

## Useful resources for mastering git and github:

* Technical foundations of informatics book: <https://info201.github.io/git-basics.html>
* Software carpentry course (Strongly recommended): <https://swcarpentry.github.io/git-novice/>
* Github Learning Lab: <https://lab.github.com/>
* If you are really committed (pun intended): <https://git-scm.com/book/en/v2>
* Getting started with Github: <https://help.github.com/en/github/getting-started-with-github>
* Git cheatsheet: <https://education.github.com/git-cheat-sheet-education.pdf>
* Learn git with bicbucket cloud: <https://www.atlassian.com/git/tutorials/learn-git-with-bitbucket-cloud>

## Useful GUI tools for version control:

* Sublime Merge: <https://www.sublimemerge.com>
* Version Control in VS Code: <https://code.visualstudio.com/docs/editor/versioncontrol>


# Server

How to use the haflinger server

> #### Overview
>
> Questions
>
> * How to connect to haflinger server?
> * What is the structure of the server?
> * What is the general workflow on the server?
>
> Objectives
>
> * Learn how to set up connection with the server
> * Understand the basic specifications of our server
> * Study commands that are useful when working on the server

## The server and some basic information

Microdata currently uses one server.

* haflinger: haflinger.ceu.hu - function: STATA/Matlab/Python with graphical interface

The haflinger server has 504GB memory and 112 cores.

## Connecting to the server from different local operating systems

First, you have to be connected to the CEU network through VPN. You can use the AnyConnect client or the openconnect package depending on your OS. For more information on VPN usage please visit <https://ceuedu.sharepoint.com/sites/itservices/SitePages/vpn.aspx>

You can access the shell (command line) on haflinger.ceu.hu by using a Secure Shell (ssh) client, such as Putty (<http://docs.microdata.io/putty>). On UNIX-like systems the built-in ssh package allows you to connect without any additional software. This is where you can change your password, or where you can start batch jobs from the shell.

You can connect to the graphical interface (windows-like) on haflinger.ceu.hu via a VNC client. On UNIX-like systems using X-server (e.g. Ubuntu) you can simply allow X11 forwarding in an ssh connection by using the `-X` optional argument and don't need a VNC client.

### Linux

You can connect to the server from a Terminal window using the following command (substitute your username and port number appropriately):

```
  $ ssh USER@haflinger.ceu.hu -p PORT -X
```

### MacOS

You can connect to the server from a Terminal window using the following command (substitute your username and port number appropriately)

```bash
  $ ssh USER@haflinger.ceu.hu -p PORT
```

For a graphical server connection a useful tool is XQuartz. Using XQuartz you can enable X11 forwarding. In an XQuartz terminal you can connect to the graphical server by issuing the following command: (substitute your username and port number appropriately)

```bash
  $ ssh USER@haflinger.ceu.hu -p PORT -y
```

### Windows

PuTTy provides a CLI for the server.

#### VNC

On Windows you can download a simple REAL VNC viewer from: [vncviewer](https://cp.webgalaxy.hu/haflinger/vncviewer.exe) After installation you have to use the following server address along with your server password: `haflinger.ceu.hu:VNCPORT`

A good example how you can start the viewer from the cmd. You have to change the "%vnc\_port%" part to your own port number.

```bash
  $ vncviewer.exe -SecurityNotificationTimeout=0 -WarnUnencrypted=0 -Quality=High -Scaling=100%x100% haflinger.ceu.hu:%vnc_port%
```

#### Xserver and git-bash

You can also connect to the X server from git-bash terminal by the help of [vcxsrv](https://sourceforge.net/projects/vcxsrv/files/).\
\
Install the application then open`Xlaunch`and use the default settings: Multiple window, start no client, clipboard. Just click next as long as an X appears on the tray. X server has started.

Open git-bash and type `cd $HOME` You are now in your Windows home folder. Just check it with `pwd`Create a new file called .bash\_profile: `nano .bash_profile` Into the profile file save the following options: `export DISPLAY=localhost:0.0`Save the file and restart git-bash.

Connect to your remote server using the following command:

```
$ ssh USER@haflinger.ceu.hu -p PORT -Y -v
```

The option`-v` is used to diagnose the X connection problems. You can leave later if everything works well.

Log in with your own haflinger password then e.g. type `xstata-mp`. The Stata comes up in a new window. Be careful this is not a VNC session, if you close the Stata window you close the session.

#### Ms Visual Studio Code

You can download the Visual studio code from here: [visual](https://code.visualstudio.com/download)

After the installation you need to install these extensions:

"Remote-SSH", "Remote-SSH: Editing Configuration Files", "Jupyter Keymap", "Julia", "StataRun"

Recommended extensions: Makey, Python, GitHub Copilot (shareware)

You have to set up two configurations files:

Open VS Code and press the “Ctrl + Shift + P” shortcut to access the Command Palette. Choose Preferences: Remote-SSH: Open SSH Configuration File. Then choose your user config file like: Users/yourusername/.ssh/config on your local computer.

Copy these settings into the config file:

```
Host haflinger.ceu.edu
  HostName haflinger.ceu.edu
  User yourusername
  Port 2222
```

The second is the setting.json file:

Open VS Code and press the “Ctrl + Shift + P” shortcut to access the Command Palette. Type “Settings.json” in the search bar and select the specific settings.json file you want to edit.

Choose Preferences: Open User Settings (JSON) and copy these settings into the .json file:

```
{
    "remote.SSH.serverInstallPath": {
        "haflinger.ceu.edu": "/srv/sandbox/yourusername"
    },
    "remote.SSH.remotePlatform": {
        "haflinger.ceu.edu": "linux"
    },
    "editor.codeActionsOnSave": {}
}
```

Open VS Code and press the “Ctrl + Shift + P” shortcut to access the Command Palette. Choose Remote-SSH: Add New SSH Host.

Your new host will be: `ssh yourusername@haflinger.ceu.edu`

You have to install all locally installed extensions when you are connected to the server.

### Private and public keys for easier connection

For easier server access you can create private/public key pairs as follows:

1. Start the key generation program by typing `ssh-keygen` on your local computer
2. Enter the path to the file where it is going to be located. Make sure you locate it in your `.ssh` folder and name it as `microdata_kulcs` (or any alternative filename).
3. Enter a Passphrase or just simply press Enter. The public and private keys are created automatically. The public key ends with the string `.pub`.
4. Copy the public key to the `$HOME/USER/.ssh` folder on the server. (substitute your username appropriately)
5. An alternative solution for point 4 is using the following code: `ssh-copy-id -i ~/.ssh/microdata_kulcs USER@haflinger.ceu.hu -p PORT`. (a useful [source](https://www.ssh.com/ssh/keygen/) for the whole process)

Finally, you can alias the command that connects you to server:

#### MacOS

Copy the following text into the `config` file which is located in your .ssh folder: (substitute your usernames and port number appropriately)

```bash
Host haflinger
        HostName haflinger.ceu.hu
        User USER
        Port PORT
        IdentityFile /Users/LOCAL_USER/.ssh/microdata_kulcs
```

This allows you to connect to the haflinger server by typing the `ssh haflinger` command.

#### Linux

Add the following lines to your `.bashrc` file located in your home folder (by typing `nano .bashrc`):

```bash
alias haflinger='ssh USER@haflinger.ceu.hu -p PORT -X'
```

This allows you to connect to the haflinger server by typing the `haflinger` command.

#### Windows

Open git-bash and type`cd $HOME`. Create a new folder called .ssh:`mkdir .ssh` and cd into the .ssh folder. From the folder run `ssh-keygen.exe` Now you can follow the "For easier server access you can create private/public key pairs steps" second and third point.

If you don't have the .ssh folder at`$HOME/USER` at the server you have to create it there also. Login from git-bash. The logout command is `exit.` Use it now!

When you generated the public and private keys called `microdata_kulcs`push it to the server from your local machine .ssh folder.

`user@DESKTOP: ssh-copy-id -i microdata_kulcs -p PORT USER@haflinger.ceu.hu`

If you done it well a file called authorized\_keys created in the `/home/USER/.ssh/authorized_keys`

Connect back to the server and change the folder permissions:

`user@haflinger: chmod 700 ~/.ssh`

`user@haflinger: chmod 600 ~/.ssh/authorized_keys`

Exit from the server.

Open the .bash\_profile with nano and put an alias into the profile file:

`alias haflinger='ssh -p PORT -Y -v USER@haflinger.ceu.hu'`

Now your bash\_profile consists two line the the export display and the alias.

The final step is to add the ssh agent to the profile file. The agent handles the private and public keys.

The final .bash\_profile looks like this:

```bash
export DISPLAY=localhost:0.0

alias haflinger='ssh -p PORT -Y -v USER@haflinger.ceu.hu'

if [ -z "$SSH_AUTH_SOCK" ] ; then 
  eval ssh-agent -s 
  ssh-add ~/.ssh/microdata_kulcs 
fi
```

Start the Xlaunch. Restart the git-bash and type `haflinger` If everything worked well you are now on the haflinger X server.

## Structure of the server and general workflow

When connecting to the server, you are directed to your home folder \`/home/USER\_NAME'. Only you have access to your home folder. This folder should only be used to store configuration files (like ssh keys, etc.).

For any project work you should be working in your sandbox located at `/srv/sandbox/USER_NAME`. Working in your sandbox allows others to check your work and develop projects collaboratively. Folders with limited access for certain projects are located in `/srv/project`. In case you need a separate project folder with access limitation you should contact a project manager.

When saving your bead, a copy of your work is created in .zip format in one of the beadboxes. The beadboxes are located at `/srv/bead-box/`. For more information on the use of bead, please visit the corresponding episode on this website.

### Creating alias to your sandbox

You can create aliases that simplifiy your access to you sandbox and other directories. For that, you need to add the following commands to your `.bashrc` file: (substitute your username appropriately)

```
alias sandbox='cd /srv/sandbox/USER_NAME'
```

The `.bashrc` is located in your home folder (`home/USER`).

Then, you can access your sandbox by typing `sandbox` to the command line.

You can create similar aliases for other frequently used locations similarly.

## Useful server tools

### File transfer to the server

To move data between your computer and the server, you need an SFTP or SCP client. You have access to your home folder, and you may access shared data and project folders. You can choose from a wide variety of SFTP clients. A few of these are the following:

* Filezilla - <https://filezilla-project.org/>
* On Windows you can use WinScp - <https://winscp.net/eng/index.php>

To access the files on the server, provide the following sftp address to your client along with your username, password, and appropriate port number:

`sftp://haflinger.ceu.hu`

It is worth noting that on Ubuntu systems you don't need any additional client for file transfer. Just open a file navigator, go to Other locations, and connect to the server by issuing it's sftp address - e.g. `sftp://USER@haflinger.ceu.hu:PORT`. You will automatically be prompted for your username and password, and you can navigate on the server just like on your own computer.

### Screen

Working in screen allows users to exit the server without terminating the running processes. Processes started in a screen will also continue running in case of a connection issue. Therefore, you should always work in screen when running complex programs that run for longer time. For instructions on how to open and close a screen window, see the 'Useful server commands' section below.

### Virtual environment

When your code requires specific python packages, you should download them to a virtual environment. The Python environment on the server incorporates only the most basic Python packages so it is always recommended to work in a virtual environment. For instructions on how to create and activate a virtual environment, see the 'Useful server commands' section below.

If your program runs from a `main.sh` file, you can easily automate the creation of the virtual environment by inserting the following script to your code. Substitute the name of the virtual environment and local package folder (if applicable) appropriately.

```
virtualenv 'NAME_OF_THE_ENV'
. 'NAME_OF_THE_ENV'/bin/activate
pip install -r requirements.txt
pip install -f 'LOCAL_PACKAGE_FOLDER'/ -r requirements-local.txt

YOUR_CODE

deactivate
```

To create a virtualenv and use it permanently, one can use [mkvirtualenv](https://virtualenvwrapper.readthedocs.io/en/latest/):

```
$ mkvirtualenv pandas
(pandas) $ pip install pandas
(pandas) $ python
(pandas) $ deactivate
$ echo "I am no longer in a virtualenv."
$ workon pandas
(pandas) $ pip install jupyter
```

### Parallelization

Parallelization refers to the spreading the code processing work across multiple cores (CPUs). Parallelization is useful to fasten the running time of codes by optimizing the available resources.

For a short introduction on parallelization in Python, please visit the following website: <https://sebastianraschka.com/Articles/2014_multiprocessing.html>

### STATA

You can access the STATA program with graphical user interface on the haflinger. You can start Stata from VNC bash command line by the help of `xstata-mp` command.

### Python

The servers run both python2 and python3. You can access them by typing `python2` for python2 (current version 2.7.18) and `python` for python3 (current version 3.8.5). To leave the python shell and return to the system shell, type the python command `exit()`.

## Useful server commands:

| Code                                                     | Short description                                                                                                  |
| -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `htop`                                                   | Check servers usage, CPU and memory (see also `top`)                                                               |
| `screen`                                                 | Create screen running in the background. Ctrl-A-D to close the screen, Ctrl-D to shut down (terminate) the screen. |
| `screen -r "number_of_screen`                            | Open previously created screen                                                                                     |
| `virtualenv “name_of_virtualenv” -p python`              | Create a Python3 virtual environment                                                                               |
| `virtualenv “name_of_virtualenv” -p python2`             | Create a Python2 virtual environment                                                                               |
| `. [‘name_of_virtualenv’]/bin/activate`                  | Activate virtual environment                                                                                       |
| `pip3 install -r requirements.txt`                       | Install requirements for virtual environment listed in requirements.txt                                            |
| `pip3 install -r requirements_packages.txt -f packages/` | Install every requirement that are contained in a folder (as files)                                                |
| `pip freeze`                                             | Show downloaded python libraries                                                                                   |
| `pip freeze -> requirements.txt`                         | Export the currently downloaded python packages to a text file                                                     |
| `exit`                                                   | Terminate connection with the server                                                                               |

## Debugging

In case you cannot create new virtualenvs or there is any other issue that might be related to reaching your home folder quota, here is how you can debug it:

1. Check if it is really a quota problem. Type

   ```
   du -sh ./
   ```

   If it gives you anything close to 500M, you are proably dealing with a quota issue.
2. Clean up your home folder. In case you have any work in your home folder (you shouldn't!) move it somewhere else. Close any running screens and applications then delete all files in your cache: `find ~/.cache/ -type f -delete`
3. Check if the quota problem persists. If yes, let me know. If not, you need to take one last step so that it doesn't fill up again.
4. Set your cache folder to your sandbox. Add the following to your `~/.bashrc` file (switch user with your username):

   ```
   export STATATMP
   export TMPDIR='/srv/sandbox/user/'
   export XDG_CACHE_HOME='/srv/sandbox/user'
   export PIP_REQUIRE_VIRTUALENV=true
   ```
5. If you use other shells (e.g. fish) you need to configure them as well. Fish users need to add the following to `~/.config/fish/config.fish` (if the file does not exist, you need to create it, switch user with your username):

```
set -x STATATMP "/srv/sandbox/user"
set -x TMPDIR '/srv/sandbox/user'
set -x XDG_CACHE_HOME '/srv/sandbox/user'
set -x PIP_REQUIRE_VIRTUALENV true
```

For any other shell consult it's documentation on setting environment variables.

### Vncrestart

When using VNC, you might experience bad behavior after a while (windows cannot be resized or the appications freeze etc). For the resolution of the above problem, you can use the `vncrestart` command from SSH or VNC terminal which will reset your VNC within 60 seconds.

Important: Please keep in mind that resetting VNC will close all your opened applications and delete all your unsaved data.

## Contacts

* If you have technical difficulties with the server, please contact a Project Manager.
* For VPN-related problems, please contact CEU HelpDesk at <helprequest@ceu.hu>.
* If you have a problem with a specific application (e.g., Stata, Matlab), a Project Manager can help you decide whether the problem is with the operating system or with the application. In the latter case, he can put you in touch with Stata or Matlab support.


# Bead

Changing your data and code together

> ### Overview
>
> Questions
>
> * How do you ensure that your data products are reproducible?
>
> Objectives
>
> * 'Use `bead`, a command-line tool to create, update and share data products.'

## The problem

Researchers and analysts need to know the provenance of their data to trust its integrity and to quickly redo the analysis when requirements change. However, in a diverse and agile team, knowledge about data is often tacit, and is destroyed when a team member leaves. This leads to a duplication of effort. Additionally, the multitude of software tools and work methods create frictions in the analytics process. Existing solutions are either too rigid to be widely adopted or involve too much face-to-face communication, reducing researcher and analyst productivity.

`bead` is a lightweight software tool with which a researcher can explicitly declare dependency on other data products, referring to them with a universally unique identifier. She can see how her work fits in the bigger picture and who to work with when redoing the analysis. Bead encapsulates data, the software script that created it and references to its dependencies in a single package, making knowledge about the data explicit. Bead is platform independent and agnostic to the specific software tools and workflows used to create data. It can be adapted to any workflow that uses the file system for both scripts and data. Sample use cases include social and business datasets of a few GB each, processed and analyzed with perl, Python, R, Stata, Matlab, julia or other scripts.

## Basic logic of `bead`

Given a discrete computation of the form

```
output = function(*inputs)
```

a BEAD captures all three named parts:

* `output` - *data files* (results of the computation)
* `function` - *source code files*, that when run hopefully compute `output` from `inputs`
* `inputs` - are other bead' `output` and thus stored as *references to* those *beads*

As a special case pure data can be thought of as *constant computation* having only output but neither inputs nor source code.

### Bead concepts

Data packages can be in one of two states. Under active development in a **workspace**, or packaged and stored as a **bead**. Beads are stored in a **box**, which is just a collection of completed beads.

#### Workspace

A *workspace* is a directory, where the user works. It contains a prototype of a *bead* - it is a computation under active development. At some time however it is supposed to have all the inputs, code and output of a computation.

The directory has special structure and content, so it must be created via the `bead` tool:

* there are metadata in a hidden .bead-meta directory which .txt file enumerate all the inputs and the bead unique hash id.
* there are 3 standard directories with special meanings:
  * `input`: where input data is read from. It is read only, managed by the `bead` tool.
  * `temp`: temporary outputs, this is an area that is ignored when saving the bead.
  * `output`: This is where results of the computation are stored.

### Bead

A *bead* is a frozen, discrete computation, created from a *workspace*. It is currently a zip file.

A bead is intended to capture data with the code that produced it. The goal is transparency and semi-automatic reproducability through extra tooling. Full automatic reproducability is assumed to be inpractical/expensive, however it can be achieved by gradual process/quality improvements (learning through feedback).

The bead format is designed to be

* resilient to change
* decentralized
* keep enough information to be able to get both the details and the big picture (if all relevant beads are available)

The main technology involved is a combination of different probabilistic identifiers (UUID, secure hash, Merkle-tree).

Main properties of a bead:

* `kind` that is shared with other versions of a bead (book analogy: ISSN)
  * it is a technical name, whose existence allows the human name to

    change/evolve/diverge over time, while still referring to conceptually

    the same computation
* `content_id`, that is unique for every bead (\~version, book analogy: ISBN)
  * it is calculated, so changes in a bead makes it either invalid or a new version
* freeze time (for ordering versions, this is fragile in theory as depends on correctly set clocks, but in practice it is expected to cause few problems)
* freeze name
* references to its inputs (`kind`, `content_id`)

The main changes from v. 0.0.2. to 0.8.1 that beads are referenced by names from here on.

It is important to mention that we should not create a new bead with a name already in use.

### Box

A *box* is where beads are saved to and loaded from. It also gives names to beads and provide minimal search functionality. Currently, boxes are implemented a flat directories on the file system.

## Basic workflow

![](/files/-MTBhSWrd0JEC31dzyvz)

### Bead help

The bead help guide you through the usage of the bead.

$ bead -h

```
usage: bead [-h] {new,develop,save,status,nuke,web,zap,xmeta,version,input,box}

positional arguments:
  {new,develop,save,status,nuke,web,zap,xmeta,version,input,box}
    new                 Create and initialize new workspace directory with a new bead.
    develop             Create workspace from specified bead.
    save                Save workspace in a box.
    status              Show workspace information.
    nuke                No operation, you probably want zap, to delete the workspace.
    web                 Manage/visualize the big picture - connections between beads.
    zap                 Delete workspace.
    xmeta               eXport eXtended meta attributes to a file next to zip archive.
    version             Show program version.
    input               Manage data loaded from other beads...
    box                 Manage bead boxes...

optional arguments:
  -h, --help            show this help message and exit
```

All the positional arguments have own subcommands with complete help.

$ bead new -h

```
usage: bead new [-h] DIRECTORY

Create and initialize new workspace directory with a new bead.

positional arguments:
  DIRECTORY   bead and directory to create

optional arguments:
  -h, --help  show this help message and exit
```

### Create a new bead

Initial setup. The `latest` bead-box already made on the haflinger.

```bash
$ mkdir /somepath/bead-box/latest
$ bead box add latest /somepath/bead-box/latest
Will remember box latest
```

This is where completed beads will be stored. Create an empty bead with name `name`:

```bash
/somepath$ bead new name
Created name
```

Add some data to the output of this new bead which we can use later. This bead has no computation, only data.

```bash
/somepath$ cd name/
/somepath/name$ echo World > output/who-do-i-greet
```

```bash
/somepath/name$ bead save latest
Successfully stored bead.
```

```bash
cd ..
/somepath/$ bead zap name
Deleted workspace /somepath/name
```

### Working with inputs in a new bead

Create a new data package:

```bash
/somepath$ bead new hello
Created hello
```

```bash
/somepath$ cd hello/
```

Add data from an existing bead at `input/<input-name>/`:

```bash
/somepath/hello$ bead input add name
Loading new data to name ... Done
```

Create a program `greet` that produces a greeting, using `input/name` as an input:

```bash
read name < input/name/who-do-i-greet
echo "Hello $name!" > output/greeting
```

Run the program:

```bash
/somepath/hello$ bash greet
```

This script has create a text file in `output/greeting`. Let us verify its content:

```bash
/somepath/hello$ cat output/greeting
Hello World!
```

Load specific version of an input in bead

I want to roll back analysis. I have cherry picked by bead meta, but how do I load the exact bead versions into the input folder?

You need to `bead input delete` it first, and then `bead input add` the version you would like to use. `bead input load` and `bead input unload` do not touch the bead meta, they only load the data specified in the meta to the input folder or delete them from the input folder (to free up disk).

Bead input have a time option. For example: you have two versions with different time stamps. address\_balance\_20180823T120149294589+0200.zip address\_balance\_20200317T111341998516+0100.zip

If you want to use version 20180823 you can type:

`bead input add address_balance -t 20180823`

You have to use the bead name and the yyyymmdd part of the timestamp with the -t option.

(source: <https://stackoverflow.com/c/ceu-microdata/questions/40>)

### Visually display the bead chain

Bead web is a new feature of version 0.8.1. You can check the details with `bead web -h`

```bash
$ bead web color auto-rewire heads / source-bead target-bead / png filename.png
```

Auto-rewire is required for the new bead.

Color is optional.

Heads are optional: if loaded they will only plot the latest version of each bead plus what is referenced by another bead.

If you change the source bead to `..` it plots the entire bead structure leading to the target bead. If you change the target bead to `..` it plots the entire structure starting from the source bead. It is very important that before and after `/` you need a space character.

Instead of png it can be `svg filename.svg` if you prefer that format.

### Package the data and send it to an outside collaborator

Save our new bead:

```bash
/somepath/hello$ bead save latest
Successfully stored bead.
```

This stores output, computation and references to inputs. Now the content of `/somepath/BeadBox` is

```bash
/somepath$ ls -1 BeadBox/
hello_20160527T130218513418+0200.zip
name_20160527T113419427017+0200.zip
```

These are regular (and, in this case, small) zip files, which can be transferred by usual means (e.g. emailed) to collaborators. The recipient can process them via the `bead` tool, keep the integrity of provenance information, and adding further dependencies as needed. Even withouth the tool, she can access the data by directly unzipping the file and inspecting its content.

The output of the computation is stored under `data/*`. An outide collaborator without access to `bead` can just ignore the computation and all other metadata.

```bash
/somepath$ unzip -p BeadBox/hello_20160527T130218513418+0200.zip data/greeting
Hello World!

/somepath$ unzip -v BeadBox/hello_20160527T130218513418+0200.zip
Archive:  BeadBox/hello_20160527T130218513418+0200.zip

    This file is a BEAD zip archive.

    It is a normal zip file that stores a discrete computation of the form

    output = code(*inputs)

    The archive contains

    - inputs as part of metadata file: references (content_id) to other BEADs
    - code as files
    - output as files
    - extra metadata to support
    - linking different versions of the same computation
    - determining the newest version
    - reproducing multi-BEAD computation sequences built by a distributed team

    There {is,will be,was} more info about BEADs at
    - https://unknot.io
    - https://github.com/ceumicrodata/bead
    - https://github.com/e3krisztian/bead

    ----

    Length    Method    Size  Cmpr    Date    Time   CRC-32   Name
    --------  ------  ------- ---- ---------- ----- --------  ----
    13        Defl:N       15 -15% 2016-05-27 13:01 7d14dddd  data/greeting
    66        Defl:N       58  12% 2016-05-27 13:01 753b9d15  code/greet
    742       Defl:N      378  49% 2016-05-27 13:02 a4eb5de9  meta/bead
    456       Defl:N      281  38% 2016-05-27 13:02 9a206f53  meta/manifest
    --------          -------  ---                            -------
    1277                  732  43%                            4 files
```

![](/files/-MTBhFgj9kWp14zsf8ji)

The following graph summarizes the internal structure of a workspace and the logical links to other beads.

## Bead boxes

> ### Key Points
>
> * Keep and share data together with the code that produced it.
> * When sharing your data, always do it in a bead.
> * Never refer to external data from a bead, use bead inputs.


# Working with data

How to work with the data

> ### Overview
>
> Questions
>
> * What are the general rules about working with data?
> * How to handle sensitive data?
>
> Objectives
>
> * Distinguish data at different stages of processing.
> * Protect sensitive data with appropriate measures.

## Stages of data

### Stage 0: raw data

Raw data is incoming data in whatever format. HTMLs scraped from the web, a large SQL dump from a data vendor, dBase files copied from a 200 DVDs (true story). Always store this for archival and replication purposes. This data is immutable, will be written once and read many times.

> Example: country names, capitals, areas and populations scraped from [scrapethissite.com](https://scrapethissite.com/pages/simple/), stored as a single HTML file.

### Stage 1: consistent data

Constistent data has the same information content as the raw data, but is in a preferred format with a consistent schema. You can harmonize inconsistent column names, correct missing value encodings, convert to CSV, that sort of thing. No judgmental cleaning yet. In our case, consistent data contains a handful of UTF-8 encoded CSV files with meaningful column and table names, generally following [tidy data principles](http://vita.had.co.nz/papers/tidy-data.html). The conversion involves no or minimal information loss.

> Example: A single CSV file with columns `country_name`, `capital`, `area`, `population`, in UTF-8 encoding.

### Stage 2: clean data

Clean data is the best possible representation of information in the data in a way that can be reused in many applications. This conversion step involves substantial amount of cleaning, internal and external consistency checks. Some information loss can occur. Written a few times, read many times, frequently by many users for many different projects. When known entities are mentioned (firms, cities, agencies, individuals, countries), they should be referred to by canonical unique identifiers, such as [ISO-3166–1 codes](https://datahub.io/core/country-list) for countries.

> Example: Same as consistent, with additional columns for ISO-3166 code of countries and [geonames ID](https://www.geonames.org/) of cities. You can also add geocoordinates of each capital city.

### Stage 3: derived data

Derived data usually contains only a subset of the information in the original data, but is built to be reused in different projects. You can aggregate to yearly frequency, select only a subset of columns, that sort of thing. Think SELECT, WHERE, GROUP BY clauses.

> Example: All countries in Europe.

### Stage 4: analysis sample

Analysis sample contains all the variable definitions and sample limitations you need for your analysis. This data is typically only used in one project. You should only do JOINS with other clean or derived datasets at this stage, not before. This is written and read frequently by a small number of users.

> Example: The European country sample joined with population of capital cities ([from the UN](https://unstats.un.org/unsd/demographic/products/dyb/City_Page.htm)) so that you can calculate what fraction of population lives in the capital.

### How do you progress from one stage to the other?

**Automate all the data cleaning and transformation between stages**. This is often hardest between raw and consistent, what with the different formats raw data can be in. But from the consistent stage onwards, you really have no excuse not to automate. Have a better algorithm to deduplicate company names (in the clean stage)? Just rerun all the later scripts.

**Don’t skip a stage**. Much as with the five stages of grief, you have to go through all the stages to be at peace with your data in the long run. With exceptionally nicely formatted raw data, you may go directly to clean, but never skip any of the later stages. This follows from [modular thinking](https://dev.to/korenmiklos/the-tupperware-approach-to-coding-1g74): separate out whatever you or others can reuse later. What if you want to redo your country-capital analysis for Asian countries? If you write one huge script to go from your raw data to the analysis sample, none if it will be reused.

**Join late**. It may be tempting to join your city information to the country-capital dataset early. But you don’t know what other users will need the data for. And you don’t want to join before your own data is clean enough. A clean data should be as close to the [third normal form](https://en.wikipedia.org/wiki/Database_normalization#Normal_forms) as possible.

**Share your intermediate data products**. All the data cleaning you have done might be useful for others, too. If possible, share your intermediate products with other analysts by saving a [`bead`](https://handbook.microdata.io/onboarding/bead).

## Categories of data protection

Privacy and ethical considerations necessitate good data protection practices. We have three categories of data:

### CAT1: Public data

The data is available publicly elsewhere. There is no embarrassment if accidentally made public.

There are no restrictions on storage and sharing beyond common sense. Can be shared in response to a data request without approval.

### CAT2: Private data

The data is not available publicly. It is proprietary or has business value. (For example, company names, addresses and financials.) Some embarrassment and possible legal implications if accidentally made public.

Access is limited to authorized individuals within CEU. Special care should be taken when sharing, transporting data. Sharing outside CEU may be allowed, but decided on a case-by-case basis.

### CAT3: Sensitive data

The data is not available publicly. It either has large business value or relates to sensitive information on individuals specifically protected by GDPR. (For example, addresses of individuals, political connections, names of company partners.) Major embarrassment and certain legal implications if accidentally made public.

Access is limited to authorized individuals within CEU. Data can only be stored and transported on encrypted medium. Sharing outside CEU may be allowed, but decided on a case-by-case basis and encryption rules still apply.

> ### Key Points
>
> * Never modify raw data.
> * Always keep CAT3 data on encrypted medium.


# Storing CAT3 data

How do I create an encrypted folder on my computer?

CAT3 data can only be stored on ecrypted medium. How do I create such a folder on Windows, Mac and Ubuntu?

## Encryption tutorial for windows systems

How to choose the best data protection, encryption technology? <https://www.youtube.com/watch?v=12pQG8sHILY>

*Check your computer have a built-in SED SSD or HDD*

If you have a Self-Encrypting Drive (SED) SSD you can turn on that. Find a proper YouTube video how to turn on SED or write to me.

Check you SSD here: /Control\_panel/Device\_manager/Disk\_drives

*Turn on Windows Bitlocker.*

The latest Windows products have built in Bitlocker software. Only in Win 7 PRO version DON’T have.

Tutorial for Win 8/10:

<https://www.youtube.com/watch?v=5o9zGAOOg4c>

*Use VeraCrypt for Full Disk Encryption (FDE)*

<https://www.youtube.com/watch?v=i_WkMELC790&t=178s> In my case FDE successfully created with VeraCrypt 1.19 on my Dell Latitude E6430, WIN 7 Pro, with Micron C400 RealSSD 2.5”. Steps:

* Download and install VeraCrypt. <https://www.veracrypt.fr/en/Downloads.html>
* Run and click Create Volume.
* Choose: Encrypt the system partition or entire system drive.
* Type of system protection – Normal.
* Encrypt the whole drive – Attention: The program says if you have Recovery drive the VeraCrypt boot loader can cause damage.

Check Disk Management. (Write “partition” to Search field.)

Despite the attention I choose “NO” because I want a FDE and there were no problems with the boot.

* Encryption of host protected area I choose “YES”. If you have SDD and ALSO a HDD (RAID system) choose “NO”
* Encryption options: AES – SHA 256. If you choose complicated encryption algorithm the encryption process takes more time.
* Password: Choose minimum 20 characters. Write it somewhere! (Phone, Paper etc.) I used this site for help: <http://www.xorbin.com/tools/password-generator>

When you will enter the code when your system boot, you must use US/EN keyboard settings. So be careful with @#$ characters. (US keyboard Shift+2, Shift+3, Shift+4)

If you choose the PIM option AFTER you entered the password, you also must type numbers as a second password. If you choose a big number for PIM, the boot time will dramatically increase! I don’t use PIM number but I have a very strong password!

* Do the encryption choose “game” with you mouse. 
* Save a rescue disk. It is good if the booting menu or the BIOS have some errors. With a rescue disk, you can decrypt your hard disk drive. I save the rescue disk iso file to a USB drive and skip this step because my DVD burner doesn’t work. If you have a DVD burner do this step.
* Wipe mode: I choose zero because of the encryption speed.
* When you restart your machine, you can try your password.
* When the encryption is running turn off sleep mode and do not turn off the computer!
* When the encryption is ready and you restart your machine, you should see “System drive” in your VeraCrypt window.

## Mac

Create an encrypted .dmg disk image, which can be mounted. Using Disk Utility, select "Create new image" and choose "Encryption". Create a long-enough password to make it secure. Give the image a short but memorable name (say, `Data3`). You can easily set up an image of even 20GB or more. Put the .dmg file somewhere where you can easily access it.

Double-click the .dmg file to mount it. After you enter the password, the encrypted "drive" will be mounted under `/Volumes/name-of-image`. [source](https://www.howtogeek.com/183826/how-to-create-an-encrypted-file-container-disk-image-on-a-mac/)

## Linux (Ubuntu 18.04)

The new Dell XPS/Ubuntu laptops at MicroData are already encrypted.

I strongly advise to encrypt the whole disk with luks when you install your OS instead of encrypting a single folder. The latter is also feasible but much less convenient.

To create an encrypted folder use ecryptfs. First you need to install it by opening up a terminal and issuing the following command (you will get prompted for a password):

```
sudo apt-get -y install ecryptfs-utils
```

Create a new directory that we will encrypt. In this example, it is the directory called `secure` within the `home` folder of the currently logged in user:

```
mkdir ~/secure
```

Now we encrypt it by mounting it with encryptfs:

```
sudo mount -t ecryptfs ~/secure ~/secure
```

You will get prompted for your password and then a passphrase. Choose a strong passphrase. You have to select a cipher. Select `aes: blocksize = 16; min keysize = 16; max keysize = 32`. Yo have to select a key size. Select 32. You will be asked if you want to enable plaintext passthrough. Select no. You will be asked if you want to enable filename encryption. Select yes. When you are asked for a Filename Encryption Key (FNEK) Signature just press enter. When it asks if you would like to proceed with the mount, select yes. When it asks if you would like to append sig \[list of chars] to \[/root/.ecryptfs/sig-cache.txt] in order to avoid this warning in the future select yes.

Your encrypted folder is now ready. To unmount it, type:

```
sudo umount ~/secure
```

You can mount it again anytime by

```
sudo mount -t ecryptfs ~/secure/ ~/secure/ -o ecryptfs_cipher=aes,ecryptfs_key_bytes=32,ecryptfs_passthrough=no,ecryptfs_enable_filename_crypto=yes
```

Just type your passphrase and press enter when it asks for your FNEK.

(source: <https://stackoverflow.com/c/ceu-microdata/questions/32> )


# Best practices

> ### Overview
>
> Questions
>
> * How to name files and variables?
> * What code style do we use?
> * How to ensure reproducible research?
>
> Objectives
>
> * Use verbose, helpful file and variable names.
> * Read and write data in a way facilitating reproducibility.

These guidelines help us share data among themselves. Always make the extra effort to make your work understandable to others: you are in the best position to explain what you did. If you follow these guidelines, you only have to do this once for every data product you create.

## Naming files and folders

1. `/data/source-of-data/name-of-dataset/stage`. For example, `/data/mak/pir_entities/raw`
2. Use long, expressive filenames, e.g. `balance-sheet-with-frame.dta` rather than `bs-merge.dta`
3. Use-dash-for-word-separation, not CamelCase, space or underscore.
4. Do not indicate version in filename. File versions should be managed by version control tool.
5. Do not indicate author in filename. File versions should be managed by version control tool.
6. For folders and files containing multiples of the same entity, use plain English singular filenames, e.g. `city.csv`, `county.csv`, `mayor.csv`, `exhibit/figure`, `output/table`&#x20;

## Data format

1. All text data files use UTF-8 encoding from the “consistent” stage upward. If the raw file is in any other encoding, your first task is to convert it to UTF-8.
2. CSV files are generally the preferred format, with `,` as separator and `”` as quote character.  Do NOT use `;` or tab as separator. CSV format is easily processed by all software (Python, STATA, Excel, ...), the only problem being with separators and quote characters defined according to individual preferences.
3. Missing values are missing. Do not include any special values (N/A, -99, 0) for missing values in fields, leave them blank. The user of the data should build in any logic to deal with missing values.
4. Only share one format of a dataset. Do not include both .csv and .dta. In some cases, .dta might be preferred (mostly numerical variables, labeling). Then we do not need .csv with the same content.

## Input and output

1. Every output you are sharing is a file saved by a script. Do not copy paste figures and tables. If you want to share it, create a script that saves it in a file (.dta, .csv, .gph, .pdf, .png etc)
2. Every script produces exactly one output, not more. If your code is producing more pieces of output, break it up into smaller pieces.
3. Use relative paths exclusively for accessing data. `../data/election/mayor.csv`, not `/home/koren/projects/political_connections/data/election/mayor.csv`
4. Use forward slashes in paths. (See <http://momentofmethods.com/blog/2012/09/19/cultivate-your-tree/>)
5. The output of a script should be named differently than any existing input or output file generated by other scripts. This rule ensures that the question “what script created this file?” can be answered.&#x20;
6. As a special case: never use the same file for input and output within a single script. If the script fails, nobody will know what the file actually contains.
7. Leave no trace: use temporary files and variables. For Stata variables and files storing intermediate calculations, that are not inputs to other scripts, use “tempvar” and “tempfile.” These are automatically deleted once your script finished.
8. Only put those data files in output folder of bead that will be actually used. Keep temporary files in the temp folder.

## Code style guide

1. Python code must follow [PEP-8](https://www.python.org/dev/peps/pep-0008/).
2. Stata code must follow [this guide](https://handbook.microdata.io/onboarding/stata-style-guide).

> ### Key Points
>
> * Name variables and datasets with nouns of what they contain.
> * Name scripts with verbs of what they do.
> * Every piece of data is written by a script.
> * Every piece of data is written by *one* script.


# Stata style guide

> ### Overview
>
> Questions
>
> * How to name variables?
> * What code style do we use?
>
> Objectives
>
> * Use verbose, helpful variable names.
> * Make your code accessible to others.

## Files

#### Use forward slash in path names

Write `save "data/worker.dta"`, not ~~`save "data\worker.dta"`~~. The former works on all three major platforms, the latter only on Windows.

#### Write out file extensions

Write `save "data/worker.dta"` and `do "regression.do"`, not ~~`save "data/worker"`~~ or ~~`do "regression"`~~. Even though some extensions are appended by Stata by default, it is better to be explicit to help future readers of your code.

#### Put file paths in quotes

Write `save "data/worker.dta"` and `do "regression.do"`, not ~~`save data/worker.dta`~~ or ~~`do regression`~~. Both are correct, but the first is more readable, as most editors readily highlight strings as separate from programming statements.

#### Use relative path whenever possible

Write `save "../data/worker.dta"`, not ~~`save "/Users/koren/Tresorit/research/data/worker.dta`~~. Nobody else will have the same absolute path as you have on your system. Adopt a convention of where you are running scripts from and make paths relative to that location.

## Naming

#### Do not abbreviate commands

Use `generate ln_wage = ln(wage)` and `summarize ln_wage, detail`, not ~~`g ln_wage = ln(wage)`~~ or ~~`su ln_wage, d`~~. Both will work, because Stata allows you abbreviation, but the former is more readable.

#### Do not abbreviate variable names

Use `summarize ln_wage, detail`, not ~~`sumarize ln_w, detail`~~. Both will work, because Stata allows you abbreviation, but the latter is very error prone. In fact, you can turn off variable name abbreviation with `set varabbrev off, permanent`.

#### Use verbose names to the extent possible

Use `egen mean_male_wage = mean(wage) if gender == "male"` , not ~~`egen w1 = mean(wage) if gender == "male"`~~. Your variables should be self documenting. Reserve variable labeling to even more verbose explanations, including units: `label variable mean_male_wage "Average wage of male workers (2011 HUF)"`.

#### Separate name components with underscore

Use `egen mean_male_wage = mean(wage) if gender == "male"` , not ~~`egen meanmalewage = mean(wage) if gender == "male"`~~ or ~~`egen meanMaleWage = mean(wage) if gender == "male"`~~. The former is more readable. Transformations like mean, log should be part of the variable name.

#### Do not put units and time in the variable name

Use `revenue` , not ~~`revenue_USD`~~ or ~~`revenue_2017`~~. Record this information in variable labels, though. You *will* change your code and your data and you don't want this detail to ruin your entire code.

#### It is ok to use short macro names in short code

If you have a `foreach` loop with a few lines of code, it is fine to use a one-character variable name for indexing: `foreach X of variable wage mean_male_wage {`. But if you have longer code and `X` would pop up multiple times, give it a more verbose name.

#### It is ok to use obvious abbreviation in variable names

If you are hard pressed against the 32-character limit of variable name length, use abbreviation that will be obvious to everyone seeing the code. Use `generate num_customer`, not ~~`generate number_of_customers_of_the_firm`~~ or ~~`generate n_cust`~~.

## White space

#### Include a space around all binary operators

Use `generate ln_wage = ln(wage)` and `count if gender == "male"`, not ~~`generate ln_wage=ln(wage)`~~ or ~~`count if gender=="male"`~~. The former is more readable.

#### Include a space after commas in function calls

Use `assert inlist(gender, "male", "female")` not ~~`assert inlist(gender,"male","female")`~~. The former is more readable.

#### Indent code that belongs together

```
foreach X of variable wage mean_male_wage {
   summarize `X', detail    
   scalar `X'_median = r(p50)
}
```

not

```
foreach X of variable wage mean_male_wage {
summarize `X', detail    
scalar `X'_median = r(p50)
}
```

#### Each .do file should be shorter than 120 lines

Longer scripts are much more difficult to read and understand by others. If your script is longer, break it up into smaller components by creating several .do files and calling them.


# Project management

We have experimented with many project management tools and methods.

## Trello

[Trello](http://trello.com/) lets you move cards across lists. Cards can contain checklists, comments, attachments, labels, letting you flexibly organize your tasks. In our experience, this approach works best for standardized, repetitive workflows. We use Trello for [release management](https://handbook.microdata.io/tools/release) and handling *data requests*.

## GitHub

Each project has its own repository on GitHub. You should always know what repository your work belongs to, this is where you will be pushing your work.

GitHub lets you create [issues](https://guides.github.com/features/issues/) for each repository. *Issues* are tasks to be done and are a simple way to organize your work with team mates. An active project has a growing number of *closed* issues and dozens of *open* ones.

When you *open a new issue* (i.e., create a new task), pay attention to the following:

### Title

Give a concise description of the thing to be done or the error that you face. Use active, specific language, such as "Remove gridlines from Figure 2", not "Edits needed".

### Description

Describe the intended outcome and the necessary steps as much as you can. You know best what you want to get done, write it down.

### Status

An issue can be *open* (still working on it) or *closed* (fixed or deemed not relevant). When you close an issue, also comment on your solution.

### Labels

You can select one ore more labels to classify your issue. This is not mandatory, but can help prioritize efforts if there are dozens or hundreds of open issues. Standard labels include "bug" (something isn't working) or "question." Developers can label your issue as "duplicate" or "wontfix."

### Assignee

Only assign an issue to a user if you are sure who is responsible for fixing it. For example, it is always encouraged to write yourself an issue and *assign it to yourself*. It will help you manage your todos, and others will also see what you are working on.

### Milestone

Milestones are a way of prioritizing issues and matching them to external deadlines. This is typically done by a manager. Example milestones can include "EEA presentation 2021" or "Cegjegyzek LTS alpha release".


# Datasets

Key datasets in MicroData

> #### Overview
>
> Questions
>
> * Which are the most important datasets and how to join them together?
> * What is an LTS dataset?
> * Where do I find the datasets on the server?
>
> Objectives
>
> * Understand the difference between primary and foreign keys
> * Get to know major databases

## Main datasets

The three main important datasets are the `merleg-LTS-2020`, the `cegjegyzek-LTS-2020` and the `kozbeszerzes-LTS-2020`. The meaning of LTS is `long-term support` and `2020` is the input year when the data arrived.

The merleg data updates are arriving in December and contains information of the previous tax year. In the 2020 version the last tax year is 2019. The merleg database are processed version of the income statements, the balance sheet (assets and liabilities) and the additional annexes.

The cegjegyzek updates are arriving every year at May and contains information till that date.

## LTS

The [long-term support](https://en.wikipedia.org/wiki/Long-term_support) (LTS) database idea comes from software development.

Our LTS products will be upgrading every year at a given date. The users can count with the new versions and have enough time to prepare their scripts on them.

Every time when we make a new LTS there is a possibility to add new feature request. Before every version update the team talk trough which feature requests will be in each releases.

<https://docs.google.com/document/d/16wEJFy-XFKkRMMKUDPx3gia73hs8odiOf-Ov1Ytj6QY/edit#heading=h.718700q5qmgh>

## Primary keys

The `Primary key` constraint uniquely identifies each record in a table. Primary keys must contain UNIQUE values, and cannot contain NULL values. A table can have only ONE primary key; and in the table, this primary key can consist of single or multiple columns (fields).

<https://www.w3schools.com/sql/sql_primarykey.asp>

### Frame\_id

Frame\_id is the primary key in most of our datasets represents a unique identifier for each corporation in our data. The unit of observation is an incorporated business entity. Frame\_id connects companies transformed from one predecessor to one successor. It is based on registry court columns and announcement information about the transformation of companies. It aims to prolong the life of companies by not breaking the life cycle when a company changes tax number during transformation.

Frame IDs that start with “ft” are created from a tax identifier of the firm. Frame IDs that start with “fc” are created from a cégjegyzékszám. This means that the variable is composed of a notation “ft” and the first tax number in time. Any number could appear after “ft”, the use of the tax\_id is left only to help with verification but it is better not to use it as a valid tax number.

### Tax\_id and originalid

Tax id could be primary or foreign key also. From the full length 11 character long tax\_id we use the `prime number` the first eight character of the id.

More information about the Hungarian tax ids:

<https://hu.wikipedia.org/wiki/Ad%C3%B3sz%C3%A1m>

The variable called `originalid` in merleg database is basically a tax id where we use a fictive negative number if we have a missing tax\_id. In the merleg database we drop the tax\_ids starts with 15,16,19 or if they bigger than 3000001.

More about Hungarian tax\_id character meanings:

<https://drive.google.com/file/d/1mxWv2Pz2bES-5dDo-FUWj83wYJImvOCR/view?usp=sharing>

## Detailed meta information about the main datasets

### Merleg-LTS-2020

The detailed variable descriptions and development history are in the merleg-LTS-2020 bead output folder. The most important merleg related variables are the following:

```
variable name                       type    format      variable label

frame_id                            str15   %15s        Frame_id identify one firm. Only_originalid if not valid
originalid                          long    %10.0g      Given year Taxid. Minus if taxid not valid
year                                int     %9.0g       Year 1980-2019
sales                               double  %12.0g      Sales 1000HUF
sales19                             double  %12.0f      Sales in 2019 price 1000HUF
emp                                 double  %9.0f       Employment clean v2
export                              double  %12.0g      Export sales 1000HUF
wbill                               double  %12.0g      Wage bill, Bérköltség 1000HUF
persexp                             double  %12.0g      Payments to personnel, Szemráf sum 1000HUF
pretax                              double  %12.0g      Net profit before taxation 1000HUF
teaor03_2d                          byte    %9.0g       2 digit TEAOR03
teaor08_2d                          byte    %9.0g       2 digit TEAOR08
gdp                                 double  %10.0g      Gross Value Added: sales+aktivalt-ranyag 1000HUF
gdp2                                double  %10.0g      Gross Value Added:(persexp+kecs+ereduzem+egyebbev)-egyebraf 1000HUF
ppi19                               double  %10.0g      Producer price index 2019=1
so3_with_mo3                        byte    %9.0g       State and local government owned dummy with ultimate owners from Complex
so3                                 byte    %9.0g       State government owned dummy with ultimate owners
fo3                                 byte    %8.0g       Foreign owned dummy with ultimate owners from Complex
do3                                 byte    %9.0g       Domestic owned dummy which is not so3 or fo3
mo3                                 byte    %9.0g       Local government owned dummy which is not so3
```

### Cegjegyzek-LTS-2020

#### Organization of information in files

**Entities**

In the different relation files contain fields (owner\_id, manager\_id, frame\_id, person\_id\_1, person\_id\_2) for entities designated with ids. In manage.csv and own.csv the type field (manager\_type, owner\_type) containing two-part strings separated with a hyphen, in the first part ‘HU’ stands for hungarian, domestic entity, while the second part designates whether it is a person (‘P’), a firm (‘F’), a municipality owned (‘MO’), a central government owned (‘SO’) or other unspecified (‘O’) type entity. The entity ids can take one of the following form:

**Frame ID**

See frame\_id section.

**Person ID**

If an ID starts with ‘P’ it uniquely designates a person with hungarian name. If it starts with ‘PP’ the uniqueness is derived from knowing both the own and mother’s name of the person, if it starts with ‘PHM’ the uniqueness is based own husband’s and mother’s name, if it starts with ‘PR’ the uniqueness is based on rarity of the name.

**Public owned entity ID**

For hungarian public (i.e. state or municipality) owned entities we used the pir id, which is a 6-digit number. The ‘SO001’ stands for state ownership through non specified entity. ‘10011953’ designates the Hungarian National Bank, which has no pir id. The ‘entity/pir.csv’ contains the pir number and the corresponding entity.

**Mock ID**

If an ID starts with ‘FP’ it is a mock id, which means it is neither a uniquely resoluted person with hungarian name, or a hungarian corporation or a state owned entity. Entities with this ID are unique within but not across corporations.

**Address ID**

Address IDs are structured like this:

`CC-SSSSS-DD-AA-WWWWW-TT-N(NNN)`

Where:

* CC: Two-character country code, e.g.: HU
* SSSSS: Settlement code. For Hungarian addresses this is the KSH Code.
* DD: District. For Budapest the actual district, 00 if unknown. For cities with suburbs it should be 01 for the city itself, and 02, 03, 04 etc. for the different suburbs.
* AA: Larger administrative area (county, only for hungarian addresses)
* WWWWW: Public way name. The same name should have the same ID across settlements.
* TT: Public way type/Street suffix. The same type should have the same ID across settlements. The key for this is in entity/official\_domain\_names.csv
* N(NNN): The number of the building. If a building has a span of numbers, the lowest should be used. E.g. in case of Nador utca 9-15, number 9 is to be used.

For now, we don’t identify floors and door numbers.

#### Direct relations

Direct relations are relations explicitly available in Corporate Registry. In these files the ‘source’ field contains a 4 part string separated by underscores designating the reference to the original CR data point, the 4 parts are the following: CR number (cégjegyzékszám), CR rubric (rovat), row number within rubric (alrovat\_id) and the group prefix (the prefix of variable group within rubric row: ‘’, ‘p’, ‘pc’, etc.)

**ownership - relation/own.csv**

The table contains the ownership relations as they are documented in Corporate Registry. The entity designated with ‘owner\_id’ is an owner in a hungarian corporation designated with the frame\_id. The ‘owner\_id’ can take a form of a person\_id, frame\_id or a tax\_id of a state or municipality owned entity. The ‘share’ field is a ratio which shows the realtive share of the owner entity in the corporation. The ‘share\_flag’ tells us about the quality of the data (empty string - no share data was avaialble, 0.0 - could not be tested against share emission data, 1 - total share counts add up to share emission data, 2.1-2.2 the share was corrected using emission data, 3 - messy share data). The ‘share\_source’ indicates from which original data field the share comes from.

**signature rights and board members - relation/manage.csv**

This table contains the significant employees and board members (‘manager\_id’) for a specific corporation (‘frame\_id’). The data comes from rubric 13 (signature rigths) and 15 (board members) of the Corporate Registry. The ‘position’, ‘board’, ‘liquidator’, ‘self-liquidator’ fields designate the role played by the entity within the corporation. The ‘position’ field can be one of the following values: ‘1’ - CEO, ‘2’ - significant manager, 3 - other employee, 0 - no specific information.

#### Indirect relations

***Firm and person networks based on ownership and location***

The outputs are temporal edge lists. Each record in the output csv files contains an edge. Each record contains the nodes connected by the edge along with the beginning date and end date of the connection and the shared characteristic between the two nodes. If the end date of the connection is empty it means that the connection is still in effect. A network file may contain flags describing the type of connection. These flags are described below at the corresponding network. The code currently generates the following three network types:

**Firm network based on common owner or manager**

Two firms (identified by frame id) are connected if they share an entity (manager or owner, identified by manager\_id or owner\_id) at a given time period. The output contains mixed connections (i.e. person X is a manager at firm A and an owner of firm B at a given time period). The role of the person (or entity, an owner may be a firm for example) in the two firms is conserved by corresponding position variables taking the values "o" for owner and "m" for manager. If you need a network based on only ownership connections you can easily filter this output to those edges where both position variables take the value "o". The same way it works for a manager based network.

**Person network based on common firm**

Two people (identified by manager\_id or owner\_id, but ONLY IF it is a proper person id) are connected if they are present at the same firm (as a manager or owner) at a given time period. The output contains mixed connections (i.e. person A is a manager at firm X while person B is an owner of firm X at a given time period). The roles of the people in the firm are conserved by corresponding position variables taking the values "o" for owner and "m" for manager.

**Firm network based on common address**

Two firms (identified by frame id) are connected if they share an address (hq, site or branch, identified by address\_id) at a given time period. The output contains mixed connections (i.e. Firm A has it's HQ at address X and Firm B has a branch at the same location). The role of the address in the two firms is conserved by corresponding type variables taking the values "h" for HQ, "b" for branch, and "s" for site.

```
## Schema

####entity/county_settlement.csv
    settlement
    county_code

####entity/HU-TTT.csv
    pw_type
    index
    timestamp

####entity/official_domain_names.csv
    Names

####entity/HU-WWWWW.csv
    pw_name
    index
    timestamp

####entity/settlement_codes.csv
    settlement
    suburb
    SSSSS
    DD

####entity/county_codes.csv
    irsz
    county_code

####entity/pir.csv
    pir
    tax_id
    name
    settlement

####entity/frame.csv
    frame_id
    tax_id
    ceg_id
    name
    is_alive
    birth_date
    death_date
    is_hq_change
    is_site
    is_transforming
    is_in_complex
    is_tax_id_corrected

####relation/manage.csv
    frame_id
    source
    manager_id
    manager_type
    sex
    birth_year
    valid_from
    valid_till
    consistent
    address_id
    country_code
    board
    position
    self_liquidator
    liquidator

####relation/own.csv
    frame_id
    source
    owner_id
    owner_type
    sex
    birth_year
    valid_from
    valid_till
    consistent
    address_id
    country
    share
    share_flag
    share_source

####relation/hq.csv
    frame_id
    address_id
    source
    valid_from
    valid_till

####relation/site.csv
    frame_id
    address_id
    source
    valid_from
    valid_till

####relation/branch.csv
    frame_id
    address_id
    source
    valid_from
    valid_till

####relation/firm_network_common_owner.csv
    edge_id
    frame_id_1
    frame_id_2
    pos_1
    pos_2
    valid_from
    valid_till

####relation/owner_network_common_firm.csv
    edge_id
    person_id_1
    person_id_2
    pos_1
    pos_2
    valid_from
    valid_till

####relation/firm_network_common_address.csv
    edge_id
    frame_id_1
    frame_id_2
    type_1
    type_2
    valid_from
    valid_till
```

### Manager DB

The Manager Database (bead name: `manager-db`) is a product derived directly from `cegjegyzek-LTS`. It creates annual snapshots at each firm: which personids were present in a managerial or supervisor role on June 21 of the year at that firm? To save space, it also converts person ids to integers.

The distribution of observations by year:

```
. tab year

       year |      Freq.     Percent        Cum.
------------+-----------------------------------
       1985 |     28,421        0.19        0.19
       1986 |     30,543        0.21        0.40
       1987 |     32,262        0.22        0.62
       1988 |     34,466        0.24        0.86
       1989 |     43,239        0.29        1.15
       1990 |     80,453        0.55        1.70
       1991 |    129,114        0.88        2.58
       1992 |    185,419        1.26        3.85
       1993 |    225,611        1.54        5.39
       1994 |    262,548        1.79        7.18
       1995 |    292,539        2.00        9.17
       1996 |    325,777        2.22       11.39
       1997 |    358,657        2.45       13.84
       1998 |    396,858        2.71       16.55
       1999 |    418,114        2.85       19.40
       2000 |    443,218        3.02       22.42
       2001 |    466,555        3.18       25.60
       2002 |    486,076        3.32       28.92
       2003 |    503,443        3.43       32.35
       2004 |    526,839        3.59       35.95
       2005 |    544,955        3.72       39.66
       2006 |    562,152        3.83       43.50
       2007 |    568,498        3.88       47.38
       2008 |    607,264        4.14       51.52
       2009 |    633,191        4.32       55.84
       2010 |    646,992        4.41       60.25
       2011 |    654,054        4.46       64.71
       2012 |    654,001        4.46       69.17
       2013 |    662,217        4.52       73.69
       2014 |    668,125        4.56       78.24
       2015 |    663,694        4.53       82.77
       2016 |    643,644        4.39       87.16
       2017 |    631,312        4.31       91.47
       2018 |    625,928        4.27       95.74
       2019 |    625,020        4.26      100.00
------------+-----------------------------------
      Total | 14,661,199      100.00
```

| Variables              | Meaning                                                                                         | Non-missing observations |
| ---------------------- | ----------------------------------------------------------------------------------------------- | ------------------------ |
| birth\_year            | Birth year of manager                                                                           | 5.3m                     |
| country\_code          | Country of manager home address (compliance with ISO 3166-2 unchecked)                          | 14.6m                    |
| board                  |                                                                                                 |                          |
| position               |                                                                                                 |                          |
| cf                     | Corporation type                                                                                |                          |
| spell\_begin           |                                                                                                 |                          |
| imputed                |                                                                                                 |                          |
| ceo                    | 1 if manager is CEO                                                                             | 14.7m                    |
| year                   |                                                                                                 |                          |
| first\_year\_as\_owner | First observed year of person as an owner of the firm in `manager-db` (missing if not an owner) | 12.1m                    |
| manager\_enter\_year   | First observed year of person in `manager-db`                                                   | 14.6m                    |
| iso639                 | Language code inferred from manager name                                                        | 1,000                    |
| person\_id             |                                                                                                 |                          |
| frame\_id\_numeric     |                                                                                                 |                          |
| expat                  | 1 if manager is a foreign person                                                                |                          |
| male                   | 1 if manager is known to be male                                                                |                          |

Only natural persons are kept, not liquidators and other firms. If a firm has no reported CEO in a given year, the following imputation rules are used:

1. If the firm has 3 or fewer managers, all of them will be classified CEOs (4,389 firm-person-years)
2. If the firm still has no CEO, its past CEOs will be imputed (4,647 firm-person-years)

### CEO Panel

The CEO Panel (bead name: `ceo-panel`) is a product derived directly from `manager-db`. It only keeps CEOs and fills in firms that do not have a reported CEO. Fill-in rules:

Impute CEOs from the past, up to 3 years. - 1 year: 43,000 - 2 years: 17,000 - 3 years: 10,000

Total number of observations: 12,891,181

### Kozbeszerzes-LTS-2020

### The bead chain

![](/files/-MTBhj_LoTlKjLsm-b8z)

The input data is from the Procurement Authority website <http://www.kozbeszerzes.hu>. The final bead is the `kozbeszerzes-LTS-2020`. The bead chain is made up of these elements:

* `kceu_oldhtml`: Mock bead (output only). Contains tenders between 1997 and 2006. These files cannot be retrieved from the website anymore. The files are in html format in the output folder.
* `kceu_newhtml`: Mock bead (output only). Contains tenders between 2007 and 2017. These files have been downloaded by the scripts of the `kceu_download` bead (see below). The files are in html format in the output folder.
* `kceu_download`: Contains scripts for downloading tenders from the website for any arbitrary year. Currently it contains the 2019 tenders. The files are in html format in the output folder.
* `kceu_parsed`: Using the three above beads as input, it converts the tender html files to structured, hierarchical xml files by extracting the relevant pieces of information from the published notices. This bead mainly consists of an external parser and the modular parser. The external parser software works as a black box for us. The latter is an internal development which works for certain notice types, to improve the external parser performance. The output files are structured xml files for each tender.
* `kceu_cleaned`: Using the `kceu_parsed` bead as input, it removes empty tags from the xml files, and converts foreign currencies to HUF.
* `kceu_xml_to_csv`: Using the `kceu_cleaned` bead as input, it converts the xml (separate files for each tender) to different csv files. These are `part.csv` which contains the basic information of the tenders (subject, cpv, value, etc.), `requestor.csv`, `bidder.csv`, and the `winner.csv`, which list the relevant entities for each tender part. Note that the latter are intermediary products in the sense that entity resolution and deduplication is still to be carried out on these files (see below).
* `kceu_er`: Using the csv files of the `kceu_xml_to_csv` bead (and additional beads of firm and pir name indexes) as input, it applies entity resolution on the tenders (using `pir search tool` and `firm name search tool` developed within Microdata): that is, it tries to identify the bidder, winner, and requestor firms and institutions using our databases at Microdata. The outputs are the resolved winner, bidder, and requestor csv files which will contain unique identifier (tax id or pir id) for entities so that it can be merged with another Microdata products.
* `kceu_duplicates`: Using the `part.csv` from the `kceu_xml_to_csv` bead, and the resolved csv files of the `kceu_er` beads, it identifies duplicate tenders. It is necessary because some tender result are announced multiple times at the official website for some reason (this is more frequent for older tenders). The identification is based on similarity of requestors and bidders, subject, value, and decision date. The output is a `duplicates.csv` file which list the duplicate tender ids and indicates which lines to drop and which to keep.
* `kceu_hand_inputs`: Despite all our effort to convert every existing procurement data creation process into beads to guarantee reproducibility, there are some remaining files for which we could not identify the source code and/or are unique hand collected inputs that do not fit into standard bead structure. The output files of this empty bead serve as inputs for the `procurement_prepare` bead.
* `procurement_prepare`: This bead combines the output files of `kceu_xml_to_csv`, `kceu_er`, `kceu_duplicates`, and generates a tender part – bidder level datafile (`all_bids.dta`). Moreover, using mostly `merleg-LTS-2020` and some other inputs such as probabilistic firm coloring, it prepares some auxiliary files which contain information on firms, pir entities, firms political connections, and election results.
* `procurement_data`: This bead builds solely upon the input files prepared in the `procurement_prepare` bead. Combining these files, it produces two types of output data ready for analysis: a tender – bidder level dataset called `procurement_bids_data`, which contains all the necessary information from the tender (subject, cpv, estimated value, final value, etc.), the requestor and bidder entities (location, NACE code, balance information, etc.), as well as the outcome of the tender. `procurement_wins_data` is essentially the same file, but for each tender only the winning bidders are included. The other type of output data called `government_private_sales_data` is a yearly panel of firms. Besides the most important balance information, it is a yearly aggregate of each firm's procurement revenues, and based this the private revenues are also derived.

### Media and scraped datasets

We have scraped, parsed and cleaned version of the biggest online media providers in the `media-bead-box`

We have firm year month unique information about advertisement data from 1991-2016.

> #### Key Points
>
> * LTS dataset is supported in the same format at every update
> * LTS beads are more than just a bunch of beads: one LTS package is suitable for use in a large variety of research trends


# Tools

Tools in MicroData

> ### Overview
>
> Questions
>
> * What is a programing tool and why we use them?
> * How to read a tool manual and understand the outputs?
>
> Objectives
>
> * Join a unique ID to a raw .csv with different input types
> * Choose the right cut offs and specify the good matches
> * Get to know how to run a tool on the server with good options

## The problem

There are lots of occasions when we would like to automate some tasks by the help of programming tools.

<https://en.wikipedia.org/wiki/Programming_tool>

One task is when we want to add a unique ID to a raw input variable. An input data could be firm name, person name, governmental institution, foundation, association .etc. Firm and person names also could be foreign ones.

We are continuously developing tools to identify these inputs and give a unique ID to them.

## Firm name search tool

Firm name search tool merges the eight-digit registration number (first 8 digits of tax number) to a Hungarian firm name. You can find, among others, the building and installing methods on github:

<https://github.com/ceumicrodata/firm_name_search>

### Using the tool

#### Requirements:

* Python2 and the tool must be available on the PATH
* a proprietary database index file (available only to members of CEU MicroData)

```python
name-to-taxids-YYYY-MM-DD "firm name" input.csv output.csv
```

where "firm name" is the field name for firm name in `input.csv` and there is an index file in the current directory with name `complex_firms.sqlite`.

The tool provides command line help, so for further details run

```python
name-to-taxids-YYYY-MM-DD -h
```

`FirmFinder.find_complex()` expects a single unicode firm name parameter which it will resolve to a match object with at least these attributes:

* `org_score`
* `text_score`
* `found_name`
* `tax_id`

#### An example how to run firm name search tool in python2

```bash
$ python name-to-taxids-20161004 name temp/distinct_firms.csv temp/distinct_firms_fname.csv --index 'input/firm-name-index/complex_firms.sqlite'
```

The tool searches for tax numbers for items in the `name` field. You must have to add the whitelist path manually: `'input/firm-name-index/complex_firms.sqlite'`

### The meaning of the outcome and how to choose the proper cut off scores

The tool outcomes and scoring system are based on Hungarian legal forms. If an input data has a valid legal form then more likely a Hungarian company that not.

<https://www.ksh.hu/gfo_eng_menu>

A good match is dependend on how well prepared the input data is.\
If the data pre-filtering is good, before we run the tool, a text\_score with lower value could become a good hit. Good cleaning opportunity to drop person names and foreign firm names from the input data.

```
        Score meaning     
   org_score  text_score     meaning
   -20            -20        No results.
   -10            -10        Too much results. 
    -1         0 <= x < 1       The legal form doesn’t match, but the input and found names have one. 
    -1              1        The firm name matches but the legal form doesn’t match. 
     0         0 <= x < 1       Only the input data have legal form.  (Input misspelling error)
     0              1        Only the input data have legal form but the firm name matches. 
     1         0 <= x < 1       Only the found name have legal form.
     1              1        In the input data NO legal form but the firm name matches. 
     2         0 <= x < 1       The legal forms are matching but the firm names not. 
     2              1        Perfect match.
```

Can be said generally that most of the possible matches will be in `org_score==2 and text_score 0 <= x < 1` category. If a data is well prepared `0.8` org\_score could be a suggested cut-off score. Results above this are expected to be good. You must have to adjust the good match cut offs in every time in every category when you run the tool on a new input.

## PIR name search tool

Pir name search tool is developed for identify Hungarian state organizations by name. Pir number is the registration number of budgetary institutions in the Financial Information System at Hungarian State Treasury.

### TIP:

There is an online platform to find PIR numbers one by one.

<http://www.allamkincstar.gov.hu/hu/ext/torzskonyv>

The PIR search command line tool requires Python 3.6+.

Input: utf-8 encoded CSV file Output: utf-8 encoded CSV file, same fields as in input with additional fields for "official data"

<https://github.com/ceumicrodata/pir_search/releases/tag/v0.8.0>

This release is the first, that requires an external index file to work with. You can find this index.json file in the pir-index beads. The index file was separated, because it enables match quality to improve without new releases.

The match precision can be greatly improved by providing optional extra information besides organization name:

* settlement
* date

An extra tuning parameter is introduced with --idf-shift which tweaks the matcher's sensitivity to rare trigrams. Its default value might not be optimal, it changes match quality. Attached files are binary releases for all 3 major platforms: pir\_search.cmd is for Windows, pir\_search (without extension) is for unix-like systems (e.g. Linux and Mac)

### An example how to run pir name search tool in python3

```bash
Run from python3 with settlement option

python3 pir_search-0.8.0 input/pir-index/index.json name temp/distinct_firms.csv temp/distinct_firms_pname.csv --settlement settlement --hun-stop-words \
--pir pir_d --score pir_score_d --match_error pir_err_d --taxid pir_taxid_d --pir-settlement pir_settlement_d \
--name pir_name_d --keep-ambiguous

Run from python3 with settlement option and idf-shift 100 and extramatches

python3 pir_search-0.8.0 input/pir-index/index.json name temp/distinct_firms.csv temp/distinct_firms_pname_extra.csv--settlement settlement --hun-stop-words \
--idf-shift 100 --extramatches
```

The pir\_score output could be between 0 <= x < 1. Pir\_score==1 AND pir\_err==0 is the perfect match.

The bigger the pir\_err score the match is more likely wrong.

`Pir score bigger than 0.8 and pir_err<0.8 are potentially good matches`.

You must have to adjust the good match cut offs in every category, every time when you run the tool on a new input.

## Complexweb

Complexweb is and internal searchable version of the raw Complex Registry Court database. VPN and password is required to log in.

### TIP:

You can find downloadable official balance and income statements from e-beszámolo.hu:

<https://e-beszamolo.im.gov.hu/oldal/kezdolap>

You can easily find the firm you are searching for if you change the tax\_id or the ceg\_id in the html:

```bash
Example pages with fictive tax_id

http://complexweb.microdata.servers.ceu.hu/cegs_by_tax_id/12345678 to 
http://complexweb.microdata.servers.ceu.hu/cegs_by_tax_id/12345679

Example pages by ceg_id

http://complexweb.microdata.servers.ceu.hu/ceg/0101234567 to
http://complexweb.microdata.servers.ceu.hu/ceg/0101234568
```

You can write Postgre SQL queries to request more complex searches:

<https://www.postgresql.org/docs/13/index.html>

```
Examples

* Count not null ceg_id from rovat 109 which is KFT

select count(distinct(ceg_id)) from rovat_109-- where cgjsz is not null

* Select a string part from a rovat 

select * from rovat_99 where szoveg like '%%Összeolvadás%%'
select ceg_id from rovat_3 where nev like '%%nyrt%%' or nev like '%%NYRT%%' or nev like '%%Nyrt%%'

* Select a string part from a rovat order and limit

select ceg_id from rovat_99 where szoveg like '%%átalakulás%%' and szoveg not like '%%való átalakulását határozta el%%' order by random() limit 20

* Select different variables from different rovats with join. 
where a tax_id is xxx 
AND létszám is xxx or datum is somethin 
-- means that line is not executing

-- explain
SELECT ceg_id, letsz, rovat_0.adosz, nev, datum, tkod08 -- * 
FROM
  rovat_0
  join rovat_99003 using (ceg_id)
  join rovat_99018 using (ceg_id)
  join rovat_8     using (ceg_id)
where 
--   rovat_0.adosz like '11502583%%'
--   rovat_0.adosz like '1150%%'
--   rovat_99003.letsz ~ '^(1[1-5]|23)$' 
     rovat_99003.letsz ~ '^13..$'
 AND rovat_8.alrovat_id = 1
 AND left(coalesce(rovat_8.datum, ''), 4) = '2006'
 AND rovat_99018.tkod08 like '77%%'

* Select rovats and join by ceg_id by the help of with

-- explain
with
    all_firms as (select left(adosz, 8) taxid8, ceg_id from rovat_0),
    more_than_one_ceg as (select taxid8 from all_firms group by taxid8 having count(*) > 1),
    ignored_taxid8 as (select distinct taxid8 from more_than_one_ceg join all_firms using (taxid8) join rovat_93 using (ceg_id)),
    hirdetmeny as (select distinct taxid8 from more_than_one_ceg join all_firms using (taxid8) join rovat_99 using (ceg_id))

(select taxid8 from more_than_one_ceg) intersect (select taxid8 from hirdetmeny) except (select taxid8 from ignored_taxid8 ) 
limit 10
;
```

## Time machine tool

A tool for collapsing start and end dates and imputing missing dates.

<https://github.com/ceumicrodata/time-machine>

### Make a new environment to run the tool

```
virtualenv -p python3 env
. env/bin/activate
```

### Required files:

You need these .py files to your code folder to run the tool:

* timemachine.py&#x20;
* timemachine\_mp.py&#x20;
* timemachine\_tools.py&#x20;

### Required inputs:

* An entity resolved csv file. Example: complex rovat csv files with person IDs.
* Rovat 8 csv file, which contains the birth dates of firms.
* Frame, which contains the death date of firms in the death\_date column.

Usage: timemachine.py \[-h] \[-s START] \[-e END] \[-u] entity\_resolved rovat\_8 deaths order unique\_id is\_sorted fp out\_path

### Optional arguments:

* -h: Shows a help message and exits.
* -s START: Comma separated field preference list for start dates. e.g. hattol,valtk,bkelt. DEFAULT: hattol,valtk,bkelt,jogvk
* -e END: Comma separated field preference list for end dates. e.g. hatig,valtv,tkelt. DEFAULT: hatig,valtv,tkelt,jogvv
* -u: Unique flag. Should be used if only a single entry is valid at any given time.

### Positional arguments:

* entity\_resolved: The path to the entity resolved input csv file.
* rovat\_8: The path to the rovat 8 csv file.
* deaths: The path to the frame.
* order: A column of the entity resolved csv file describing the order of records within a firm. It is usually the alrovat\_id.
* unique\_id: A column of the entity resolved csv file which contains unique entity IDs. E.g.: person ID
* fp: A comma separated list of column labels in the entity resolved csv file describing the path to a single firm. It is usually ceg\_id.
* out\_path: Path where the output should be written.

### An example how to run time machine tool on the server

In this example we would like to clean the raw NACE input dates by ceg\_id:

```bash
$ python3 timemachine_mp.py -u temp/rovat_902_fortm_fotev.csv input/frame-20190508/frame_with_dates.csv alrovat_id teaor ceg_id temp/rovat_902_tm.csv 25
```

You can see the `-u` unique option means that we have one NACE main activity code at the same time. The unique column is the `teaor` and the code is using the `frame_with_dates.csv` which identify one frame\_id-tax\_id pair for each firm. The `25` means that we choose multiprocessing with maximum 25 cores.

> ### Key Points
>
> * Tools are helping you to automate tasks like joining unique ID-s for an input variable.
> * Firm name tool good for firm matching and PIR tool is good for state organizations matching


# How to work on server

This section provides an overview of the standard workflow and etiquette when working on the department's computational server.

## Connect to the server

Make sure you are connected to the CEU VPN server. The server only accepts connections from within CEU. You then have to proceed depending on whether you need a graphical or a command line interface.

### Establishing a CLI connection

You need an SSH connection. On Windows, you can use PuTTy. On UNIX systems you can use your terminal. Please check the [Server](https://handbook.microdata.io/onboarding/server) episode for details.

### Establishing a GUI session

You will need a VNC connection or X11 forwarding. On Windows you should use a VNC client. On Mac, you can use XQuartz. On Ubuntu you do not have to install any additional tool. Check the [Server](https://handbook.microdata.io/onboarding/server) episode for details on starting your connection.

## Starting a screen

If you are connected to the server via VNC, you do not need to start a screen. In any other case it is highly recommended to start a screen. This allows you to continue from where you left off later on in case you decide to halt your work or if you get disconnected from the server for any reason. Without a screen you will lose all unsaved progress and all the processes you started will terminate as soon as you close or lose connection to the server.

## Work at the proper location

You shall not work in your home folder. Please always navigate to the proper sandbox or project folder before beginning your work. For the basic architecture of the server, please check the Server]\(<https://handbook.microdata.io/onboarding/server>) episode.

## Work in virtual environments

You must not install any packages directly on the server. Trying to install outside a virtual environment will fail as soon as you reach your home folder quota. You can create virtual environments or move the temp folders of the software you use to your sandbox. In case of any issue contact a project manager.

## Running jobs

UNIX terminal and XQuartz users can start batch jobs and initiate interactive sessions using the command-line. Windows users can use PuTTy or open a terminal in their VNC client to start batch jobs. Interactive sessions can be initiated in the VNC client.

## Check your footprint

Always check the resources you use via `htop`. If your process has a memory/CPU requirement that would interfere with the daily workflow of other users please schedule your process to run outside working hours or during the weekend.

## Clean up

Before disconnecting always make sure that you do not have any leftover sessions using resources (unless you are running a longer process within a screen). Remove unused virtual environments, zap unused bead workspaces, close software instances with data in memory, etc.

## Close your connection

Exit the server by pressing `Ctrl + D` or type the `exit` command in your CLI.

## Inform others

Use Slack to communicate any planned and persistent server use with a heavy footprint so that other users can plan accordingly.

## Get help

You can always get help by revisiting this handbook. If you cannot find the answers you are looking for, ask a project manager. Remember: if you are unsure, it is better to ask before you act.


# PostgreSQL


# Make

This page provides a simple introduction to using make. Most of this page is based on https\://github.com/theicfire/makefiletutorial with modifications specific to MicroData.

## Getting Started <a href="#getting-started" id="getting-started"></a>

### Why do we need Makefiles? <a href="#why-do-makefiles-exist" id="why-do-makefiles-exist"></a>

Makefiles are used to help decide which parts of a large program need to be recompiled. In a data-intensive project it can be helpful in determining which data transformations or analysis codes need to be re-run due to a change. In general terms, it can be used when you need a series of instructions to run depending on what files have changed. This tutorial will focus on the data analysis use case.

Here's an example dependency graph that you might build with Make. If any file's list of dependencies changes, then the file will get re-created:

![An example of a data-intensive project](/files/-MVWybhswaJBt9jeBrDJ)

### Running the Examples <a href="#running-the-examples" id="running-the-examples"></a>

To run these examples, you'll need a terminal and "make" installed. For each example, put the contents in a file called `Makefile`, and in that directory run the command `make`. Let's start with the simplest of Makefiles:

```bash
hello:
    echo "hello world"
```

Here is the output of running the above example:

```bash
$ make
echo "hello world"
hello world
```

That's it!&#x20;

### Makefile Syntax <a href="#makefile-syntax" id="makefile-syntax"></a>

A Makefile consists of a set of *rules*. A rule generally looks like this:

```
targets: prerequisites
   command
   command
   command
```

* The *targets* are file names, separated by spaces. Typically, there is only one per rule.
* The *commands* are a series of steps typically used to make the target(s). These *need to start with a tab character*, not spaces.
* The *prerequisites* are also file names, separated by spaces. These files need to exist before the commands for the target are run. These are also called *dependencies*

### Beginner Examples <a href="#beginner-examples" id="beginner-examples"></a>

The following Makefile has three separate *rules*. When you run `make sample.csv` in the terminal, it will create a dataset called sample.csv in a series of steps:

* Make is given `sample.csv` as the target, so it first searches for this target
* `sample.csv` requires `consistent.csv`, so make searches for the `consistent.csv` target
* `consistent.csv` requires `source.csv`, so make searches for the `source.csv` target
* `source.csv` has no dependencies, so the `test` command is run
* The `python` command is then run, because all of the `consistent.csv` dependencies are finished
* The top `stata` command is run, because all the `sample.csv` dependencies are finished
* That's it: `sample.csv` is our last dataset to create.

```
sample.csv: consistent.csv
    stata -b create_sample.do # Runs third

consistent.csv: source.csv
    python clean_data.py # Runs second

source.csv:
    test -f source.csv && echo "$FILE exists." # Runs first
```

This makefile has a single target, called `some_file`. The default target is the first target, so in this case `some_file` will run. Notice that the command below does not create any actual file, it is a simple `echo` command.

```
some_file:
    echo "This line will always print"
```

This file will make `some_file`, which is an actual file in this case. The first time we run this code the file `some_file` will be created. The second time you try to make it - since it's already made and the dependencies did not change - it will result in `make: 'some_file' is up to date.`

```
some_file:
    echo "This line will only print once"
    touch some_file
```

Here, the target `some_file` "depends" on `other_file`. When we run `make`, the default target (`some_file`, since it's first) will get called. It will first look at its list of *dependencies*, and if any of them are older, it will first run the targets for those dependencies, and then run itself. The second time this is run, neither target will run because both targets exist.

```
some_file: other_file
    echo "This will run second, because it depends on other_file"
    touch some_file

other_file:
    echo "This will run first"
    touch other_file
```

This will always run both targets, because `some_file` depends on `other_file`, which is never created.

```
some_file: other_file
    touch some_file

other_file:
    echo "nothing"
```

`clean` is often used as a target that removes the output of other targets, but it is not a special word in `make`.

```
some_file: 
    touch some_file

clean:
    rm -f some_file
```

### Variables <a href="#variables" id="variables"></a>

Variables can only be strings. Here's an example of using them:

```
files = file1 file2
some_file: $(files)
    echo "Look at this variable: " $(files)
    touch some_file

file1:
    touch file1
file2:
    touch file2

clean:
    rm -f file1 file2 some_file
```

You can reference variables using `${}` or `$().`

```
x = dude

all:
    echo $(x)
    echo ${x}

    # Bad practice, but works
    echo $x
```

## Targets <a href="#targets" id="targets"></a>

### The all target <a href="#the-all-target" id="the-all-target"></a>

Making multiple targets and you want all of them to run? Make an `all` target.

```
all: one two three

one:
    touch one
two:
    touch two
three:
    touch three

clean:
    rm -f one two three
```

### Multiple targets <a href="#multiple-targets" id="multiple-targets"></a>

When there are multiple targets for a rule, the commands will be run for each target\
`$@` is an automatic variable that contains the target name.

```
all: file1 file2

file1 file2:
    echo $@
# Equivalent to:
# file1
#     echo $@
# file2
#     echo $@
```

## Automatic Variables and Wildcards <a href="#automatic-variables-and-wildcards" id="automatic-variables-and-wildcards"></a>

### \* Wildcard <a href="#wildcard" id="wildcard"></a>

Both `*` and `%` are called wildcards in Make, but they mean entirely different things. `*` searches your filesystem for matching filenames. I suggest that you always wrap it in the `wildcard` function, because otherwise you may fall into a common pitfall described below. It's oddly unhelpful and I find it more confusing than useful.

```
# Print out file information about every .csv file
print: $(wildcard *.csv)
    ls -la  $?
```

`*` may be used in the target, prerequisites, or in the `wildcard` function.

Danger: `*` may not be directly used in variable definitions

Danger: When `*` matches no files, it is left as it is (unless run in the `wildcard` function)

```
thing_wrong := *.csv # Don't do this! '*' will not get expanded
thing_right := $(wildcard *.csv)

all: one two three four

# Fails, because $(thing_wrong) is the string "*.csv"
one: $(thing_wrong)

# Stays as *.csv if there are no files that match this pattern :(
two: *.o 

# Works as you would expect! In this case, it does nothing.
three: $(thing_right)

# Same as rule three
four: $(wildcard *.csv)
```

### % Wildcard <a href="#wildcard" id="wildcard"></a>

`%` is really useful, but is somewhat confusing because of the variety of situations it can be used in.

* When used in "matching" mode, it matches one or more characters in a string. This match is called the stem.
* When used in "replacing" mode, it takes the stem that was matched and replaces that in a string.
* `%` is most often used in rule definitions and in some specific functions.

See these sections on examples of it being used:

* Static Pattern Rules
* Pattern Rules
* String Substitution
* The vpath Directive

### Automatic Variables <a href="#automatic-variables" id="automatic-variables"></a>

There are many [automatic variables](https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html), but often only a few show up:

```
hey: one two
    # Outputs "hey", since this is the first target
    echo $@

    # Outputs all prerequisites newer than the target
    echo $?

    # Outputs all prerequisites
    echo $^

    touch hey

one:
    touch one

two:
    touch two

clean:
    rm -f hey one two
```

## Fancy Rules <a href="#fancy-rules" id="fancy-rules"></a>

### Static Pattern Rules <a href="#static-pattern-rules" id="static-pattern-rules"></a>

Make loves c compilation. And every time it expresses its love, things get confusing. Here's the syntax for a new type of rule called a static pattern:

```
targets ...: target-pattern: prereq-patterns ...
   commands
```

The essence is that the given target is matched by the target-pattern (via a `%` wildcard). Whatever was matched is called the *stem*. The stem is then substituted into the prereq-pattern, to generate the target's prereqs.

A typical use case is to compile `.c` files into `.o` files. Here's the *manual way*:

```
objects = foo.o bar.o all.o
all: $(objects)

# These files compile via implicit rules
foo.o: foo.c
bar.o: bar.c
all.o: all.c

all.c:
    echo "int main() { return 0; }" > all.c

%.c:
    touch $@

clean:
    rm -f *.c *.o all
```

Here's the more *efficient way*, using a static pattern rule:

```
objects = foo.o bar.o all.o
all: $(objects)

# These files compile via implicit rules
# Syntax - targets ...: target-pattern: prereq-patterns ...
# In the case of the first target, foo.o, the target-pattern matches foo.o and sets the "stem" to be "foo".
# It then replaces the '%' in prereq-patterns with that stem
$(objects): %.o: %.c

all.c:
    echo "int main() { return 0; }" > all.c

%.c:
    touch $@

clean:
    rm -f *.c *.o all
```

### Static Pattern Rules and Filter <a href="#static-pattern-rules-and-filter" id="static-pattern-rules-and-filter"></a>

While I introduce functions later on, I'll forshadow what you can do with them. The `filter` function can be used in Static pattern rules to match the correct files. In this example, I made up the `.raw` and `.result` extensions.

```
obj_files = foo.result bar.o lose.o
src_files = foo.raw bar.c lose.c

all: $(obj_files)

$(filter %.o,$(obj_files)): %.o: %.c
    echo "target: $@ prereq: $<"
$(filter %.result,$(obj_files)): %.result: %.raw
    echo "target: $@ prereq: $<" 

%.c %.raw:
    touch $@

clean:
    rm -f $(src_files)
```

### Implicit Rules <a href="#implicit-rules" id="implicit-rules"></a>

Perhaps the most confusing part of make is the magic rules and variables that are made. Here's a list of implicit rules:

* Compiling a C program: `n.o` is made automatically from `n.c` with a command of the form `$(CC) -c $(CPPFLAGS) $(CFLAGS)`
* Compiling a C++ program: `n.o` is made automatically from `n.cc` or `n.cpp` with a command of the form `$(CXX) -c $(CPPFLAGS) $(CXXFLAGS)`
* Linking a single object file: `n` is made automatically from `n.o` by running the command `$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)`

As such, the important variables used by implicit rules are:

* `CC`: Program for compiling C programs; default cc
* `CXX`: Program for compiling C++ programs; default G++
* `CFLAGS`: Extra flags to give to the C compiler
* `CXXFLAGS`: Extra flags to give to the C++ compiler
* `CPPFLAGS`: Extra flags to give to the C preprosessor
* `LDFLAGS`: Extra flags to give to compilers when they are supposed to invoke the linker

```
CC = gcc # Flag for implicit rules
CFLAGS = -g # Flag for implicit rules. Turn on debug info

# Implicit rule #1: blah is built via the C linker implicit rule
# Implicit rule #2: blah.o is built via the C compilation implicit rule, because blah.c exists
blah: blah.o

blah.c:
    echo "int main() { return 0; }" > blah.c

clean:
    rm -f blah*
```

### Pattern Rules <a href="#pattern-rules" id="pattern-rules"></a>

Pattern rules are often used but quite confusing. You can look at them as two ways:

* A way to define your own implicit rules
* A simpler form of static pattern rules

Let's start with an example first:

```
# Define a pattern rule that compiles every .c file into a .o file
%.o : %.c
        $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
```

Pattern rules contain a '%' in the target. This '%' matches any nonempty string, and the other characters match themselves. ‘%’ in a prerequisite of a pattern rule stands for the same stem that was matched by the ‘%’ in the target.

Here's another example:

```
# Define a pattern rule that has no pattern in the prerequisites.
# This just creates empty .c files when needed.
%.c:
   touch $@
```

### Double-Colon Rules <a href="#double-colon-rules" id="double-colon-rules"></a>

Double-Colon Rules are rarely used, but allow multiple rules to be defined for the same target. If these were single colons, a warning would be printed and only the second set of commands would run.

```
all: blah

blah::
    echo "hello"

blah::
    echo "hello again"
```

## Commands and execution <a href="#commands-and-execution" id="commands-and-execution"></a>

### Command Echoing/Silencing <a href="#command-echoing-silencing" id="command-echoing-silencing"></a>

Add an `@` before a command to stop it from being printed\
You can also run make with `-s` to add an `@` before each line

```
all: 
    @echo "This make line will not be printed"
    echo "But this will"
```

### Command Execution <a href="#command-execution" id="command-execution"></a>

Each command is run in a new shell (or at least the effect is as such)

```
all: 
    cd ..
    # The cd above does not affect this line, because each command is effectively run in a new shell
    echo `pwd`

    # This cd command affects the next because they are on the same line
    cd ..;echo `pwd`

    # Same as above
    cd ..; \
    echo `pwd`
```

### Default Shell <a href="#default-shell" id="default-shell"></a>

The default shell is `/bin/sh`. You can change this by changing the variable SHELL:

```
SHELL=/bin/bash

cool:
    echo "Hello from bash"
```

### Error handling with `-k`, `-i`, and `-` <a href="#error-handling-with-k-i-and" id="error-handling-with-k-i-and"></a>

Add `-k` when running make to continue running even in the face of errors. Helpful if you want to see all the errors of Make at once.\
Add a `-` before a command to suppress the error\
Add `-i` to make to have this happen for every command.

```
one:
    # This error will be printed but ignored, and make will continue to run
    -false
    touch one
```

### Interrupting or killing make <a href="#interrupting-or-killing-make" id="interrupting-or-killing-make"></a>

Note only: If you `ctrl+c` make, it will delete the newer targets it just made.

### Recursive use of make <a href="#recursive-use-of-make" id="recursive-use-of-make"></a>

To recursively call a makefile, use the special `$(MAKE)` instead of `make` because it will pass the make flags for you and won't itself be affected by them.

```
new_contents = "hello:\n\ttouch inside_file"
all:
    mkdir -p subdir
    printf $(new_contents) | sed -e 's/^ //' > subdir/makefile
    cd subdir && $(MAKE)

clean:
    rm -rf subdir
```

### Use export for recursive make <a href="#use-export-for-recursive-make" id="use-export-for-recursive-make"></a>

The export directive takes a variable and makes it accessible to sub-make commands. In this example, `cooly` is exported such that the makefile in subdir can use it.

Note: export has the same syntax as sh, but they aren't related (although similar in function)

```
new_contents = "hello:\n\\techo \$$(cooly)"

all:
    mkdir -p subdir
    echo $(new_contents) | sed -e 's/^ //' > subdir/makefile
    @echo "---MAKEFILE CONTENTS---"
    @cd subdir && cat makefile
    @echo "---END MAKEFILE CONTENTS---"
    cd subdir && $(MAKE)

# Note that variables and exports. They are set/affected globally.
cooly = "The subdirectory can see me!"
export cooly
# This would nullify the line above: unexport cooly

clean:
    rm -rf subdir
```

You need to export variables to have them run in the shell as well.

```
one=this will only work locally
export two=we can run subcommands with this

all: 
    @echo $(one)
    @echo $$one
    @echo $(two)
    @echo $$two
```

`.EXPORT_ALL_VARIABLES` exports all variables for you.

```
.EXPORT_ALL_VARIABLES:
new_contents = "hello:\n\techo \$$(cooly)"

cooly = "The subdirectory can see me!"
# This would nullify the line above: unexport cooly

all:
    mkdir -p subdir
    echo $(new_contents) | sed -e 's/^ //' > subdir/makefile
    @echo "---MAKEFILE CONTENTS---"
    @cd subdir && cat makefile
    @echo "---END MAKEFILE CONTENTS---"
    cd subdir && $(MAKE)

clean:
    rm -rf subdir
```

### Arguments to make <a href="#arguments-to-make" id="arguments-to-make"></a>

There's a nice [list of options](http://www.gnu.org/software/make/manual/make.html#Options-Summary) that can be run from make. Check out `--dry-run`, `--touch`, `--old-file`.

You can have multiple targets to make, i.e. `make clean run test` runs the `clean` goal, then `run`, and then `test`.

## Variables Pt. 2 <a href="#variables-pt-2" id="variables-pt-2"></a>

### Flavors and modification <a href="#flavors-and-modification" id="flavors-and-modification"></a>

There are two flavors of variables:

* recursive (use `=`) - only looks for the variables when the command is *used*, not when it's *defined*.
* simply expanded (use `:=`) - like normal imperative programming -- only those defined so far get expanded

```
# Recursive variable. This will print "later" below
one = one ${later_variable}
# Simply expanded variable. This will not print "later" below
two := two ${later_variable}

later_variable = later

all: 
    echo $(one)
    echo $(two)
```

Simply expanded (using `:=`) allows you to append to a variable. Recursive definitions will give an infinite loop error.

```
one = hello
# one gets defined as a simply expanded variable (:=) and thus can handle appending
one := ${one} there

all: 
    echo $(one)
```

`?=` only sets variables if they have not yet been set

```
one = hello
one ?= will not be set
two ?= will be set

all: 
    echo $(one)
    echo $(two)
```

Spaces at the end of a line are not stripped, but those at the start are. To make a variable with a single space, use `$(nullstring)`

```
with_spaces = hello   # with_spaces has many spaces after "hello"
after = $(with_spaces)there

nullstring =
space = $(nullstring) # Make a variable with a single space.

all: 
    echo "$(after)"
    echo start"$(space)"end
```

An undefined variable is actually an empty string!

```
all: 
    # Undefined variables are just empty strings!
    echo $(nowhere)
```

Use `+=` to append

```
foo := start
foo += more

all: 
    echo $(foo)
```

[String Substitution](https://makefiletutorial.com/#string-substitution) is also a really common and useful way to modify variables. Also check out [Text Functions](https://www.gnu.org/software/make/manual/html_node/Text-Functions.html#Text-Functions) and [Filename Functions](https://www.gnu.org/software/make/manual/html_node/File-Name-Functions.html#File-Name-Functions).

### Command line arguments and override <a href="#command-line-arguments-and-override" id="command-line-arguments-and-override"></a>

You can override variables that come from the command line by using `override`. Here we ran make with `make option_one=hi`

```
# Overrides command line arguments
override option_one = did_override
# Does not override command line arguments
option_two = not_override
all: 
    echo $(option_one)
    echo $(option_two)
```

### List of commands and define <a href="#list-of-commands-and-define" id="list-of-commands-and-define"></a>

"define" is actually just a list of commands. It has nothing to do with being a function. Note here that it's a bit different than having a semi-colon between commands, because each is run in a separate shell, as expected.

```
one = export blah="I was set!"; echo $$blah

define two
export blah=set
echo $$blah
endef

# One and two are different.

all: 
    @echo "This prints 'I was set'"
    @$(one)
    @echo "This does not print 'I was set' because each command runs in a separate shell"
    @$(two)
```

### Target-specific variables <a href="#target-specific-variables" id="target-specific-variables"></a>

Variables can be assigned for specific targets

```
all: one = cool

all: 
    echo one is defined: $(one)

other:
    echo one is nothing: $(one)
```

### Pattern-specific variables <a href="#pattern-specific-variables" id="pattern-specific-variables"></a>

You can assign variables for specific target *patterns*

```
%.c: one = cool

blah.c: 
    echo one is defined: $(one)

other:
    echo one is nothing: $(one)
```

## Conditional part of Makefiles <a href="#conditional-part-of-makefiles" id="conditional-part-of-makefiles"></a>

### Conditional if/else <a href="#conditional-if-else" id="conditional-if-else"></a>

```
foo = ok

all:
ifeq ($(foo), ok)
    echo "foo equals ok"
else
    echo "nope"
endif
```

### Check if a variable is empty <a href="#check-if-a-variable-is-empty" id="check-if-a-variable-is-empty"></a>

```
nullstring =
foo = $(nullstring) # end of line; there is a space here

all:
ifeq ($(strip $(foo)),)
    echo "foo is empty after being stripped"
endif
ifeq ($(nullstring),)
    echo "nullstring doesn't even have spaces"
endif
```

### Check if a variable is defined <a href="#check-if-a-variable-is-defined" id="check-if-a-variable-is-defined"></a>

ifdef does not expand variable references; it just sees if something is defined at all

```
bar =
foo = $(bar)

all:
ifdef foo
    echo "foo is defined"
endif
ifdef bar
    echo "but bar is not"
endif
```

### $(makeflags) <a href="#makeflags" id="makeflags"></a>

This example shows you how to test make flags with `findstring` and `MAKEFLAGS`. Run this example with `make -i` to see it print out the echo statement.

```
bar =
foo = $(bar)

all:
# Search for the "-i" flag. MAKEFLAGS is just a list of single characters, one per flag. So look for "i" in this case.
ifneq (,$(findstring i, $(MAKEFLAGS)))
    echo "i was passed to MAKEFLAGS"
endif
```

## Functions <a href="#functions" id="functions"></a>

### First Functions <a href="#first-functions" id="first-functions"></a>

*Functions* are mainly just for text processing. Call functions with `$(fn, arguments)` or `${fn, arguments}`. You can make your own using the [call](https://www.gnu.org/software/make/manual/html_node/Call-Function.html#Call-Function) builtin function. Make has a decent amount of [builtin functions](https://www.gnu.org/software/make/manual/html_node/Functions.html).

```
bar := ${subst not, totally, "I am not superman"}
all: 
    @echo $(bar)
```

If you want to replace spaces or commas, use variables

```
comma := ,
empty:=
space := $(empty) $(empty)
foo := a b c
bar := $(subst $(space),$(comma),$(foo))

all: 
    @echo $(bar)
```

Do NOT include spaces in the arguments after the first. That will be seen as part of the string.

```
comma := ,
empty:=
space := $(empty) $(empty)
foo := a b c
bar := $(subst $(space), $(comma) , $(foo))

all: 
    # Output is ", a , b , c". Notice the spaces introduced
    @echo $(bar)
```

### String Substitution <a href="#string-substitution" id="string-substitution"></a>

`$(patsubst pattern,replacement,text)` does the following:

"Finds whitespace-separated words in text that match pattern and replaces them with replacement. Here pattern may contain a ‘%’ which acts as a wildcard, matching any number of any characters within a word. If replacement also contains a ‘%’, the ‘%’ is replaced by the text that matched the ‘%’ in pattern. Only the first ‘%’ in the pattern and replacement is treated this way; any subsequent ‘%’ is unchanged." ([GNU docs](https://www.gnu.org/software/make/manual/html_node/Text-Functions.html#Text-Functions))

The substitution reference `$(text:pattern=replacement)` is a shorthand for this.

There's another shorthand that that replaces only suffixes: `$(text:suffix=replacement)`. No `%` wildcard is used here.

Note: don't add extra spaces for this shorthand. It will be seen as a search or replacement term.

```
foo := a.o b.o l.a c.o
one := $(patsubst %.o,%.c,$(foo))
# This is a shorthand for the above
two := $(foo:%.o=%.c)
# This is the suffix-only shorthand, and is also equivalent to the above.
three := $(foo:.o=.c)

all:
    echo $(one)
    echo $(two)
    echo $(three)
```

### The foreach function <a href="#the-foreach-function" id="the-foreach-function"></a>

The foreach function looks like this: `$(foreach var,list,text)`. It converts one list of words (separated by spaces) to another. `var` is set to each word in list, and `text` is expanded for each word.\
This appends an exclamation after each word:

```
foo := who are you
# For each "word" in foo, output that same word with an exclamation after
bar := $(foreach wrd,$(foo),$(wrd)!)

all:
    # Output is "who! are! you!"
    @echo $(bar)
```

### The if function <a href="#the-if-function" id="the-if-function"></a>

`if` checks if the first argument is nonempty. If so runs the second argument, otherwise runs the third.

```
foo := $(if this-is-not-empty,then!,else!)
empty :=
bar := $(if $(empty),then!,else!)

all:
    @echo $(foo)
    @echo $(bar)
```

### The call function <a href="#the-call-function" id="the-call-function"></a>

Make supports creating basic functions. You "define" the function just by creating a variable, but use the parameters `$(0)`, `$(1)`, etc. You then call the function with the special `call` function. The syntax is `$(call variable,param,param)`. `$(0)` is the variable, while `$(1)`, `$(2)`, etc. are the params.

```
sweet_new_fn = Variable Name: $(0) First: $(1) Second: $(2) Empty Variable: $(3)

all:
    # Outputs "Variable Name: sweet_new_fn First: go Second: tigers Empty Variable:"
    @echo $(call sweet_new_fn, go, tigers)
```

### The shell function <a href="#the-shell-function" id="the-shell-function"></a>

shell - This calls the shell, but it replaces newlines with spaces!

```
all: 
    @echo $(shell ls -la) # Very ugly because the newlines are gone!
```

## Other Features <a href="#other-features" id="other-features"></a>

### Include Makefiles <a href="#include-makefiles" id="include-makefiles"></a>

The include directive tells make to read one or more other makefiles. It's a line in the makefile makefile that looks like this:

```
include filenames...
```

This is particularly useful when you use compiler flags like `-M` that create Makefiles based on the source. For example, if some c files includes a header, that header will be added to a Makefile that's written by gcc. I talk about this more in the [Makefile Cookbook](https://makefiletutorial.com/#makefile-cookbook)

### The vpath Directive <a href="#the-vpath-directive" id="the-vpath-directive"></a>

Use vpath to specify where some set of prerequisites exist. The format is `vpath <pattern> <directories, space/colon separated>`\
`<pattern>` can have a `%`, which matches any zero or more characters.\
You can also do this globallyish with the variable VPATH

```
vpath %.h ../headers ../other-directory

some_binary: ../headers blah.h
    touch some_binary

../headers:
    mkdir ../headers

blah.h:
    touch ../headers/blah.h

clean:
    rm -rf ../headers
    rm -f some_binary
```

### Multiline <a href="#multiline" id="multiline"></a>

The backslash ("\\") character gives us the ability to use multiple lines when the commands are too long

```
some_file: 
    echo This line is too long, so \
        it is broken up into multiple lines
```

### .phony <a href="#phony" id="phony"></a>

Adding `.PHONY` to a target will prevent make from confusing the phony target with a file name. In this example, if the file `clean` is created, make clean will still be run. `.PHONY` is great to use, but I'll skip it in the rest of the examples for simplicity.

```
some_file:
    touch some_file
    touch clean

.PHONY: clean
clean:
    rm -f some_file
    rm -f clean
```

### .delete\_on\_error <a href="#delete_on_error" id="delete_on_error"></a>

The make tool will stop running a rule (and will propogate back to prerequisites) if a command returns a nonzero exit status.\
`DELETE_ON_ERROR` will delete the target of a rule if the rule fails in this manner. This will happen for all targets, not just the one it is before like PHONY. It's a good idea to always use this, even though make does not for historical reasons.

```
.DELETE_ON_ERROR:
all: one two

one:
    touch one
    false

two:
    touch two
    false
```

## Makefile Cookbook <a href="#makefile-cookbook" id="makefile-cookbook"></a>

Let's go through a really juicy Make example that works well for medium sized projects.

The neat thing about this makefile is it automatically determines dependencies for you. All you have to do is put your C/C++ files in the `src/` folder.

```
# Thanks to Job Vranish (https://spin.atomicobject.com/2016/08/26/makefile-c-projects/)
TARGET_EXEC := final_program

BUILD_DIR := ./build
SRC_DIRS := ./src

# Find all the C and C++ files we want to compile
SRCS := $(shell find $(SRC_DIRS) -name *.cpp -or -name *.c)

# String substitution for every C/C++ file.
# As an example, hello.cpp turns into ./build/hello.cpp.o
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)

# String substitution (suffix version without %).
# As an example, ./build/hello.cpp.o turns into ./build/hello.cpp.d
DEPS := $(OBJS:.o=.d)

# Every folder in ./src will need to be passed to GCC so that it can find header files
INC_DIRS := $(shell find $(SRC_DIRS) -type d)
# Add a prefix to INC_DIRS. So moduleA would become -ImoduleA. GCC understands this -I flag
INC_FLAGS := $(addprefix -I,$(INC_DIRS))

# The -MMD and -MP flags together generate Makefiles for us!
# These files will have .d instead of .o as the output.
CPPFLAGS := $(INC_FLAGS) -MMD -MP

# The final build step.
$(BUILD_DIR)/$(TARGET_EXEC): $(OBJS)
    $(CC) $(OBJS) -o $@ $(LDFLAGS)

# Build step for C source
$(BUILD_DIR)/%.c.o: %.c
    mkdir -p $(dir $@)
    $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@

# Build step for C++ source
$(BUILD_DIR)/%.cpp.o: %.cpp
    mkdir -p $(dir $@)
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@


.PHONY: clean
clean:
    rm -r $(BUILD_DIR)

# Include the .d makefiles. The - at the front suppresses the errors of missing
# Makefiles. Initially, all the .d files will be missing, and we don't want those
# errors to show up.
-include $(DEPS)
```


# Make in Windows

Description of how to install and use Make in Windows OS.

## Installation

There are several ways to install Make on Windows. In this tutorial we will use Git Bash because it is also needed for [Git ](/onboarding/git-and-github)on Windows, so you might already have that if you followed the steps in [Onboarding](/onboarding/checklist). The steps follow the instructions detailed [here](https://gist.github.com/evanwill/0207876c3243bbb6863e65ec5dc3f058). After installing Git & Git Bash:

* Go to [ezwinports](https://sourceforge.net/projects/ezwinports/files/).
* Download `make-4.4-without-guile-w32-bin.zip` (get the version without guile).
* Extract zip.
* Copy the contents to your `C:\Program Files\Git\mingw64\` merging the folders, but do NOT overwrite/replace any existing files.

## Using Makefiles in different environments

Commands are called differently in different environments, for example, if you want to run Stata in Git Bash terminal on Windows you should use `StataMP-64`, but `stata` on Mac and Linux. Aliases don't work well in our setting (as Make is run in Git Bash, but Make itself uses the sh shell). Although if you include an operation system detector part at the beginning of your Makefile, it provides a simple solution for a reproducible Makefile in different environments.&#x20;

Let's create a project folder called `trial/`, where the codes can be run with a Makefile both on Windows and Mac or Linux. There should be 2 files in the folder: `trial.do` and `Makefile`. The `trial.do` creates a `trial.log` just to see and check whether Make runs correctly. The content of `trail.do` is the following:

```
capture log close
log using "trial.log", replace text
disp "DateTime: $S_DATE $S_TIME"
log close
```

You can copy the following content in your `Makefile`:

```
#OS detector part
ifeq ($(OS),Windows_NT) # is Windows_NT on XP, 2000, 7, Vista, 10... STATA := StataMP-64 else STATA := stata endif

#Code starts here
trial.log: trial.do $(STATA) -e do $<
```

When you finished, open the Git Bash terminal, go to the `trial/` folder where the `trail.do` and your `Makefile` is, and then run `make`.

```
$ cd ~/.../trial/
$ ls
  trial.do
  Makefile
$ make
```

Afterward, you should see the `trial.log` created by the `Makefile`.


# Julia

## Julia startup and install

[Julia](https://julialang.org/) is a high-level, general-purpose dynamic programming language, still designed to be fast and productive, for e.g. data science, artificial intelligence, machine learning, modeling and simulation, most commonly used for numerical analysis and computational science.

Recomended to start Julia from your haflinger workspace.

You can start Julia from VNC terminal or VS code terminal or by ssh connection by:

`julia`

or even better to start as `julia --project` [Julia CML](https://docs.julialang.org/en/v1/manual/command-line-interface/)

You can install Julia extensions:

`]` and `pkg>add Kezdi`

Julia Help:

`?`

Julia shell commands:

`;`

[Julia documentation](https://docs.julialang.org/en/v1/)

If you log in to you CEU account you can find basic tutorials with [Julia LinkedinLearning](https://www.linkedin.com/learning/learning-julia?u=139332290)

### Recomended extensions for server usage:

[Kezdi.jl](https://github.com/codedthinking/Kezdi.jl) is a Julia package that provides a Stata-like interface for data manipulation and analysis. It is designed to be easy to use for Stata users who are transitioning to Julia.1

[IJulia](https://github.com/JuliaLang/IJulia.jl) is a Julia-language backend combined with the Jupyter interactive environment (also used by IPython).


# Jupyter Notebook

## Jupyter Notebook

Log in to your work folder by VS code terminal.

Create a python3 env:

`virtualenv -p python3 env`

Activate it:

`. env/bin/activate`

Install your python commands and tools inside the env:

`pip install jupyter notebook`

Run jupyter notebook:

`jupyter notebook`

Click on the localhost link starting like: `http://localhost:8891/tree?token=ef69a1ea99a1377dc2bf783ecec2420d90fdc9b0593f1707`

[Jupyter notebook docs](https://docs.jupyter.org/en/latest/running.html)

If you want to use Jupyter Notebook with Julia Kernel install [IJulia](https://github.com/JuliaLang/IJulia.jl) on the haflinger.


# Csvkit

How to use csvkit

> ### Overview
>
> Questions
>
> * How to open data with csvkit?
> * How to select certain rows and columns of the data? How to append them after filtering?
> * How to sort and describe basic characteristics of the data?
>
> Objectives
>
> * Learn how to install csvkit and how to use csvlook
> * Learn csvgrep, csvcut and csvstack commands
> * Learn csvsort and csvstat commands

## The use of csvkit

csvkit is a command-line tool written in Python to be used for simple data wrangling and analysis tasks. This tutorial presents the most important commands implemented in it. The following sections rely heavily on the official csvkit [tutorial](https://csvkit.readthedocs.io/en/1.0.5/tutorial.html).

## Installing csvkit

The csvkit tool can be installed with the following command (if you use Python 2.7 you might type `sudo pip install csvkit` instead).

```bash
$ sudo pip3 install csvkit
```

For illustration purposes an example [dataset](https://perso.telecom-paristech.fr/eagan/class/igr204/datasets) is also used in this tutorial. The data contain information on cars and their characteristics. To get the data you should type the following command. The dataset has a second row with information on data type that is removed for later analysis purposes with the head and tail commands - an alternative way to do this is by using `sed 2,2d cars.csv > cars-tutorial.csv`.

```bash
$ wget https://perso.telecom-paristech.fr/eagan/class/igr204/data/cars.csv
$ head -1 cars.csv > cars-tutorial.csv
$ tail -n+3 cars.csv >> cars-tutorial.csv
```

## The most important csvkit commands

The example dataset is semi-colon and not comma separated. For all the commands presented below the input delimiter can be set with the `-d` argument: in this case as -`d ";"`. Setting the input delimiter with `-d` changes the decimal separator in the ouput as well. To change it back to dot from comma, `csvformat -D "."` should be used after any command where it is relevant.

* `csvlook` shows the data in a Markdown-compatible format. `cat` may also be used instead of `csvlook` to open a csv file, but the latter is more readable. This command can be combined with `head` in order to have a look at the first few lines of the data. As seen here and in later examples, csvkit commands can be piped together and with other commands. For the latter command the following output can be seen.

{% tabs %}
{% tab title="Bash" %}

```bash
$ csvlook -d ";" cars-tutorial.csv | csvformat -D "."
$ head -5 cars-tutorial.csv | csvlook -d ";" | csvformat -D "."
```

{% endtab %}

{% tab title="Output" %}

```
| Car                       | MPG | Cylinders | Displacement | Horsepower | Weight | Acceleration | Model | Origin |
| ------------------------- | --- | --------- | ------------ | ---------- | ------ | ------------ | ----- | ------ |
| Chevrolet Chevelle Malibu |  18 |         8 |          307 |        130 |  3 504 |         12.0 |    70 | US     |
| Buick Skylark 320         |  15 |         8 |          350 |        165 |  3 693 |         11.5 |    70 | US     |
| Plymouth Satellite        |  18 |         8 |          318 |        150 |  3 436 |         11.0 |    70 | US     |
| AMC Rebel SST             |  16 |         8 |          304 |        150 |  3 433 |         12.0 |    70 | US     |

```

{% endtab %}
{% endtabs %}

* `csvcut` shows the column names in the data if the `-n` argument is specified. It can also help to select certain columns of the data with the `-c` argument and the corresponding column numbers (or names). The code and output is the following:

{% tabs %}
{% tab title="Bash" %}

```bash
$ csvcut -n -d ";" cars-tutorial.csv
```

{% endtab %}

{% tab title="Output" %}

```
1: Car
2: MPG
3: Cylinders
4: Displacement
5: Horsepower
6: Weight
7: Acceleration
8: Model
9: Origin
```

{% endtab %}
{% endtabs %}

The following two commands have identical outputs: car, miles per gallon consumption and origin columns, as shown below. For space constraints only the first few rows are printed out.

{% tabs %}
{% tab title="Bash" %}

```bash
$ csvcut -c 1,2,9 -d ";" cars-tutorial.csv | head -5 | csvlook
$ csvcut -c Car,MPG,Origin -d ";" cars-tutorial.csv | head -5 | csvlook
```

{% endtab %}

{% tab title="Output" %}

```
| Car                       | MPG | Origin |
| ------------------------- | --- | ------ |
| Chevrolet Chevelle Malibu |  18 | US     |
| Buick Skylark 320         |  15 | US     |
| Plymouth Satellite        |  18 | US     |
| AMC Rebel SST             |  16 | US     |
```

{% endtab %}
{% endtabs %}

* `csvstat` calculates summary statistics for all columns. It recognizes the data type of the column and prints out descriptive information accordingly. `csvstat` may be piped together with `csvcut` to calculate descriptive statistics only for certain columns.

  The following command shows the summary statistics for the car, miles per gallon consumption and origin columns.

{% tabs %}
{% tab title="Bash" %}

```bash
$ csvcut -c 1,2,9 -d ";" cars-tutorial.csv | csvstat | csvformat -D "."
```

{% endtab %}

{% tab title="Output" %}

```
"  1. ""Car"""

  Type of data:          Text
  Contains null values:  False
  Unique values:         308
  Longest value:         36 characters
  Most common values:    Toyota Corolla (9x)
                         Ford Pinto (6x)
                         Ford Maverick (5x)
                         AMC Matador (5x)
                         Volkswagen Rabbit (5x)

"  2. ""MPG"""

  Type of data:          Number
  Contains null values:  False
  Unique values:         130
  Smallest value:        0
  Largest value:         46.6
  Sum:                   9 358.8
  Mean:                  23.051
  Median:                22.35
  StDev:                 8.402
  Most common values:    13 (20x)
                         14 (19x)
                         18 (17x)
                         15 (16x)
                         26 (14x)

"  3. ""Origin"""

  Type of data:          Text
  Contains null values:  False
  Unique values:         3
  Longest value:         6 characters
  Most common values:    US (254x)
                         Japan (79x)
                         Europe (73x)

Row count: 406
```

{% endtab %}
{% endtabs %}

* `csvsort` sorts the rows for the column specified (either with a number or a name) after the argument `-c`. Reversed order can be set by using `-r`.

  Based on the previous example, the highest value in miles per gallon is 46.6. If you want to search for this very fuel efficient car, one way is to sort the data in a reversed order.

{% tabs %}
{% tab title="Bash" %}

```bash
$ csvcut -c 1,2 -d ";" cars-tutorial.csv | csvsort -c 2 -r | head -5 | csvlook | csvformat -D "."
```

{% endtab %}

{% tab title="Output" %}

```
| Car                          |  MPG |
| ---------------------------- | ---- |
| Mazda GLC                    | 46.6 |
| Honda Civic 1500 gl          | 44.6 |
| Volkswagen Rabbit C (Diesel) | 44.3 |
| Volkswagen Pickup            | 44.0 |
```

{% endtab %}
{% endtabs %}

The output shows the four most fuel efficient cars. Mazda GLC, the most fuel efficient one has indeed a 46.6 miles per gallon consumption.

* `csvgrep` selects rows that match specific patterns, so in other words it can be used for filtering. The pattern may either be a string or an integer. The `-c` argument specifies the column in which the pattern is searched for (either the column number or name can be used), while -m defines the pattern.

  Following the previous examples, the car with the highest miles per gallon consumption (which is 46.6) is searched for.

{% tabs %}
{% tab title="Bash" %}

```bash
$ csvgrep -c MPG -m 46.6 -d ";" cars-tutorial.csv | csvlook | csvformat -D "."
```

{% endtab %}

{% tab title="Output" %}

```
| Car       |  MPG | Cylinders | Displacement | Horsepower | Weight | Acceleration | Model | Origin |
| --------- | ---- | --------- | ------------ | ---------- | ------ | ------------ | ----- | ------ |
| Mazda GLC | 46.6 |         4 |           86 |         65 |  2 110 |         17.9 |    80 | Japan  |

```

{% endtab %}
{% endtabs %}

The command yields an output showing only cars with a 46.6 miles per gallon consumption. There is only one such car: Mazda GLC.

It is also possible to filter and separate the file based on a string variable. In the following example three different csv files are created based on the origin variable. We know from the `csvstat` command that there are three possible categories for origin: US, Japan and Europe.

```bash
$ csvgrep -c Origin -m US -d ";" cars-tutorial.csv > cars-tutorial-us.csv
$ csvgrep -c Origin -m Japan -d ";" cars-tutorial.csv > cars-tutorial-japan.csv
$ csvgrep -c Origin -m Europe -d ";" cars-tutorial.csv > cars-tutorial-europe.csv
```

* `csvstack` appends datasets with identical column names. There might be cases where it makes sense to specify the `-g` argument which adds a column identifying the source csv. In the following example it is not needed.

  The three csv files created in the previous example can be stacked. Since there were three countries of origin, this command should have the same length as the original data.

  ```
  $ csvstack cars-tutorial-us.csv cars-tutorial-europe.csv cars-tutorial-japan.csv
  $ csvstack cars-tutorial-us.csv cars-tutorial-europe.csv cars-tutorial-japan.csv | wc -l
  $ wc cars-tutorial.csv -l
  ```

  Both files have 407 rows as expected (406 plus the header).

## Useful resources for learning csvkit:

* The csvkit tutorial and documentation: <https://csvkit.readthedocs.io/en/1.0.5/tutorial.html>


# Release

## **Release management**

The most important element of our work is reproducibility. We have a relatively long time for our projects but we have to rerun our codes and beads countless times.

The following terms are used as an own industrial jargon when we work: alpha release, beta release, Long time support (LTS), data testers and developers.

We are developing codes like software developers and we use terms from [software release life cycle](https://en.wikipedia.org/wiki/Software_release_life_cycle) like alpha release and beta release.

Alpha release in our terms when the codes and the outputs are ready and the bead is saved into the `latest`bead-box.&#x20;

Tester is a person who knows the codes and gives feedbacks to the developer. Tester can run tests on the alpha release like: descriptive statistics, figures or manual checkings.&#x20;

Developer/maintainer is a person who is responsible for data inputs, developments outputs. Developer is also responsible to keep a bead up to date and to write Meta documentations and Readme-s.

Beta stage is when we share the bead inside our team or share the data with another researcher. For example if we need feedback from our colleagues or if we would like to ask for help in debugging from another researcher.

LTS beads are supported and updated at specified intervals. LTS products must have a cleaned bead route and must contain a Makefile which copy all the proper inputs to the output folders.&#x20;

We also have quarterly release plans and personal due dates linked to each Trello card. <br>


# People

Meet our team

CEU MicroData is a research group of faculty, PhD students and research associates within the CEU Economics Department.


# Projects

Research activities and partners, grants

Our project website:

[Macromanagers](https://macromanagers.eu/)


