Crash Course in Scientific Computing

Computers & Operating Systems

Computers are everywhere, nowadays, even in most people's pockets or even hand-wrist. In this Course, we will learn how to tame them and make them obey us so as to be useful companions. For that, we will first have to understand what types of beasts they are, although their proliferation might make us believe we're familiar enough already. But in the jungle of computers, those that we see most often aren't actually the best prototypes to control, as they often represent precisely the species already so much domesticated as to behave more like high-level slaves than low-level machines. At the highest level, we can give as examples your smartphone or an interactive display in the mall or airport. We are interested in the low-level, fundamental, basic aspects of computers, and have them obey us to the letter. We will see that computers are very hierarchical, they build layers over layers over layers. At the highest layers, there is, e.g., skype, allowing you to speak to someone pretty much as if they are in front of you, except that they are on the other side of the planet. At the lowest level, there is the bit: the element of information, that takes the value either 0 or 1. This is useful already. For instance, you could have a bit called day to store the status of the day, being either day, in which case:

day=1

or night, in which case

day=0

Note that we use 0 or 1 but these are just labels. In fact some people like to use day=TRUE and day=FALSE, meaning that for all practical purposes, TRUE=1 and FALSE=0.

Now the world isn't really this type of place where things are night and day, white or black, true or false, bad or good, 1 or 0, we need more refinement, more complexity. This we can do by bringing more bits. For instance,

With two bits, we can store 4 values, namely:

  1. 00 = value 1
  2. 01 = value 2
  3. 10 = value 3
  4. 11 = value 4

The algebra of bits is called Boolean algebra. Because we already know algebra, we can:

A byte is eight bits:

$$b_7b_6b_5b_4b_3b_2b_1b_0$$


Similarly, with $n$ bits, we can store $2^n$ values. This can be use for fairly rudimentary information encoding, for instance, if we lay out our 64 bits (eight bytes) into an array, we can form patterns, such as:

00011000
00011000
00100100
00111100
01000010
01000010
00000000
00000000

or:

01111000
01000100
01111000
01000100
01000100
01111000
00000000
00000000

which is probably not so clear as such but see if we label 1 with a dark character such as # and 0 with a space, we see (putting them side by side):

   ##     ####   
   ##     #   #  
  #  #    ####   
  ####    #   #  
 #    #   #   #  
 #    #   ####   

If we make the computer switch on a pixel of the screen if the bit is set to 1 and leave it off if set to 0, we thus have a way to convert bits into images. We can also use that not to project on screen but to be stored in a disk, or sent over the internet. That is a fairly simple way to store an image, but one that is actually used. Together with some necessary information such the geometry of the image, which specifies how many bits go in the first line and at which point we should break to start the next line, we then create a so-called "file", namely, a pbm file—PBM stands for portable bitmap format—which has a so-called "header" that follows a pre-ascribed format, which for pbm is:

  • two bytes defining the type of file, in our case P1 for pixmap.
  • A line starting with # allowing for a comment (accessorily).
  • Two bytes giving the padding of the image.

This is a valid bitmap file:

P1
# A
8 8
0 0 0 1 1 0 0 0
0 0 0 1 1 0 0 0
0 0 1 0 0 1 0 0
0 0 1 1 1 1 0 0
0 1 0 0 0 0 1 0
0 1 0 0 0 0 1 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

It is 138 bits. You can download it and play with it. Of course, more characters would give us more resolution, and we are not limited to letters. Here's a pbm file of your lecturer:

P1
# Created by GIMP version 2.10.8 PNM plug-in
783 966
1111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111
...(1468 lines of only 1)...
1111111111111111111111111111111111111111111111111111111110111111111111
1111111111111000100111111111111111111111111111111111111111111111111111
...(5778 lines)...
0000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000010111111111111111111111111111111111111111111111
1111111111111111111111111111111111100000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000001111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111100111110000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000001111111111111111111111111111111111
1111111111111111111111111111111111111111111110000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000111111111111111111111111111111111
...(5023 lines)...
1111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111

which, setting 1 bits to black and 0 to white, gives:

Fabrice.laussy-pbm.jpg

Note that there is a linebreak (and no space) so that the data is not actually stored directly as the grid of pixels itself, mainly for portability, that's what the P of PBM stands for. For this reason, we really need the encoding in the header. For instance, if it would be off by one and read 784 966 instead of 783 966, the image would be reconstructed as:

Fabrice.laussy-squeezed-pbm.jpg

Can you see why?

While at the deepest level, the computer really stores these images as such, it is not convenient for us, human beings, and we would work here too in a different basis than 2. Since we group bits by groups of eight (bytes), the Hexadecimal (base 16) is convenient since $2^4=16$, an hexadecimal represents half-a-byte (a so-called nibble) and two numbers represent a byte. Therefore, the bits for the letter A, which in a single line read:

0001100000011000001001000011110001000010010000100000000000000000

we can convert in hexadecimal as:

18 18 24 3C 42 42 00 00

The same for B:

78 44 78 44 44 78 00 00

etc.

What is the letter 0x3844808044380000? How about

  • 0x3C023E463A0000
  • 0x40407C42625C0000
  • 0x6094681629060000
  • 0x3C449C945C201C?

etc.

If we do not store the data in plain text (ASCII, 0 & 1 only) but in hexademical (with no linebreaks) the same file looks like this:

Raw-pbm.png

where the header now reads P4 (it is left as an exercise for you to decipher the header completely) meaning that encoding is now RAW, not ASCII (0/1).

Instead of using two bits to represent two colours (white & black) we would use, say, 8 bits to represent shades of grey, making a much neater image, or 3 bytes to encode Red, Green and Blue components, making an RGB bitmap:

Laussy-grayscale.png

Still encoding this in ASCII, and with one data per line (as is the [arbitrary] choice of the software used, gimp), this gives the following headers:

P2
# PGM file Created by GIMP version 2.10.8 PNM plug-in
783 966
255
0
1
1
1
2
2
1
1
1
0
0
1
1
0
0
1

and

P3
# PPM file Created by GIMP version 2.10.8 PNM plug-in
783 966
255
1
0
0
4
0
0
4
0
1
5
0
1
5
1
2
5

You see that the header varies with specification P2 & P3 which correspond to ASCII gray & color encoding, respectively. You already know P4, there is also P5 & P6 which are for hexadecimal encodings. This table gives you the fairly complete characterization of [PBM] bitmap encoding.

Type Magic number Extension Colors
ASCII (plain) Binary (raw)
Portable BitMap P1 P4 .pbm 0–1 (white & black)
Portable GrayMap P2 P5 .pgm 0–255 (gray scale), 0–65535 (gray scale), variable, black-to-white range
Portable PixMap P3 P6 .ppm 16777216 (0–255 for each RGB channel), some support for 0-65535 per channel

We could carry on discussing image encoding, for instance introducing more popular formats, but basically equally simple formats, such as Targa (abbreviation tga), which is the simplest widely supported binary image file format, or BMP, using the same encoding (more complex headers) and popular on Microsoft platforms—you might actually have encountered these file extensions before—or even go onto the really famous formats, such as gif, jpg or png, but that is not our direction. We are interested instead in the general system which allows us to deal with collections of bits to turn them into useful things, not specifically images. We have seen texts, images, there is also music, movies, etc. We shall come to that, but one bit at a time! The object of our current interest is the system that operates all these features, that brings together programs (so-called software) with data (files, data in memory, data downloaded from the web). This is the so-called Operating System.

From a Scientific perspective, the Operating System of choice is called Unix. This was the system used initially by computer scientists, scientists in general and even the military. This was mainly developed for mainframes, workstations, etc. Someone very clever understood there was a big market in bringing computers to the general public. Bill Gates introduced a user-friendly, layman's system to use so-called Personal Computers (PC). This is the so-called Windows, already a marketing coup since the concepts of Windows in the computer environment comes from Unix (so-called X-Windows). Gates' company, Microsoft, which everybody knows, simplified everything and delivered a baby's version of operating systems, which got so popular (since the wide public is not technically minded) that Gates became the richest man on the planet for decades. Another very clever guy, Steve Jobs, sensed that there was a niche market in providing computers for even less-technically minded people, who would favour even simpler, shinier, fancier computer environment. Along with a tech guy (Steve Wozniak), he developed the Apple company. At the same time, on the Unix side, something wonderful happened with a student, Linus Torvalds, developed on his own a Unix-like operating system for PCs, as an exercise or toy-project. This was at the time where internet forums were starting to become popular and other people followed him in playing with this fun little project. The collaboration of dedicated, enthusiastic and curious people led this fun project into one of today's most powerful, important and growing computer environment: linux (a blend of Linux and Unix).

A fourth figure, less famous, needs to be mentioned at this point: Richard Stallman. He is a computer scientist who developed a series of software for the Unix environment, known as GNU, standing for "GNU is Not Unix", which principle is that of being free-software, meaning, the source code is free (as in freedom, not as in cost-free) for the user to view, modify, adapt to their own needs. This is compared to Windows/Apple's philosophy which is that of copyright and intellectual property, where not only you must pay for each copy, but also have no regard to what's inside and of course no way to actually modify it. Stallman actually had planned to write a GNU version of the Unix operating system, which was called Hurd. But this was too difficult and the GNU team focused on the softwares instead. Linus, on the other hand, managed to break a dynamics to do just that, independently, an open-source, free-software version of a Unix like operating system. Together, these two things provide the GNU/Linux environment, which is the one we encourage you to use for the following reasons:

  • It is free (as in freedom, you can do whatever you want).
  • It is also free in the sense of cost-free.
  • It is more powerful for scientific/technological purposes than Windows & Apple products.
  • It is more ethical.

You can install Linux on your personal computer, to side along your other operating systems in a so-called dual-booting configuration: you decide which OS you will take command of the computer with.

Once linux is installed, one needs a Windows manager/desktop environment, that abstracts concepts such as files and directories into folders, etc. Two popular for Linux are kde and gnome. It's just a question to get used to them.

Let us look at some simple/basic commands or functions that the Linux (or Unix) operating systems bring to our disposition. We can go back to the more basic Operating System from the Windows environment by using a console, or terminal. In kde, this can be used with konsole. That is what one would normally access before launching a Windows manager, but nowadays everybody starts at the Windows level.

In the OS, one is logged-in as a user. Linux answers your most existential question with the command whoami

laussy@wulfrun2:~$ whoami
laussy

Note the (typical, could differ depending on the configuration) structure of the prompt, i.e., the point at which you enter your command: laussy is the user name, wulfrun2 is the name of the computer:

laussy@wulfrun2:~$ hostname
wulfrun2

so here you have laussy working @ wulfrun2, which is the computer with which I am writing these notes. The symbol ~ tells us where we are in the Directory tree, this is a shortcut for "home". We can ask this to be explicit with the command:

laussy@wulfrun2:~$ pwd
/home/laussy

We can change the directories with the cd command, e.g., cd .. goes one way up:

laussy@wulfrun2:~$ cd ..
laussy@wulfrun2:/home$ cd ..
laussy@wulfrun2:/$ 

You see that we went from home (~ or /home/laussy) to /home to /.

What's in /? We can see the content of a directory with the command ls (for "list"):

laussy@wulfrun2:/$ ls
bin   cdrom  etc   lib    lib64   lost+found  mnt  proc  run   snap  sys  usr
boot  dev    home  lib32  libx32  media       opt  root  sbin  srv   tmp  var

For now, we do not need to go into much more details of these directories... /media, for instance, is where the system will link external devices (like a USB key). Let's get back home and make a working directory:

laussy@wulfrun2:/$ cd
laussy@wulfrun2:~$ mkdir julia
laussy@wulfrun2:~$ rmdir julia
laussy@wulfrun2:~$ mkdir lecture-1
laussy@wulfrun2:~$ cd lecture-1
laussy@wulfrun2:~/lecture-1$ 

We created (mkdir) but also deleted (rmdir) a directory julia since we shall see that later on. Instead we created lecture-1 and went there. Of course it is currently empty:

laussy@wulfrun2:~/lecture-1$ ls

We can create an empty file with touch and then list it:

laussy@wulfrun2:~/lecture-1$ touch file
laussy@wulfrun2:~/lecture-1$ ls
file

Not very exciting. In Unix (Linux), commands typically come with options. For instance, we can ask a listing with more information with:

laussy@wulfrun2:~/lecture-1$ ls -l
total 0
-rw-rw-r-- 1 laussy laussy 0 Jan 13 14:06 file

and this is already more than you'd like to know. It tells us the permissions on the file: r is for read, the file can be read, w is for write, the file can be modified and there is a x for executable, meaning the file can be run as a program, which here is not set so we have - instead. The first batch rw- is for the user (laussy), the 2nd, also rw-, is for the group (which is also laussy, in case you work in a group with other people; this is a relic of the Unix environment which was on mainframes) and the last batch is for people not in the group: they can only read the file, not change it. Note that this status rwx requires one byte, so three bytes for each file, that you can change with the command chmod. So if we want to make the file not readable to people not in our group (confidential file), we'd write:

laussy@wulfrun2:~/lecture-1$ chmod 660 file 
laussy@wulfrun2:~/lecture-1$ ls -l
total 0
-rw-rw---- 1 laussy laussy 0 Jan 13 14:06 file

If we'd like to make it executable, for ourselves only (not people of our group, but still allowing everybody to read the file), we'd ask:

laussy@wulfrun2:~/lecture-1$ chmod 764 file 
laussy@wulfrun2:~/lecture-1$ ls -l
total 0
-rwxrw-r-- 1 laussy laussy 0 Jan 13 14:06 file

It is now executable (by us) but does nothing, since it's empty.

Let's populate this file with something, for instance with the date:

laussy@wulfrun2:~/lecture-1$ date
Wed 13 Jan 14:26:23 CET 2021
laussy@wulfrun2:~/lecture-1$ date > file 
laussy@wulfrun2:~/lecture-1$ cat file
Wed 13 Jan 14:26:26 CET 2021

The first command asks the date (it is echoed on the screen), the second sends the output to file, the last one asks to display its content. If we use >>, the content is added at the end rather than overwriting:

laussy@wulfrun2:~/lecture-1$ date >> file 
laussy@wulfrun2:~/lecture-1$ cat file
Wed 13 Jan 14:26:26 CET 2021
Wed 13 Jan 14:27:26 CET 2021

Remember that it's an executable. If we ask to run the content:

laussy@wulfrun2:~/lecture-1$ ./file 
./file: line 1: Wed: command not found

we get a mistake, since we populated it with data, not code! On the other hand:

laussy@wulfrun2:~/lecture-1$ echo date > file
laussy@wulfrun2:~/lecture-1$ ./file 
Wed 13 Jan 14:29:55 CET 2021

where echo echoes what comes next rather than execute it. Hey! we made our first program. Here's a slightly more interesting one:

laussy@wulfrun2:~/lecture-1$ echo "date; sleep 1; date" > file
laussy@wulfrun2:~/lecture-1$ ./file 
Wed 13 Jan 14:31:16 CET 2021
Wed 13 Jan 14:31:17 CET 2021

and you can guess what happened as well! We could rename this to a more meaningful name, by moving mv or copying cp the file:

laussy@wulfrun2:~/lecture-1$ cp file just-a-sec
laussy@wulfrun2:~/lecture-1$ ls
file  just-a-sec

You can see the options available for ls with the --help argument:

laussy@wulfrun2:~/lecture-1$ ls --help
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.

Mandatory arguments to long options are mandatory for short options too.
  -a, --all                  do not ignore entries starting with .
  -A, --almost-all           do not list implied . and ..
      --author               with -l, print the author of each file
  -b, --escape               print C-style escapes for non-graphic characters
      --block-size=SIZE      with -l, scale sizes by SIZE when printing them;
                               e.g., '--block-size=M'; see SIZE format below
  -B, --ignore-backups       do not list implied entries ending with ~
  -c                         with -lt: sort by, and show, ctime (time of last
                               modification of file status information);
                               with -l: show ctime and sort by name;
                               otherwise: sort by ctime, newest first
  -C                         list entries by columns
      --color[=WHEN]         colorize the output; WHEN can be 'always' (default
                               if omitted), 'auto', or 'never'; more info below
  -d, --directory            list directories themselves, not their contents
  -D, --dired                generate output designed for Emacs' dired mode
  -f                         do not sort, enable -aU, disable -ls --color
  -F, --classify             append indicator (one of */=>@|) to entries
      --file-type            likewise, except do not append '*'
      --format=WORD          across -x, commas -m, horizontal -x, long -l,
                               single-column -1, verbose -l, vertical -C
      --full-time            like -l --time-style=full-iso
  -g like -l, but do not list owner
      --group-directories-first
                             group directories before files;
                               can be augmented with a --sort option, but any
                               use of --sort=none (-U) disables grouping
  -G, --no-group             in a long listing, don't print group names
  -h, --human-readable       with -l and -s, print sizes like 1K 234M 2G etc.
      --si                   likewise, but use powers of 1000 not 1024
  -H, --dereference-command-line
                             follow symbolic links listed on the command line
      --dereference-command-line-symlink-to-dir
                             follow each command line symbolic link
                               that points to a directory
      --hide=PATTERN         do not list implied entries matching shell PATTERN
                               (overridden by -a or -A)
      --hyperlink[=WHEN]     hyperlink file names; WHEN can be 'always'
                               (default if omitted), 'auto', or 'never'
      --indicator-style=WORD  append indicator with style WORD to entry names:
                               none (default), slash (-p),
                               file-type (--file-type), classify (-F)
  -i, --inode                print the index number of each file
  -I, --ignore=PATTERN       do not list implied entries matching shell PATTERN
  -k, --kibibytes            default to 1024-byte blocks for disk usage;
                               used only with -s and per directory totals
  -l                         use a long listing format
  -L, --dereference          when showing file information for a symbolic
                               link, show information for the file the link
                               references rather than for the link itself
  -m                         fill width with a comma separated list of entries
  -n, --numeric-uid-gid      like -l, but list numeric user and group IDs
  -N, --literal              print entry names without quoting
  -o                         like -l, but do not list group information
  -p, --indicator-style=slash
                             append / indicator to directories
  -q, --hide-control-chars   print ? instead of nongraphic characters
      --show-control-chars   show nongraphic characters as-is (the default,
                               unless program is 'ls' and output is a terminal)
  -Q, --quote-name           enclose entry names in double quotes
      --quoting-style=WORD   use quoting style WORD for entry names:
                               literal, locale, shell, shell-always,
                               shell-escape, shell-escape-always, c, escape
                               (overrides QUOTING_STYLE environment variable)
  -r, --reverse              reverse order while sorting
  -R, --recursive            list subdirectories recursively
  -s, --size                 print the allocated size of each file, in blocks
  -S                         sort by file size, largest first
      --sort=WORD            sort by WORD instead of name: none (-U), size (-S),
                               time (-t), version (-v), extension (-X)
      --time=WORD            with -l, show time as WORD instead of default
                               modification time: atime or access or use (-u);
                               ctime or status (-c); also use specified time
                               as sort key if --sort=time (newest first)
      --time-style=TIME_STYLE  time/date format with -l; see TIME_STYLE below
  -t                         sort by modification time, newest first
  -T, --tabsize=COLS         assume tab stops at each COLS instead of 8
  -u                         with -lt: sort by, and show, access time;
                               with -l: show access time and sort by name;
                               otherwise: sort by access time, newest first
  -U                         do not sort; list entries in directory order
  -v                         natural sort of (version) numbers within text
  -w, --width=COLS           set output width to COLS.  0 means no limit
  -x                         list entries by lines instead of by columns
  -X                         sort alphabetically by entry extension
  -Z, --context              print any security context of each file
  -1                         list one file per line.  Avoid '\n' with -q or -b
      --help     display this help and exit
      --version  output version information and exit

The SIZE argument is an integer and optional unit (example: 10K is 10*1024).
Units are K,M,G,T,P,E,Z,Y (powers of 1024) or KB,MB,... (powers of 1000).

The TIME_STYLE argument can be full-iso, long-iso, iso, locale, or +FORMAT.
FORMAT is interpreted like in date(1).  If FORMAT is FORMAT1<newline>FORMAT2,
then FORMAT1 applies to non-recent files and FORMAT2 to recent files.
TIME_STYLE prefixed with 'posix-' takes effect only outside the POSIX locale.
Also the TIME_STYLE environment variable sets the default style to use.

Using colour to distinguish file types is disabled both by default and
with --color=never.  With --color=auto, lt emits colour codes only when
standard output is connected to a terminal.  The LS_COLORS environment
variable can change the settings.  Use the dircolors command to set it.

Exit status:
 0  if OK,
 1  if minor problems (e.g., cannot access subdirectory),
 2  if serious trouble (e.g., cannot access command-line argument).

GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Full documentation at: <https://www.gnu.org/software/coreutils/ls>
or available locally via: info '(coreutils) ls invocation'

As you can see, it's quite mighty. We usually don't need to enter into such details. Those are the very basics, and all these things you can do with the mouse and clicking on files, but it's important to know how they arise at a more fundamental level because when we will program, or instruct the computer, we'll need to refer to these basic commands. There are of course very many commands, even to do fairly similar things. For instance, cat outputs the entire file, which, if it's big, will flood the screen. If you want only the beginning, you can use head, actually the content of the bitmap files above was obtained with, e.g., head -20 fabrice.laussy.pgm (to get the first 20 lines). If you want the last lines you'd ask for tail instead. To see the content of a file page by page, we would use more but this has been replaced with less that allows you come back (as you can see, Unix computer scientists have a sense of humour).

Anyway, let's have a look at more powerful things, involving text processing, images, music, movies, etc. Actually, although you may not know the basics so well, you certainly know the advanced applications, such as Word for text-editing (power-point for presentations), etc. In Linux, there are many text editors. A very powerful one, but maybe not the most user friendly, is Emacs, which you can invoke as follows:

laussy@wulfrun2:~/lecture-1$ emacs just-a-sec 

at which point the console freezes (if you do not want it to freeze and remain independent, use an amperan: emacs just-a-sec &) and opens a window:

Screenshot 20210113 145446.png

There one can edit the "program", for instance making it wait 2 seconds. Everybody has a text-editor of their choice, you can use whichever you want. Some are even more cryptic than Emacs (such as vi; launch it and get frustrated). To get something Windows-looking like you can invoke libre-office, but this is certainly not the best for computer programming.

Emacs works with key-control rather than click with the mouse. To open a new file, try C-x C-f (meaning first do Control-x then Control-f). To give you an idea of the GNU spirit, run C-h C-t, it will bring you to the Emacs TODO list which gives a list of things you can do to enhance the editor. At the time of writing (which you know from just-a-sec above), it reads:

* Speed up Elisp execution
** Speed up function calls
Change src/bytecode.c so that calls from byte-code functions to byte-code
functions don't go through Ffuncall/funcall_lambda/exec_byte_code but instead
stay within exec_byte_code.

** Improve the byte-compiler to recognize immutable (lexical) bindings
and get rid of them if they're used only once and/or they're bound to
a constant expression.

Etc...

Emacs has been benefitting from hundreds of contributors for decades. It is possibly the most powerful text editor existing. Some say it's not even a text-editor anymore, but a religion. If you are interested to learn to use it, try C-h t, this will bring you to a self-contained tutorial.

What are other applications of interest? Here are some which you are invited to explore:

Next Lecture, we will look at one specific software, $\TeX$, which is a typesetting program.