Programming
and computers
Aurélien Ginolhac, DLSM
University of Luxembourg
Friday, the 14th of March, 2025
Learning objectives
What are the differences between hard/software
Touch how computer work
A brief history of computers
Learn the main programming controls (for/if
)
Hardware vs Software
Hardware : body of a computer
Software : soul of a computer
Hardware / Software
OS: / /
OS: /
Many machine OS: : PlayStation, smartTV, routeurs, servers
Binary
1 or 0 (on or off: high / low voltage)
Two digits are easier to manipulate
Less complexity = less errors or chances to fail (permutations of bits)
This is how everything is stored, even music and pictures!
bit = 1 binary digit
1 byte = 8 bits
1 byte can encode up to 256 values (0-255, \(2^8\) ). IP is 0-255.0-255.0-255.0-255.
Naming is tricky:1 GB
= 8 Gb
Memory
Random Access Memory: RAM
Fast
Limited capacity (8GB is decent)
Wiped out when powered off
Picture: Andrey Matveev, Unsplash
Hard drive (now mostly SSD)
Slower, SSD faster than HDD
Large capacity (250GB is standard)
Retain information
Photo by Benjamin Lehman , Unsplash
How do we get to binary?
Decimal vs binary
0
0000000
1
0000001
2
0000010
3
0000011
4
0000100
5
0000101
6
0000110
7
0000111
8
0001000
9
0001001
10
0001010
11
0001011
12
0001100
13
0001101
14
0001110
15
0001111
107
1101011
Abacus Objects
Keep track / help for calculus (little stone in Latin)
Not necessarily decimal system, bi-quinary, 5-digit base-20 system etc.
Mechanical systems
Blaise Pascal in 1642-1645 conceived the Pascaline : direct additions / subtractions
Charles Babbage
Analytical Engine using punched cards (1834-1871)
Ada Lovelace
1815-1827, English mathematician and first programmer using punched card
Diagram of Bernoulli numbers (1712): first published computer algorithm
How computer work? Logical gates
Adding 5 (0101) and 6 (0110) = 1011
XOR gate
Exclusive OR: 1 only if one input is 1
VIDEO
AND gate
1 only if both inputs are 1
VIDEO
How computer work? Half-Adder
Adding 5 (0101) and 6 (0110) = 1011
One bit at a time
XOR gate (sum): 0011
AND gate (carry): 0100
Missing full circuit:
Logical gates with transistors
AND gate on the left, OR gate on the right
Relay, Vaccum tubes, Transistors
How computer went faster and smaller
What is a program, a language?
A program is a series of instructions
Started with punched cards (Babbage)
A language is a syntax
+/- close to machine instructions
Interpreted (R/Python), slower and easier
Compiled (C, Rust) efficient and complex
The instructions requirements depend on the language
Memory allocation (C)
Memory ownership (Rust)
Strict indentation (Python)
But languages don’t make communities , people do (Julia)
Syntax
Some differences are superficial:
BASIC: print
Java: System.out.print();
C++: printf();
But, high level vs low level programming languages
#!/usr/bin/env python
print ("Hello from BASV!" )
C++ , while compiled still high-level
#include <stdio.h>
int main( void ) {
printf( "Hello from BASV! \n " );
return 0 ;
}
The same code for printing a 3-word string
.LC0:
.string "Hello from BASV!"
.text
.globl main
.type main, @f unction
main:
.LFB0:
.cfi_startproc
pushq % rbp
.cfi_def_cfa_offset 16
.cfi_offset 6 , - 16
movq % rsp , % rbp
.cfi_def_cfa_register 6
movl $. LC0, % edi
call puts
movl $ 0 , % eax
popq % rbp
.cfi_def_cfa 7 , 8
ret
.cfi_endproc
Run-time errors
Errors detected during execution lead to crash like division by 0
C language
#include <stdio.h>
int main( void )
{
int a = 8 ;
int b = 4 ;
int c = 0 ;
int average = ( a + b) / 2 ;
int result = average / c;
printf( "mean ( %d , %d ) by %d = %d\n " , a, b, c, result);
return 0 ;
}
Floating point exception 💣
No crash, but returns Infinite
a <- 8
b <- 4
c <- 0
average <- (a + b) / 2
result <- average / c
result
Logical errors
Errors that are not detected, execution continues
C, spot the mistake
#include <stdio.h>
int main( void )
{
int a = 8 ;
int b = 4 ;
int c = 2 ;
int average = a + ( b / 2 );
int result = average / c;
printf( "mean ( %d , %d ) by %d = %d\n " , a, b, c, result);
return 0 ;
}
Solution
Average defined as a + (b / 2)
And not (a + b) / 2
Algorithm: definition
An algorithm is a well-ordered collection of unambiguous and effectively computable operations that when executed produces a result and halts in a finite amount of time
— Schneider and Gersting 1995
Pseudocode: prepare and plan
Not in normal language, nor in pure code
Separate syntax from logical misconceptions
Like a cooking recipe
Example
Given a vector of several numbers
How to check numbers equal to 2?
Iterate through the elements with a variable i
Test if
i
is equal to 2
Print the value of i
.
in
serie <- c (1 , 2 , 3 ,4 )
for (i in serie) {
if (i == 2 ) print (paste ("found 2 in i = " , i))
}
And with vectorization ! What are the results?
serie == 2
serie[serie == 2 ]
sum (serie == 2 )
Variables
Variables store information for later use
Variable names should be clear and understandable
Naming
Be consistent !, use naming conventions :
alllowercase
period.separated
underscore_separated (_*_)
lowerCamelCase
UpperCamelCase
Examples
my_age
, class_size
to store a number
my_name
to store letters (a “string”)
add_footer
, for a function (action)
is_odd
, for a function that detects odd numbers and return a logical (TRUE
/FALSE
)
One named value in memory
We assign the name x
to the value 1
.
assignment operator is <-
In memory:
0x5e903189e078
is the RAM (volatile) address where 1
is stored.
Values / Indices
How to have more than one value to store?
Data structure: vectors
We assign the name y
to the values 1, 2, 3
.
concatenation function is c()
y <- c (1 , 2 , 3 ) # shortcut 1:3
For characters instead of integers
Control statements: if, else
Definition: if (condition)
condition
must be a boolean (TRUE
/FALSE
)
Could be one of more conditions
Combined by AND
or OR
statement
else
is optional
else if
is possible
Use indentations in code
Syntax
if (condition) {
do_task ()
} else {
do_something_else ()
}
Logical/boolean operators, AND, OR, NOT
3 types
A
B
A AND B
A OR B
NOT A
False
False
False
False
True
False
True
False
True
True
True
False
False
True
False
True
True
True
True
False
var1 <- 1 : 20 # a vector of 1, 2, 3, ..., 20
# for AND use &
if (var1 > 10 & var1 <= 20 )
# for OR use |
if (var1 > 10 | var1 <= 20 )
What will be the difference?
Conditional blocks in R
if
, else if
and else
Blocks are delimited with curly braces {
and }
Indent your code after {
, RStudio does it for you
Re-indent with Cmd/Ctrl + i
Example: compare 2 numbers, handling the 3 possibilities
n1 <- 11
n2 <- 7
if (n1 == n2) {
print (paste (n1, "and" , n2, "are equal" ))
} else if (n1 > n2) {
print (paste (n1, "is greater than" , n2))
} else {
print (paste (n1, "is smaller than" , n2))
}
[1] "11 is greater than 7"
We will see dplyr::case_when()
for multiple if / else
statements
For loops
v <- c (3 : 6 )
for (i in v) {
print (i)
}
Loop over indices (seq_along()
handles empty vector)
for (i in seq_along (v)) {
print (paste ("indice" , i, "=" , v[i]))
}
[1] "indice 1 = 3"
[1] "indice 2 = 4"
[1] "indice 3 = 5"
[1] "indice 4 = 6"
We will try to avoid writing any for loops!
Using functional programming.
For loops in , the “are slow” myth
Growing vector
for_loop <- function (x) {
res <- c () # initialize an empty vector
for (i in seq_len (x)) {
res[i] <- i
}
}
Using Rcpp
library (Rcpp) # binds cpp compilation to R
cppFunction ("NumericVector rcpp(int x) {
NumericVector res(x);
for (int i=0; i < x; i++) {
res[i] = i;
}
}" )
Correct allocation
for_loop <- function (x) {
res <- vector (mode = "integer" , length = x)
for (i in seq_len (x)) {
res[i] <- i
}
}
Cubetto
For the students interested (= not mandatory):
As introduction to functions we have an extra 45 minutes course with the Cubetto .
Before we stop
What is a computer
What is a program / memory
Write pseudo-code
Control flows
For loops
Conditional blocks
Thank you for your attention!