Python basics
Python was conceived in the late 1980s by Guido van Rossum. Python 3.0 final was released on December 3rd, 2008.
So please use python3 😉 #nomorepython2
Its name is based on the "Monty Python".
Python is :
an interpreted language
strongly typed and dynamically typed
note : python can also be statically typed through
type hintingNote: some languages are weakly typed (JavaScript), some are strongly typed (Python) and some are statically typed (Go, Rust). Being strongly typed means you can't perform operations inappropriate to the type, so for example: in Python you can't add a number typed variable with a string typed variable.
garbage collected
ZEN of python
A collection of 19 principles that influence the conception and usage of the language.
CPython
CPython ? What is that ?
CPython is the reference implementation of the Python programming language. Written in C and Python, CPython is the default and most widely used implementation of the Python language.
CPython can be defined as both an interpreter and a compiler as it compiles Python code into bytecode before interpreting it.
-- Wikipedia
/!\ Everything in Python is an object.
Comments
Single line comments start with a # : # this is a comment
Multiline comments can be written using triple single-quotes ou double-quotes :
We usually use triple-quotes to write documentation, also called docstrings.
Variables
You don't need to declare a variable before using it, nor its type.
A variable stores a piece of data, and gives it a specific name.
naming
The name of a variable should use the snake_case convention.
Reading a variable name should give you a hint about its meaning.
You should not put the type of the variable in its name.
Finally, you should NOT use reserved keywords for a variable name (eg. dict, from)
Memory management (under the hood)
TODO
https://realpython.com/pointers-in-python/
primitive/native data types
the most common types are :
numbers : integers ; floating point numbers (floats) ; complex
string
list
dict
tuple
boolean (bool) :
TrueandFalseNone, 0, and empty strings/lists/dicts/tuples all evaluate toFalse
but there's a lot of other special ones :
iterators
range
bytes ; bytearray ; memoryview
frozenset
remember when we said that everything in python is an object ? all these types are objects, represented by a class.
more about what's a class later 😉
Note : all native types are available here
casting / converting a type to another one
a variable can be converted to another type, for example :
operators
Python comes with a lot of operators that you can use and combine.
You can use them with variables of the same type, and also with variables of different types.
But be careful, some operations don't exist and will raise an Exception and crash your app.
is keyword
is keyword can be a little confusing and can lead to error later if not properly used.
is checks that two variables refer to the same object (memory address).
== checks if two objects have the same value.
See the difference here ?
We can dig deeper with the help of the id function, which returns the memory address of an object.
None
None is an object. Always use is to compare a variable to None.
mutability
some sequences (tuples and strings for example) are immutable which means that you can't edit them after creation.
If you wan't to edit them, you need to reassign them.
type hinting
functions (intro)
quick explanation about functions, we're not going to too much into details here but we need to address the subject a little.
definition - def f()
call - f()
TODO
Signature
Arguments positionnels vs. Arguments mots clés
Attention au nommage
DRY / YAGNI
fonction vs procedure : fonction renvoie une valeur et une procédure exécute uniquement des commandes
LGI : Lorsque Python rencontre une variable, il va traiter la résolution de son nom avec des priorités particulières. D'abord il va regarder si la variable est locale, puis si elle n'existe pas localement, il vérifiera si elle est globale et enfin si elle n'est pas globale, il testera si elle est interne
def f(arg: type) -> None:ts("obama", False, 20, True)twitter_search(username=‘@obama’, retweets=False, numtweets=20, unicode=True)attention aux arguments par défaut
built-in functions
dir() help()
classes (intro)
wait, isn't it only the beginning of the course ? sorry again, we need to address this subject too 😃
TODO
methods
TODO
magic methods
TODO
__len__
printing
TODO
f-string
TODO
Lists
A list is a sequence object that stores an ordered sequence of objects, which can be of different types (even lists, yes).
Each element of a list can be accessed by its index (which begins at 0).
Trying to access an invalid index results in an Exception IndexError being raised.
One of the under-rated feature of python is its negative index ! If you want to access the last element of a list without having to calculate its size, use the -1 index !
also works for string obviously :
Slicing
Slicing is used to get a part of a sequence. A lot of tricks can be done with slicing.
The syntax of a slice is as followed : [<start>:<stop>:<step>].
Common list methods
.append(<value>)adds an element at the end of the list.pop()removes the last element of the list and returns it.remove(<value>)removes the first occurence of a value (or raises aValueErrorif the value can't be found).insert(<index>, <value>)adds an element at the given index.index(<value>)returns the index of the first occurence of a value (or raises aValueErrorif the value can't be found).sort()modify the list to sort it ascendingly.reverse()modify the list to put it in reverse order.count(<value>)returns the number of occurence of a value in the list
list built-in function
the list function converts an object to a list.
in keyword
The in keyword has two purposes:
check if a value is present in a
sequence(list, range, string etc.).iterate through a sequence in a
forloop
len built-in function
the len function returns the length of a sequence
del keyword
use the del keyword to delete an element with its index
common built-in functions used with lists
max(<list>)returns the maximum value in a listmin(<list>)returns the minimum value in a list
strings (again!)
a string can be seen as a list of characters (because it is a sequence) ! You can access each of its characters via their index. You can also loop on it.
Two or more string literals (i.e. the ones enclosed between quotes) next to each other are automatically concatenated.
This feature is particularly useful when you want to break long strings:
common string methods
<string>.join(<list>)creates a new string with each element of<list>, separated by<string>.upper()returns the string entirely in ALL CAPS.lower()returns the string entirely in lowercase.capitalize()returns the string with a Uppercase at the beginning.split(<separator>)splits the string using the separator and returns a list of string.startswith(<value>)checks if the string starts with the value.endswith(<value>)checks if the string ends with the value.replace(<old>, <new>, [count=-1])returns a copy of the string where the<old>part is replaced by the<new>part. By default,countis at-1meaning that all occurences of<old>will be replaced. If you want only the first occurence ofoldto be replaced, then setcountas1.find(<sub>)returns the first index where thesubstring is found
ellipsis
... in python is called ellipsis. It is a string literal.
One of its main purpose is placeholding (just like pass). For example if you declare a class without attribute (like a custome Exception for example), you can use the ellipsis as a placeholder.
But the no-op instruction pass is prefered and much older than the ellipsis so use pass instead 😃
tuples
Tuples are like lists but are immutable and are written with parenthesis.
unpacking
a sequence can be unpacked into variables.
Unpacking is powerful tool !
dictionaries / dict
A dict is a key/value datastructure, created by placing a sequence of elements within curly braces {}.
Keys of a dict needs to be immutable (int, float, string, tuple). But a dict is not immutable.
You can access an element using square brackets and the key. [<key>]
When the element is nested, combined multiple square brackets.
To add or edit an element, also use square brackets + the = assign operator.
common dict methods
.keys()returns a list of all the keys.values()returns a list of all the values.items()returns a list of tuples which are the couples ,.get(<key>, [default])returns an element for a key, if the key does not exist,Noneis returned, except if adefaultis provided.setdefault(<key>, <value>)set a default value for a key if it's not already set.update({"four":4})merges two dictionaries
in keyword
the in keyword can be used to check if an element is a key of a dict.
del keyword
you can use the del keyword to delete a key in a dict.
trying to delete a key that doesn't exist raises a KeyError exception.
unpacking (again!)
Since python 3.5, you can now unpack elements in a dict, resulting in a merge or an addition !
sets
a set is a collection of unique elements. You can add multiple times the same element, but there will be only one occurence of this element in the set.
a set can be instancied with the function set or with curly braces (like a dict) {}.
a set can contain only immutable elements (strings, tuples, ints...) (like the keys of a dict).
Like a mathematical set, we can do mathematical operations such as intersection &, union |, difference - ...
in keyword
the in keyword can be used to check if an element exists in a set, and to iterate.
pointers, pass-by-value, pass-by-reference
We need to talk about how python variables are passed between functions etc...
Python is "pass-by-object-reference"
This is equivalent to “object references are passed by value".
The variable is not the object.
Let's dig deeper. Take a look at the following examples and try to guess the answer :
now what about this example :
but what if we want b to be a copy of a and not a reference to it ? 😉
we can use the .copy() method (or use a trick with slicing)
but be careful, with a "simple" copy like this, we don't clone the elements in the list, we just make new pointers to them.
if you modify the new list, elements in the old list will be affected too ! this is called a shallow copy.
if we really want to clone the entire list, we must create a deep copy with the copy module and its function deepcopy() :
but what does it all mean ? well, you must remember that when you pass a list to a function, you pass the address of this list, so it can be modified by the function. And sometimes you don't want that.
Here's an example :
the previous example can be confusing because the local variable of the function has the same name as the the other variable (l).
we can rewrite it for more clarity :
BUT when you don't know how python works, you can think that this list will not be modified simply because it doesn't have the same name (not true !)
so here's the final ~straw~ example 😃
you choosed answer 2, well done !
answer 1, yikes ! please read this chapter again 😃 (or drop an email)
source :
range built-in function
range is a powerful function, which can be used in various ways :
generate a sequence of numbers from 0 to
<stop>-1withrange(<stop>)generate a sequence of numbers from
<start>to<stop>(with an optional<step>) withrange(<start>, <stop>, [step])
(Want to see its source code ? https://github.com/python/cpython/blob/5fcfdd87c9b5066a581d3ccb4b2fede938f343ec/Objects/rangeobject.c#L76)
conditions
TODO If / elif / else break continue
loops
TODO ok
For la clause else # equivalent to a if no break Si objet séquentiel Si vous utilisez les index, cest que vous le faites surement pas bien range function enumerate function While
exercice : create a program which takes in input a number of lines, and print a pyramid.
dict
loop over keys
loop over key and value
cornercase avec cette façon de faire ? On ne peut pas muter un dict lorsque l’on itère dessus
préférer :
functions (again!)
*args and **kwargs
When a final formal parameter of the form **name is present, it receives a dictionary (see Mapping Types — dict) containing all keyword arguments except for those corresponding to a formal parameter. This may be combined with a formal parameter of the form *name (described in the next subsection) which receives a tuple containing the positional arguments beyond the formal parameter list. (*name must occur before **name.) For example, if we define a function like this:
It could be called like this:
and of course it would print:
type annotation
Function annotations are completely optional metadata information about the types used by user-defined functions.
Annotations are stored in the annotations attribute of the function as a dictionary and have no effect on any other part of the function.
comprehension
TODO dict {k:k**2 for k in range(10)}
modules/packages/libraries
TODO
file handling
TODO
Bonnes pratiques
TODO
PEP8
Google styling guide
Documentation
TODO peut etre merge avec commentaires ? pour parler doctstring etc ?
DRY
YAGNI
Advanced
protocol
TODO
In Python a protocol is an informal interface. Protocols are either known as an accepted truth or defined in documentation and not strictly in code1. For example, any class that implements the __container__() special method is said to follow the "container protocol." While this is an accepted truth, there is no syntax in the Python language that declares a class as following a protocol. Python classes can also implement multiple protocols.
decorators
TODO
iterators
TODO
context manager
TODO
exceptions - try/except
Analogy : Imagine that you order something on the web, and during the delivery you're not at home. Error handling in this context means that the delivery company should be able to deliver your package another time/place so you can have it.
TODO
generators
TODO
OOP
TODO
functional
TODO
Design patterns
TODO
a design pattern is a general repeatable solution to a commonly occurring problem in software design. A design pattern isn't a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations.
Threading
TODO
GIL
Testing
TODO
env
TODO
RESTE A FAIRE
affichage print signature d'une fonction help() function __dir__ method fstring
conditions if /elif / else == != > >= < <= continue saute à l’itération suivante break stoppe la boucle
boucle si vous utilisez des index, cest que vous le faites probablement pas bien for for i in range(len(colors)): print(colors[i])
dir() help() - how to use it + how does it work (docstrings) sorted() - sorted(, key)
fonction (vs procedure) signature portée LGI anonyme DRY passage d'arguments renvoi de résultats arguments positionnels vs. arguments par mots clés twitter_search("@obama", False, 20, True) twitter_search("@obama", retweets=False, numtweets=20, popular=True)
tuples NamedTuples (subclass of tuple) unpacking : p = 'pommes', 30, 1 produit, quantite, prix = p
dictionnaires fundamental relationships, linking, counting, grouping
fichier binaire modules / package docstring
iterators
context manager with
one liner : 1 ligne de code = 1 phrase en francais
bonnes pratiques pep8 (syntaxe) pep257 pep20
python : everything is an object
decorateurs try except comprehension generateurs magic methods
DRY YAGNI
classes interfaces conventions (snake case, globals in all-caps) "pythonic" code https://www.python.org/dev/peps/pep-0008/ https://google.github.io/styleguide/pyguide.html
Voici quelques conseils pour vous aider à concevoir un script Python.
Réfléchissez avec un papier, un crayon... et un cerveau (voire même plusieurs) ! Reformulez avec des mots en français (ou en anglais) les consignes qui vous ont été données ou le cahier des charges qui vous a été communiqué. Dessinez ou construisez des schémas si cela vous aide.
Découpez en fonctions chaque élément de votre programme. Vous pourrez ainsi tester chaque élément indépendamment du reste. Pensez à écrire les docstrings en même temps que vous écrivez vos fonctions.
Quand l’algorithme estc omplexe, commentez votre code pour expliquer votre raisonnement. Utiliser des fonctions(ou méthodes) encore plus petites peut aussi être une solution.
Documentez-vous. L’algorithme dont vous avez besoin existe-t-il déjà dans un autre module ? Existe-t-il sous la forme de pseudo-code ? De quels outils mathématiques avez-vous besoin dans votre algorithme ?
Si vous créez ou manipulez une entité cohérente avec des propriétés propres, essayez de construire une classe.
Utilisez des noms de variables explicites, qui signifient quelquechose. En lisant votre code, on doit comprendre ce que vous faites. Choisir des noms de variables pertinents permet aussi de réduire les commentaires.
Quand vous construisez une structure de données complexe (par exemple une liste de dictionnaires contenant d’autres objets), documentez et illustrez l’organisation de cette structure de données sur un exemple simple.
Testez toujours votre code sur un jeu de données simple pour pouvoir comprendre rapidement ce qui se passe. Par exemple, une séquence de 1000 bases est plus facile à gérer que le génome humain ! Cela vous permettra également de retrouver plus facilement une erreur lorsque votre programme ne fait pas ce que vous souhaitez.
Lorsque votre programme « plante », lisez le message d’erreur. Python tente de vous expliquer ce qui ne va pas. Le numéro de la ligne qui pose problème est aussi indiqué.
Discutez avec des gens. Faites tester votre programme par d’autres. Les instructions d’utilisation sont-elles claires ?
Si vous distribuez votre code :
Rédigez une documentation claire.
Testez votre programme (jetez un œil aux tests unitaires 10).
Précisez une licence d’utilisation. Voir par exemple le site Choose an open source license