Variables and control structures
Contents
Programming Course - Master 1 PSL - Science et Génie des Matériaux / Énergie
Variables and control structures#
Basile Marchand (Centre des Matériaux- Mines ParisTech / CNRS / PSL University)
Define and manipulate variables#
Concretely, what is a variable?#
In general, in computer science, a variable is a symbol associated with a value. The value in question can be of any type. Depending on the programming language considered, a variable can be typed (i.e. when it is declared it has an immutable type) or not (i.e. the value associated with the variable can change its type during the execution of the program). Python is a non-typed programming language. In other words if you declare a variable A that contains a string you can later in the program associate it with a number instead for example.
The Python language, compared to low level languages such as C, greatly simplifies the manipulation of variables. Indeed, to create a variable, we usually distinguish the declaration operation from the assignment operation. Typically in C++ the first step is to declare a variable A with its type. And in a second step using the =
operator we assign to this variable a value of the corresponding type. For example to define an integer in C++ :
int value;
value = 1;
In Python the declaration step is included in the assignment. Indeed since variables are not typed in Python they can’t be declared in advance. In all rigor this is possible but is strictly useless given the internal mechanisms of the language.
The question we can then ask ourselves is where the value associated with the variable is actually located in the computer? In a file?
No, it is located in the RAM memory. How it works:
When in a Python code we create a variable A associated to a value of a certain type (floating number for example) the mechanism of the language will automatically ask the computer to give it a box in the memory (the size of the box depends on the type of the value we want to store). The Python language then retrieves a pointer to the allocated memory slot (a memory address) and associates the variable to be manipulated with this memory address. The Python language is called high level because of this process of creating variables in memory which is automated and transparent for the user. Contrary to low level languages, like C or FORTRAN for example, where the programmer must explicitly ask for the allocation of a memory cell before storing a value.
Tip: to know the address in memory of a variable in Python you just have to do :
my_variable = 12.4 # we define a variable named my_variable and we associate the value 12.4
hex(id(my_variable)) # request the memory address in hexadecimal
'0x70ed38516e30'
How do you define a variable? Can we define everything as a variable?#
In Python, as in a number of other languages, the assignment of a value to a variable (which in Python creates the variable if it does not exist) is done with the = symbol The syntax for all types is the following:
variable_name = associated_value
For example:
var1 = 1.3
Note on variable naming: the PEP8
The naming of variables is an important element, whatever the programming language. Indeed a bad choice in the naming of variables does not affect the functioning of the code but it generates :
Programming errors.
A code that is difficult to read and understand.
A code that is difficult to maintain and to evolve.
The first and most important point is therefore that variables must always be named in such a way that you know from the name what it refers to.
There are “official” recommendations for Python concerning the naming of variables, it is the PEP8.
Among the various recommendations contained in PEP8, the one concerning the naming of variables stipulates that :
Variable names begin with a lower case letter
If the name consists of more than one word, the words are separated by _
my_variable
Tip: to know the type of a variable just use
type(my_variable)
float
The basic types (so not the only ones possible)!#
We will now review the different basic types available in Python. We will see later in the course that Python allows to define new additional types. We will also see that the use of modules makes it possible to handle other types such as matrices for example.
Numbers: integers, floats and complexes#
Like any computer language, Python allows the manipulation of numbers of all types, integers, floats and complexes.
Integers are objects of type int (for integer).
un_entier = 127
## ou bien
un_entier = int(127)
un_entier, un_autre = 128,25
All the usual operations addition, subtraction, multiplication, division and raising to the power are already defined and usable on integers.
Warning: In Python 2.X the / division of two integers actually returns the integer division while in Python 3.X it is indeed a floating-point division.
%%python2
a = 1
b = 3
print("a/b = {}".format( a/b ))
Couldn't find program: 'python2'
The real are objects of type float for floating
Floats are defined in Python following the same logic as integers, note that the comma is represented by a dot.
a = 1.2387
## or
a = float(1.2387)
We can also define \(0.000123\) by \(1.23 e^{-4}\) as follows
1.23e-4
0.000123
As for integers, all the usual operations are defined and usable in Python
a = 1.24
b = 2.45
print(a+b) ## Addition
print(a-b) ## Subtraction
print(a*b) ## Multiplication
print(a/b) ## Division
print(a**b) ## a power b
3.6900000000000004
-1.2100000000000002
3.0380000000000003
0.5061224489795918
1.6938819049274374
When mixing types within expressions Python automatically takes care of converting the operands into the appropriate type.
For example the sum of an integer and a float returns a float
a = 2
print(type(a))
b = 2.
print(type(b))
c = a + b
print(c)
print(type(c))
a = 0.1
b = 0.2
c=a+b
print(a)
print(b)
print(c)
<class 'int'>
<class 'float'>
4.0
<class 'float'>
0.1
0.2
0.30000000000000004
The complexes are defined by a doublet of two numbers the real part and the imaginary part. In Python the definition of this doublet can be done in two different ways
## Using the "complex" constructor
un_complex = complex(1,1) # corresponds to 1+1i
## Use of the constant "j
un_complex = 1+1j
Caution : there is no * operator between the 1 and the j if you try to put this operator in the definition of a complex it will lead to an error
>>> x=1
>>> y=2
>>> c = x+y*j
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-26-b894b6a64e03> in <module>()
1 x=1
2 y=2
----> 3 c = x+y*j
NameError: name 'j' is not defined
*Tip: If you want to manipulate complexes involving variables without having to rewrite the complex command each time, the easiest way is to proceed as follows
i = 1j
x = 1
y = 2
c = x+i*y
print(c)
(1+2j)
Of course the basic operations on complex numbers already exist in Python.
c1 = 1+1j
c2 = 2+3.45j
print(c1+c2)
print(c1-c2)
print(c1*c2)
print(c1/c2)
(3+4.45j)
(-1-2.45j)
(-1.4500000000000002+5.45j)
(0.3427134098412199-0.09118063197610438j)
But there are also other specific operations available
print(c1.real) ## Real part
print(c1.imag) ## Imaginary part
print(c1.conjugate()) ## Conjugate of c1
print(abs(c1)) ## Module of c1
1.0
1.0
(1-1j)
1.4142135623730951
Booleans#
The boolean type is used in Python for writing logical expressions, tests. The boolean type can only take two values True or False.
un_true = True
un_false = False
In order to build logical expressions we have the following logical operators in Python:
Comparison operators (applicable to integers and floats): >,>=,<,<=,==,!=
Connectors: and, or, not, == or is, in
Below are some examples of logical expressions:
a = 2.3
b = 10
print( a <= b)
print( a >= b)
print( (a <= b) is True )
print( (a <= b) == False )
print( (a <= b) or (a > b) )
print( ( (a <= b) or (a > b) ) and ( a>b ) )
print( not (b>10.))
True
False
True
False
True
False
True
Strings of characters#
The last native type in Python is the string type for strings. Strings in Python can be defined in three different ways.
une_string = "Hell World"
### or
une_string = 'Hello World'
### or
une_string = """Hello World"""
These three definition methods all have an interest. The first one allows to define strings containing apostrophes. The second one allows to define strings containing quotation marks. The last one allows to keep the formatting of the string when displaying it with the print command for example
one_chain_without_formatting = "Hello everyone, how are you?"
print( one_chain_without_formatting )
one_chain_with_formatting = """Hello everyone,
how are you? """
print( one_chain_with_formatting )
Hello everyone, how are you?
Hello everyone,
how are you?
Note: the last method of writing a string, based on triple quotes, also allows you to define comment blocks.
String manipulation {“lang”: “en”, “slideshow”: {“slide_type”: “subslide”}}
We will now see how we can manipulate strings. This may seem secondary but for the processing of experimental data a large part of the work is the processing of files and thus of strings representing their contents. It is therefore essential to know how to process strings quickly and efficiently. Here are some elementary operations on strings.
string_a = "start"
string_b = "end"
Concatenation of strings :
res = string_a + string_b
print(res)
res = string_a + " " + string_b
print(res)
startend
start end
Formatting a string:
my_string = "A string with an integer {} a float {} and a boolean {}".format(1,2.34,False)
print( my_string )
A string with an integer 1 a float 2.34 and a boolean False
my_string = "A string with an integer {2} a float {1} and a boolean {0}".format(False,2.34,1)
print( my_string )
A string with an integer 1 a float 2.34 and a boolean False
Since Python 3.6 it is possible to format a string more concisely using the following syntax:
f"a string {variable} and/or {python expression}"
pi=3.14
print( f"pi={pi} and pi*pi={pi*pi}")
pi=3.14 and pi*pi=9.8596
And since Python 3.8 you can :
print( f"{pi=}")
pi=3.14
Find if a substring is in a string :
sub_string = "ar"
print( sub_string in string_a )
True
Separate a string into a set of strings at a given character level:
res = string_a + "_" + string_b
print(res)
after_split = res.split("_")
print(after_split)
print(after_split[0])
print(after_split[1])
start_end
['start', 'end']
start
end
Join a list of strings with a given delimiter :
print(after_split)
"-".join(after_split)
['start', 'end']
'start-end'
Know the size of a string
print(string_a)
len(string_a)
start
5
Extract a subpart (slice)
string_a[1:3]
'ta'
string_a[::2]
'sat'
Slicing in general
In general, the syntax for extracting a slice is of the form:
start:end:step
With by default :
start=0
end=len(obj)
step=1
Warning
In the slice the value ofend
is excluded.
Control structures#
Principle#
The last point addressed in this first part is what is called in computer science the control structures. We have seen previously that we can easily write logical expressions about variables. What we have not seen for the moment is what the result of these logical expressions can be used for in the code and this is where the control structures come in. Indeed the interest of a computer program is generally to carry out a certain number of tasks/actions. But according to the input values of the program the actions to be performed are potentially not the same, so we need to set up logical expressions associated to the control structures in order to direct the program and the processing flow.
Concretely, let’s imagine that I make a program which, according to grades, tells me automatically if a student validates my module or if he has to go for a re-take. Once the grade has been calculated, I have to test if it is greater than or equal to 10 or if it is less than 10, because depending on the case, the program should not display the same message. This is what the use of control structures is all about.
if … elif … else#
In Python the only commands that allow you to direct the flow of a program are if, elif and else. Which you may have guessed can be translated as if, if, if.
if a_first_condition:
action_associated_with_the_first_condition
elif another_condition:
action_associated_with_the_second_condition
else:
action_performed_by_default
Of course the syntax allows you to have as many elif as necessary, meaning from 0 to N. You can only have one else and you must start with a if. The condition objects/variables must be of type boolean or integer. Indeed Python can assimilate an integer to a boolean according to the following rule if the integer is 0 it is associated to False, if it is different from 0 it is associated to True.
Important : syntax rule
You may have noticed it :
at the end of each line if, elif, else there is the character “:”
there is no keyword to specify the end of the control structure (no endif) the command lines located within the control structure (under the if, elif, else commands) are indented.
This is a fundamental concept in Python, all instruction blocks start with the character “:” and are delimited by the indentation level of the code. For example:
if une_condition:
## Start of statements executed if the condition "a_condition" is true
a = 2
print(a)
b = 3
print(b)
## End of the instructions contained in the if
### Resume the executed code whether we pass in the if or not
a = 234
b = a**3
print( b )
By following this indentation rule it is quite possible to nest several blocks of if, elif, else statements within each other. For example:
if condition_1:
if sub_condition_11:
an_action
elif sub_condition_12:
an_other_action
else:
yet_an_other_action
elif condition_2:
if sub_condition_21:
pass
elif:
one_action
else:
one_action
You can see the keyword pass
appearing. This keyword in fact serves no purpose, since it does not perform any action. Its only interest is to allow to respect the syntax rules. In the previous case it allows to define a elif block associated to a if block which does not perform any action.
Comment on the indentation :
For indentations in your code you can use :
The tab key
An arbitrary number of spaces (usually 4)
However, be careful not to mix tabs and spaces in your code, otherwise you will get an error when you run the code. Most text editors automatically replace tabs with 4 spaces. However, some editors under Windows in particular do not do this, which can lead to errors. The error message returned by Python is quite explicit and is of the form
TabError : inconsistent use of tabs and spaces in indentation