Un script Python est un fichier texte enregistré avec l'extension .py
que l'on peut créer par exemple avec un simple éditeur de texte comme le bloc note de Windows. Mais il est plus pratique d'utiliser un éditeur adapté pour l'écriture de scripts, comme Notepad++, PyScripter, Geany ou Bluefish.
Le langage Python est multi-paradigme, c'est-à-dire qu'il admet plusieurs manières différentes de traiter les problèmes. Les structures de contrôle (branchement conditionnel, boucles) permettent une programmation impérative en enchainant des instructions. La définition de fonctions réduit les répétitions dans le code et ouvre le champ à la programmation fonctionnelle. Mais surtout Python offre un cadre clair pour découvrir la programmation orientée objet : la structure des objets modélisés (atome, opération comptable, grammaire linguistique, variété algébrique, génôme…) est transcrite directement dans le code, avec les propriétés, relations et opérations associées.
Toutes ces approches ne sont pas incompatibles et un script Python peut très bien commencer par une déclaration d'objets, utiliser le lambda-calcul et se terminer par un algorithme impératif.
Un script Python n'a pas besoin d'une en-tête a priori, mais il est utile d'indiquer sur la première ligne le chemin d'accès vers l'interpréteur lorsqu'il est connu, précédé du shebang #!
. On peut même préciser la version de Python avec laquelle le script doit être exécuté.
Sur la deuxième ligne, il est important de spécifier la norme de codage utilisée pour la saisie du programme, surtout si on y emploie des caractères accentués, d'autres signes diacritiques ou des caractères plus exotiques encore (Unicode), selon les cas ISO-8859-1
ou UTF-8
. Les deux premières lignes du programme pourront donc apparaitre comme suit :
#! /usr/bin/env python3
# -*- coding: ISO-8859-1 -*-
Contrairement à beaucoup de langages de programmation, Python ne délimite pas l'intérieur d'une boucle ou d'un branchement conditionnel à l'aide de commandes comme begin
et end
, mais par une indentation du code (en général avec quatre espaces). Les deux-points et l'indentation sont indispensables.
# Exemple d'utilisation d'un branchement conditionnel
from time import strftime
h = int(strftime('%H')) # formatage de l'heure courante
if h < 18:
print("Bonjour !")
elif h < 22:
print("Bonsoir !")
else:
print("Bonne nuit !")
# Exemple d'utilisation d'une boucle itérative
for k in range(10, 0, -1): # intervalle parcouru en décroissant
print("C'est dans %d an%s, je m'en irai," % (k, (k>1)*'s'))
print("j'entends le loup et le renard danser...")
else:
print("C'est cette année que je m'en vais...")
# Exemple d'utilisation d'une boucle conditionnelle
from random import randint
while randint(1, 6) < 6:
print("Raté.")
else:
print("Six !")
La boucle for
peut parcourir n'importe quel itérateur, entre autres les listes, uplets, chaines de caractères, dictionnaires, ensembles.
Les commandes elif
et else
sont facultatives. En sortie de boucle, elles sont même a priori inutiles mais peuvent différencier la sortie normale (fin de parcours de l'itérateur ou négation de la condition de boucle) d'une sortie sur interruption ou exception.
En effet, les boucles for
et while
peuvent être interrompues par l'instruction break
.
# Détection de la présence d'une lettre en 6 exemplaires
occurrences = {}
for c in "Supercalifragilisticexpialidocious":
if occurrences.has_key(c):
occurrences[c] += 1
if occurrences[c] == 6:
print("La lettre %s apparait au moins 6 fois." % c)
break # fin de la recherche, sortie de boucle
# pas de else pour ce branchement
else: # nouvelle lettre
occurrences[c] = 1
else: # fin du mot
print("Pas de lettre en 6 exemplaires ou plus.")
L'instruction continue
à l'intérieur d'une boucle permet de passer directement à l'étape suivante de la boucle. L'instruction pass
correspond à une action vide mais peut être utile lorsque la syntaxe exige au moins une instruction.
Une fonction est une suite d'instructions qui peuvent être appliquées à plusieurs objets donnés en paramètres et renvoyer éventuellement un résultat. Les noms des variables désignant les paramètres peuvent coïncider avec des noms de variables extérieures à la fonction sans impact sur ces dernières. Mais lorsque des objets modifiables (listes, objets…) sont passés en paramètres, ils sont susceptibles d'être modifiés lors de l'exécution de la fonction, par effet de bord.
Il existe plusieurs manières de saisir une fonction. Les différentes formes sont plus ou moins adaptées selon les contextes.
# À la manière du lambda-calcul
add = lambda x: lambda y: x+y
f = add(4)
print(f(3)) # affiche : 7
# Définition de fonction
def polynome(coeffs):
def fpolynome(x):
resultat = 0
puissance = 1
for c in coeffs:
resultat += c*puissance
puissance *= x
return resultat
return fpolynome
cube = polynome([0, 0, 0, 1])
print(cube(2)) # affiche : 8
def toutincremente(liste_nbs):
for i in range(len(liste_nbs)):
liste_nbs[i] += 1
print(toutincremente([1, 2, 4])) # affiche : None
# En effet, la fonction toutincremente ne renvoie rien.
liste = [1, 2, 4]
toutincremente(liste)
print(liste) # affiche : [2, 3, 5]
La deuxième forme de définition des fonctions permet de donner des valeurs par défaut aux paramètres, à l'aide de l'opérateur =
. Il est même possible d'indiquer par une annotation la signification de chaque argument et du résultat.
def segmente(chaine: "mot à découper", taille: "longueur des segments" = 1, reste: "il y en a un peu plus, je vous le mets ?" = True) -> "liste des segments":
resultat = []
i = 1
segment = []
for c in chaine:
segment.append(c)
if i == taille:
resultat.append(''.join(segment))
segment = []
i = 1
else:
i += 1
if segment and reste:
resultat.append(''.join(segment))
return resultat
segmente('la valse à mille temps', 3)
# affiche ['la ', 'val', 'se ', 'à m', 'ill', 'e t', 'emp', 's']
pgcd(a, b)
ppcm(a, b)
est_palindrome(texte)
syracuse(n)
n
univoyelles(texte)
GramSchmidt(u, v, w)
Plutôt que de renvoyer une liste, une fonction peut constituer un générateur dont les valeurs sont calculées successivement à chaque appel.
def premiers():
yield 2;
liste = []
n = 3
while True:
for p in liste:
if n % p == 0:
break
elif p*p > n:
yield n
liste.append(n)
break
else:
yield n
liste.append(n)
n += 2
def premier_suivant(seuil):
for p in premiers():
if p > seuil:
return p
Les classes permettent de définir des types complexes en intégrant les opérations usuelles associées. Chaque fonction définie à l'intérieur de la classe est à utiliser comme une méthode (c'est le sens du mot-clé self
). Certaines de ces fonctions (nommées avec deux caractères souligné de chaque côté) servent pour les opérateurs et les fonctions globales.
class Polynome:
"""Une classe pour les polynômes"""
def __init__(self, coeffs): # constructeur
if coeffs:
self.coeffs = list(coeffs)
else:
self.coeffs = []
k = len(self.coeffs)
for c in self.coeffs[::-1]:
k -= 1
if c:
self.deg = k
break
else:
self.deg = float(-inf)
def ev(self, x):
"""Évaluation en un scalaire."""
resultat = 0
puissance = 1
for c in self.coeffs:
resultat += c*puissance
puissance *= x
return resultat
def __repr__(self, indeterminee = 'X'): # pour fonction print
return ''.join([
(' + ' if c > 0 else ' - ')
+ (str(abs(c)) if k == 0
else (('' if abs(c) == 1 else str(abs(c)))
+ indeterminee + ('^' + str(k) if k > 1 else '')))
for (k,c) in list(zip(range(self.deg+1),self.coeffs))[::-1]
if c]).strip(' +')
def __add__(self, other): # pour opérateur +
coeffs = [a+b for (a, b) in zip(self.coeffs, other.coeffs)]
if self.deg > other.deg:
coeffs += self.coeffs[len(other.coeffs)-1:self.deg+2]
else:
coeffs += other.coeffs[len(self.coeffs)-1:other.deg+2]
return Polynome(coeffs)
def derive(self):
"""Construction du polynome dérivé."""
k = 0
coeffs = []
for c in self.coeffs[1:]:
k += 1
coeffs.append(k*c)
return Polynome(coeffs)
P = Polynome([4, 3, -0.5, 0, 2])
print(P.derive()) # affiche 8X^3 - X + 3
Atome
avec les champs symbole
, Z
(numéro atomique), valence
, puis construire quelques atomes.Repere
avec des champs précisant une position et une orientation dans l'espace, puis définir les fonctions de mouvement avant, lacet, roulis et tangage.Les exceptions permettent de gérer les erreurs d'exécution (mais pas les erreurs de syntaxe !) en renvoyant un code d'erreur qui pourra être traité à un niveau supérieur.
import math
def sinc(x):
try:
return math.sin(x)/x
except ZeroDivisionError:
return 1
def moyenne(liste):
if len(liste)==0:
raise NameError('Liste vide')
return sum(liste)/len(liste)