text:
.. index:: cheat sheet

===================
Cheat sheet: Python
===================

.. contents::
    :local:

Ce document résume en quelques pages les éléments essentiels de la syntaxe du langage python.
Quelques lignes suffisent pour découvrir la version installée :

::

    import sys
    print (sys.version)

Avec la version *3.x*, le langage a introduit quelques changements importants qui seront précisés.
Il est préférable de choisir la version 3 plutôt que 2.7. Outre le fait qu'elle
contient les dernières évolutions, elle est beaucoup plus cohérente en ce qui concerne
les chaînes de caractères.

Le langage
==========

Quelques rappels sur le langage :

* Il n'y a pas de séparateur d'instructions, il faut écrire une instruction
  par ligne et décaler les lignes dans une boucle, un test, une fonction, une classe.
  Pour écrire une instruction sur plusieurs lignes, il faut utiliser le caractères
  `\\` sur toutes les lignes de l'instruction sauf la dernière.
  Il ne doit rien y avoir derrière ce caractère, ni espace, ni commentaires.
  Cette règle n'est nécessaire s'il s'agit d'une liste d'éléments séparés par des virgules.
* On peut mettre autant d'espaces qu'on veut. Il peut n'y en avoir aucun
  sauf derrière une instruction ``for``, ``if``, ...
* Les commentaires dans un programme commencent par le symbole ``#``
  et vont jusqu'à la fin de la ligne.
* L'instruction ``print`` permet d'afficher n'importe quelle information.
  Elle affiche le résultat de la méthode ``__str__`` pour les classes.
  **Version 3.x :** ``print`` est une fonction, tout ce qui doit être affiché
  doit l'être entre parenthèses.
* L'instruction ``help`` affiche l'aide associée à une variable, une fonction,
  une classe, une méthode, un module. Pour une fonction, une classe,
  une méthode du programme, cette aide correspond à une chaîne de caractères
  encadrée par trois ``"``. Ce message d'aide peut s'étaler sur plusieurs lignes.

.. runpython::
    :showcode:

    def fonction () :
         """fonction de
         démonstration"""
         return 0
    help (fonction)

**2 astuces en cas de problème**

En cas de doute sur une partie de code, un calcul, une priorité entre
opérateurs, le résultat d'une fonction, il est possible d'utiliser
la fonction ``print`` pour afficher une valeur intermédiaire pendant un calcul.
Il ne faut pas non plus hésiter à vérifier sur un petit exemple dans
un petit programme que des lignes douteuses font exactement ce pour quoi elles ont été écrites.

Il est souvent utile de chercher sur Internet des exemples de
programmes pour corriger une syntaxe incorrecte, utiliser un moteur de recherche en
ajoutant une requête commençant par le mot *python*. Pour les erreurs, il est
parfois intéressant de recopier intégralement le message d'erreur sur un moteur de
recherche, les réponses obtenues sont souvent assez claires.

Les variables
=============

Le nom d'une variable commence par une lettre ou un blanc souligné,
il peut également inclure par la suite des chiffres. Python distingue les
minuscules des majuscules. La portée d'une variable, c'est-à-dire la portion
de code où elle définie, s'étend depuis sa déclaration (première affectation)
jusqu'à la fin du programme ou de la fonction où elle est définie.
Pour déclarer une variable portant le nom ``va``, il suffit d'écrire :

::

    va = <valeur>

Le type de ``<valeur>`` détermine le type de la variable ``va``.
Si une variable de même portée portait déjà ce nom-là, son contenu
est écrasé (perdu aussi). L'instruction ``type(x)`` retourne le type de la variable ``x``.
Un **identificateur** qu'il désigne une variable,
une fonction, une classe ou un module garde la valeur de sa dernière affectation.

Les types immuables
+++++++++++++++++++

Les variables de type immuable ne peuvent pas être modifiées.

* ``None``, ce type veut dire rien, il est utilisé comme convention
  de programmation pour dire qu'un algorithme, un calcul ne s'est pas terminé
  correctement ou une valeur n'a pas encore été calculée.
* ``bool`` : un booléen (résultat d'un test)
* ``int`` : un entier
* ``float`` : un réel
* ``complex`` : un complexe
* ``str`` : une chaîne de caractères ou string, elle apparaît entre guillemets,
  entre apostrophes, entre trois guillements (``"""``) si elle s'étend sur
  plusieurs lignes. ``s = "exemple"``.
  **Version 2.7 :** il existe un autre type ``unicode`` utilisé pour représenter des
  chaînes de caractères non latines (en chinois par exemple).
* ``tuple`` : un vecteur d'éléments de types identiques ou différents,
  il apparaît entre parenthèses, on accède à un de ses éléments à l'aide de
  crochets. Les éléments d'un t-uple ``t`` sont indicés de 0 à ``len(t)-1`` inclus.

  ::

        t = ()        # tuple vide
        t = (2, "e")  # tuple de deux éléments
        print(t[0])   # affiche le premier élément

L'affectation d'une valeur de type immuable à une variable est une copie.
On peut appliquer sur les types numériques les opérations usuelles
(``+ * - / \% ** += *= -= /= \%= **=``)
``**`` est le symbole pour puissance : ``3 ** 4`` = :math:`3^4`.
On rappelle que ``a += 10`` est équivalent à ``a = a + 10``, ceci signifie que la
valeur de ``a`` avant le calcul n'a plus besoin d'exister.
Le *et* logique et le *ou* logique sont notés ``and`` et ``or``.
Les priorités sont celles usuellement utilisées en mathématique,
en cas de doute, il faut utiliser des parenthèses.

Les opérateurs de comparaison (``< > == <= >=``) s'appliquent sur tous
les types numériques ainsi que sur les chaînes de caractères.
**Rappel :** les minuscules sont classées après les majuscules.

.. runpython::
    :showcode:

    print('A' < 'a')

**Fréquente source de bug :**

* **Version 2.7 :** une division entière a pour résultat le quotient
  et non un nombre décimal. Autrement dit : ``1/2 = 0`` et non ``0.5``.
* **Version 3.x :** une division entière a pour résultat un réel.
  Autrement dit : ``1/2 = 0.5``. Pour une division entière, il faut utiliser
  ``//`` : ``1//2 = 0``.

Pour convertir une information d'un type à un autre, il suffit
d'utiliser le nom de ce type suivi de la valeur à convertir
entre parenthèses : ``b = float ("2.145")`` équivaut à la
conversion d'une chaîne de caractères en réel.

L'addition d'un t-uple et d'une valeur retourne un t-uple incluant
cette valeur à la fin (plus long d'un élément). L'addition de deux
t-uples concatène les deux t-uples. L'addition de deux chaînes de
caractères retourne leur concaténation.

Pour savoir si un élément ``x`` fait partie d'un t-uple ``t``,
il faut utiliser la syntaxe ``x in t`` dont la réciproque
est ``x not in t``.

La fonction `len <https://docs.python.org/3/library/functions.html#len>`_
retourne la longueur d'un tuple ou d'une
chaîne de caractères. Les éléments ou les caractères d'un tuple
ou d'une chaîne de caractères ``t`` sont indicés de 0 à ``len (t)-1`` inclus.

::

    t[i:j]  # correspond à un sous-ensemble allant des indices i à j exclu
    t[:j]   #  = t[0:j]
    t[i:]   # = t [i: len (t)]

Pour les chaînes de caractères, on utilise fréquemment les
méthodes suivantes :

::

    st = "langage python"
    st = 'langage python'           # idem
    st = 'un guillement "'          # chaîne contenant un guillement
    st = "un guillement \""         # chaîne contenant un guillement, il faut ajouter \
                                    #     pour ne pas confondre avec l'autre guillement
    st = st.upper ()                # mise en lettres majuscules
    i  = st.find ("PYTHON")         # on cherche "PYTHON" dans st
    print (i)                       # affiche 8  Version 3.x, écrire print (i),
                                    #    pour la version 2.x, écrire print i
    print (st.count ("PYTHON"))     # affiche 1  Version 3.x : idem print (...)
    print (st.count ("PYTHON", 9))  # affiche 0  Version 3.x : idem print (...)

.. list-table::
    :widths: 10 20
    :header-rows: 0

    * - ``count( sub[, start[, end]])``
      - Retourne le nombre d'occurences de la chaîne de caractères ``sub``,
        les paramètres par défaut ``start`` et ``end`` permettent de réduire la
        recherche entre les caractères d'indice ``start`` et ``end`` exclu. Par défaut,
        ``start`` est nul tandis que ``end`` correspond à la fin de la chaîne de caractères.
    * - ``find( sub[, start[, end]])``
      - Recherche une chaîne de caractères ``sub``,
        les paramètres par défaut ``start`` et ``end`` ont la même signification
        que ceux de la fonction ``count``. Cette fonction retourne -1 si
        la recherche n'a pas abouti.
    * - ``isalpha()``
      - Retourne ``True`` si tous les caractères sont des lettres, ``False`` sinon.
    * - ``isdigit()``
      -  Retourne ``True`` si tous les caractères sont des chiffres, ``False`` sinon.
    * - ``replace( old, new[, count])``
      - Retourne une copie de la chaîne de caractères en remplaçant toutes les
        occurrences de la chaîne ``old`` par ``new``. Si le paramètre optionnel
        ``count`` est renseigné, alors seules les ``count`` premières occurrences
        seront remplacées.
    * - ``split( [sep [,maxsplit]])``
      - Découpe la chaîne de caractères en se servant de la chaîne ``sep`` comme
        délimiteur. Si le paramètre ``maxsplit`` est renseigné, au plus ``maxsplit``
        coupures seront effectuées.
    * - ``upper()``
      - Remplace les minuscules par des majuscules.
    * - ``lower()``
      - Remplace les majuscules par des minuscules.
    * - ``join ( li )``
      - ``li`` est une liste,
        cette fonction agglutine tous les éléments d'une liste séparés par ``sep``
        dans l'expression ``sep.join ( ["un", "deux"])``.

Quelques fonctions s'appliquant aux chaînes de caractères, l'aide associée au langage python
fournira la liste complète. Certains des paramètres sont encadrés par des crochets,
ceci signifie qu'ils sont facultatifs.
L'affichage de réels nécessite parfois de tronquer la partie
décimale ce qui est fait grâce à la syntaxe suivante :

.. runpython::
    :showcode:

    x = 0.123456789
    print ("%1.2f" % x)    # donne 0.12
    s = "%2.2e %s" % (3.14159, "est une approximation de pi")
    print (s)              # Version 2.x : print s

Les types modifiables
=====================

python fournit deux types modifiables : les listes et les dictionnaires.
Pour ces deux types, **il faut faire attention à chaque affectation**.

::

    a = [1,2]
    b = a

La seconde ligne ne fait pas une copie de la première liste,
elle ne fait que créer un second nom pour nommer la même liste.
Pour copier une liste ou un dictionnaire, il faut utiliser :

::

    a = [1,2]
    import copy
    b = copy.copy (a)

ou, si la liste inclut également d'autres listes ou dictionnaires :

::

    a = [1,2]
    import copy
    b = copy.deepcopy (a)

Cette remarque s'applique à tout type modifiable, liste, dictionnaire ou
tout autre classe. La suppression d'une variable n'implique pas la
suppression de toutes les variables se référant à une seule et
même instance de classe.

Liste
+++++

Une liste est une sorte de tableau qui permet de mémoriser
un ensemble d'éléments de types variés. C'est une sorte de t-uple modifiable.

::

    x = [4,5]               # création d'une liste composée de deux entiers
    x = ["un",1,"deux",2]   # création d'une liste composée deux chaînes de caractères
                            # et de deux entiers, l'ordre d'écriture est important
    x = [3,]                # création d'une liste d'un élément, sans la virgule,
                            # le résultat reste une liste
    x = [ ]                 # crée une liste vide
    x = list ()             # crée une liste vide

Opérations qu'une liste supporte.

.. list-table::
    :widths: 10 20
    :header-rows: 0

    * - ``x in s``
      - vrai si ``x`` est un des éléments de ``l``
    * - ``x not in s``
      - réciproque de la ligne précédente
    * - ``l + t``
      - concaténation de ``l`` et ``t``
    * - ``l * n``
      - concatène ``n`` copies de ``l`` les unes à la suite des autres
    * - ``l[i]``
      - retourne le ième élément de ``l``,
        à la différence des T-uples, l'instruction ``l [i] = "3"``
        est valide, elle remplace l'élément ``i`` par 3.
    * - ``l[i:j]``
      - retourne une liste contenant les éléments de ``l`` d'indices ``i`` à
        ``j`` exclu. Il est possible de remplacer cette sous-liste par une autre en
        utilisant l'affectation `` l[i:j] = l2 `` où ``l2``
        est une autre liste (ou un T-uple) de dimension différente ou égale.
    * - ``l[i:j:k]``
      - retourne une liste contenant les éléments de ``l`` dont les
        indices sont compris entre ``i`` et ``j`` exclu, ces indices sont espacés
        de ``k`` (le pas) : ``i, i+k, i+2k, i+3k, ...``
        Ici encore, il est possible d'écrire l'affectation suivante :
        ``l[i:j:k] = l2`` mais ``l2`` doit être une liste
        (ou un T-uple) de même dimension que ``l[i:j:k]``
    * - ``len(l)``
      - nombre d'éléments de ``l``
    * - ``min(l)``
      - plus petit élément de ``l``, résultat difficile à prévoir
        lorsque les types des éléments sont différents
    * - ``max(l)``
      - plus grand élément de ``l``, résultat difficile à prévoir
        lorsque les types des éléments sont différents
    * - ``sum(l)``
      - retourne la somme de tous les éléments
    * - ``del l [i:j]``
      - supprime les éléments d'indices entre ``i`` et ``j`` exclu.
        Cette instruction est équivalente à ``l [i:j] = []``.
    * - ``list(x)``
      - convertit ``x`` en une liste quand cela est possible

Opérations disponibles sur les listes, identiques à celles des T-uples,
on suppose que ``l`` et ``t`` sont des listes, ``i`` et ``j`` sont des entiers.
``x`` est quant à lui quelconque.

.. list-table::
    :widths: 10 20
    :header-rows: 0

    * - ``l.count (x)``
      - Retourne le nombre d'occurrences de l'élément ``x``.
        ``count`` est une méthode de la classe ``list``.
    * - ``l.index (x)``
      - Retourne l'indice de la première occurrence de l'élément ``x``
        dans la liste ``l``. Si celle-ci n'existe, une exception est
        déclenchée.
    * - ``l.append (x)``
      - Ajoute l'élément ``x`` à la fin de la liste ``l``. Si ``x``
        est une liste, cette fonction ajoute la liste ``x`` en tant qu'élément,
        au final, la liste ``l`` ne contiendra qu'un élément de plus.
    * - ``l.extend (k)``
      - Ajoute tous les éléments de la liste ``k`` à la liste ``l``.
        La liste ``l`` aura autant d'éléments supplémentaires qu'il y en a
        dans la liste ``k``.
    * - ``l.insert(i,x)``
      - Insère l'élément ``x`` à la position ``i`` dans la liste ``l``.
    * - ``l.remove (x)``
      - Supprime la première occurence de l'élément ``x`` dans la liste ``l``.
        S'il n'y a aucune occurrence de ``x``, cette méthode déclenche
        une exception.
    * - ``l.pop ([i])``
      - Retourne l'élément ``l[i]`` et le supprime de la liste. Le
        paramètre ``i`` est facultatif, s'il n'est pas précisé, c'est le dernier
        élément dont la valeur est d'abord retournée puis il est supprimé de la liste.
    * - ``l.reverse (x)``
      - Retourne la liste, le premier et dernier élément échangent leurs places,
        le second et l'avant dernier, et ainsi de suite.
    * - ``l.sort([key=None, reverse=False])``
      - Cette fonction trie la liste par ordre croissant. Le paramètre ``f``
        est facultatif, il permet de préciser une fonction qui associe une clé de tri à
        chaque élément. Le paramètre *reverse* permet de trier dans un sens ou dans l'autre.

Opérations permettant de modifier une liste
on suppose que ``l`` est une liste,  ``x`` est quant à lui quelconque.
Les listes peuvent aussi être définies à partir d'une écriture abrégée :

.. runpython::
    :showcode:
    :process:

    li = list(range(0,5))                # liste des entiers de 0 à 5 exclu
    y = [i for i in li if i % 2 == 0]    # sélection des éléments pairs
    print(y)
    z = [i+j for i in li for j in li]    # construit tous les nombres i+j possibles
    print(z)

Dictionnaire
++++++++++++

Un dictionnaire est un tableau pour lequel les indices ou clés
ne sont pas uniquement des entiers mais tout type non modifiable
(le plus souvent un entier, un réel, une chaîne de caractères, un t-uple).

.. runpython::
    :showcode:

    x = { "cle1": "valeur1", "cle2": "valeur2" }
    print(x ["cle1"])
    x [(0,1)] = "clé tuple"   # ajoute une nouvelle valeur dont la clé est (0,1)
                              #   les parenthèses sont superflues
    print(x)
    y = { }                   # crée un dictionnaire vide
    z = dict ()               # crée aussi un dictionnaire vide

Opérations qu'un dictionnaire supporte.

.. list-table::
    :widths: 10 20
    :header-rows: 0

    * - ``x in d``
      - vrai si ``x`` est une des clés de ``d``
    * - ``x not in d``
      - réciproque de la ligne précédente
    * - ``l[i]``
      - retourne l'élément associé à la clé ``i``
    * - ``len(d)``
      - nombre d'éléments de ``d``
    * - ``min(d)``
      - plus petite clé
    * - ``max(d)``
      - plus grande clé
    * - ``del l [i]``
      - supprime l'élément associé à la clé ``i``
    * - ``list (d)``
      - retourne une liste contenant toutes les clés du dictionnaire ``d``.
    * - ``dict (x)``
      - convertit ``x`` en un dictionnaire si cela est possible,
        en particulier, ``d`` est égal à ``dict(d.items())``

Opérations disponibles sur les dictionnaires, ``d`` est un dictionnaire,
``x`` est quant à lui quelconque.

.. list-table::
    :widths: 10 20
    :header-rows: 0

    * - ``d.copy()``
      - Retourne une copie de ``d``.
    * - ``x in d``
      - Retourne ``True`` si ``x`` est une clé de ``d``.
    * - ``d.items()``
      - Retourne un itérateur parcourant contenant tous les couples (clé, valeur)
        inclus dans le dictionnaire. Pour obtenir une liste, il faut écrire
        ``list(d.items())``.
        **Version 2.x :** retourne une liste.
    * - ``d.keys()``
      - Retourne un itérateur parcourant toutes les clés du dictionnaire ``d``.
        **Version 2.x :** retourne une liste.
    * - ``d.values()``
      - Retourne un itérateur parcourant toutes les valeurs du dictionnaire ``d``.
        **Version 2.x :** retourne une liste.
    * - ``d.get(k[,x])``
      - Retourne ``d[k]``, si la clé ``k`` est manquante, alors
        la valeur ``None`` est retournée à moins que le paramètre optionnel ``x``
        soit renseigné, auquel cas, ce sera ce paramètre qui sera retourné.
    * - ``d.clear()``
      - Supprime tous les éléments du dictionnaire.
    * - ``d.update(d2)``
      - Pour chaque clé de ``d1``, ``d[k] = d2[k]``
    * - ``d.setdefault(k[,x])``
      - Retourne ``d[k]`` si la clé ``k`` existe, sinon, affecte ``x`` à ``d[k]``.
    * - ``d.popitem()``
      - Retourne un élément et le supprime du dictionnaire.

Méthodes associées aux dictionnaires, ``d``, ``d2`` sont des dictionnaires,
``x`` est quant à lui quelconque.

Tableaux numériques
+++++++++++++++++++

Ce type ne fait pas partie du langage python standard mais il est couramment utilisé.

::

    import numpy
    a = numpy.array ( [0,1] )

Il permet de convertir des listes en une structure plus appropriée au calcul
qui sont nettement plus rapides. En contrepartie, il n'est pas aussi
rapide d'ajouter ou supprimer des éléments.

Tests et boucles
================

Tests
+++++

Les tests permettent d'exécuter telle ou telle instruction selon
la valeur d'une condition. Le test est suivi de ``:`` et les
instructions dépendant de ce test sont indentées (décalées vers la droite).

::

    if x < 5 :
        x = x * 2
        ...

Il peut y avoir une contrepartie :

::

    if x < 5:
        x = x * 2
        ...
    else:
        x = x * 3
        ...

S'il n'y a qu'une seule instruction, elle peut s'écrire en bout de ligne :

::

    if x < 5:
        x = x * 2
    else:
        x = x * 3

Il peut y avoir plusieurs conditions qui s'enchaînent :

::

    if x < 5:
        x = x*2
    elif x > 5:
        x = x*3
    else:
        x = x*6

Il existe un raccourci pour les intervalles :

::

    if 5 < x and x < 10 :     # peut être écrit : if 5 < x < 10 :
        ...

Boucles
+++++++

Il y a deux types de boucles, la boucle ``for`` parcourt un ensemble,
la boucle ``while`` continue tant qu'une condition est vraie.
Comme pour les tests, une boucle est suivie du syumbol ``:``,
les lignes incluses dans cette boucle sont indentées à moins qu'il
n'y en ait qu'une seule, auquel cas elle peut être écrite après
le symbole ``:`` sur la même ligne.

::

    while condition :
        # lignes décalées
        # contenu de la boucle

Quelques exemples de boucles ``for`` :

::

    for i in range(0,n) :             # parcourt tous les entiers de 0 à n-1 inclus
    for i in xrange(0,n) :            # même chose mais en plus rapide
                                      # Version 3.x : la fonction xrange n'existe plus,
                                      #               et range équivaut à xrange
    for i in range(n,0,-1) :          # parcourt tous les entiers de n à 1 inclus
                                      #                  dans le sens décroissant
    for i in range(2,1000,3) :        # parcourt tous les entiers de 2 à 1000 de 3 en 3
                                      #                                     (2,5,8,...)
    for e in li :                     # parcourt tous les éléments de la liste li
    for cle,valeur in di.items() :    # parcourt tous les éléments du dictionnaire di

Pour toutes les boucles, l'instruction ``break`` permet de sortir de la
boucle, l'instruction ``continue`` passe directement à l'itération suivante
sans exécuter les instructions qui suivent l'instruction ``continue``.

Fonction ``enumerate``
++++++++++++++++++++++

On peut écrire :

::

    l = [ 4, 5, 6 ]
    s = 0
    for i in range(0,len(l)) :
        s += l[i]

Ou utiliser la fonction
`enumerate <https://docs.python.org/3/library/functions.html#enumerate>`_
qui retourne chaque élément et sa position dans l'ensemble :

::

    l = [ 4, 5, 6 ]
    s = 0
    for i,x in enumerate(l) :
        s += x

Fonction ``zip``
++++++++++++++++

Pour faire la somme de deux listes terme à terme, on peut écrire :

::

    l = [ 4, 5, 6 ]
    g = [ 3,10,11 ]
    s = 0
    for i in range(0,len(l)) :
        s += l[i] + g[i]

Ou utiliser la fonction `zip <https://docs.python.org/3/library/functions.html#zip>`_ :

::

    l = [ 4, 5, 6 ]
    g = [ 3,10,11 ]
    s = 0
    for x,y in zip(l,g) :
        s += x + y

Fonction ``map``
++++++++++++++++

Il est possible d'éviter une fonction pour éviter d'écrire une
boucle avec la fonction `map <https://docs.python.org/3/library/functions.html#map>`_.
Elle applique une fonction à chaque élément d'un ensemble.

.. runpython::
    :showcode:

    def fonction (x):
        return x % 2

    li  = [ 3,4,5]
    li2 = map (fonction, li)
    print(list(li2))

A priori, l'ensemble qui en résulte contient autant d'éléments
sauf si on utilise la fonction `filter <https://docs.python.org/3/library/functions.html#filter>`_.
L'exemple suivant affiche tous les nombres pairs.

.. runpython::
    :showcode:

    def fonction(x):
        if x % 2 == 0:
            return True

    li  = [3, 4, 5]
    li2 = filter(fonction, li)
    print(list(li2))

Autres mot-clés
+++++++++++++++

Le mot-clé ``with`` est utile lorsqu'on une utilise une variable
pour une portion réduite de code. Cette notation cache deux appels
implicites à deux méthodes comme indiqué ci-dessous.

::

    with random_matrix(1000,1000) as mat :
        #   appelle mat.__enter__()
        ...
        #   appelle mat.__exit__()

Lorsque ces méthodes sont surchargées, l'utilisation de cette syntaxe
réduit la taille du code. C'est le cas des fichiers.

Fonctions
=========

Définition, paramètres
++++++++++++++++++++++

Les fonctions ou sous-programmes permettent de faire la même chose sans
avoir à recopier le code informatique plusieurs fois dans le programme.
Elles acceptent plusieurs paramètres ou aucun, elles peuvent retourner
plusieurs résultats ou aucun. Leur déclaration suit le schéma suivant :

::

    def exemple_fonction (p1, p2, p3) :
        # code de la fonction
        return r1, r2

    a,b = exemple_fonction (1,2,3)   # exemple d'appel de la fonction

L'instruction ``return`` n'est pas obligatoire mais si elle
est présente à un ou plusieurs endroits, aucune autre instruction de la
fonction ne sera exécutée après l'exécution de la première
instruction ``return`` rencontrée lors de l'exécution de la fonction.
Les fonctions peuvent être récursives et inclure des paramètres par défaut :
ces paramètres reçoivent une valeur même si celle-ci n'est pas précisée lors de l'appel.

::

    def exemple_fonction (p1, p2 = 4, p3 = 7) :
        # code de la fonction
        return r1, r2

    a,b = exemple_fonction (1)         # = exemple_fonction (1,4,7)
    a,b = exemple_fonction (1,2,3)     # = exemple_fonction (1,2,3)
    a,b = exemple_fonction (1,2)       # = exemple_fonction (1,2,7)
    a,b = exemple_fonction (1,p3 = 2)  # = exemple_fonction (1,4,2)

Les paramètres par défaut doivent tous être mis en fin de
déclaration, l'exemple suivant n'est pas correct :

::

    def exemple_fonction (p1, p2 = 4, p3) :
        # code de la fonction
        return r1, r2
    # affiche le message d'erreur : SyntaxError: non-default argument follows default argument

En ce qui concerne les paramètres, les paramètres de type non modifiable
sont passés par valeur (une modification à l'intérieur de la fonction
n'a pas de répercution à l'extérieur).

.. runpython::
    :showcode:

    def exemple_fonction (p1) :
        p1 = 3
    a = 1
    exemple_fonction (a)
    print (a)

Les paramètres de type modifiable sont passés par référence (une modification
à l'intérieur de la fonction a des répercutions à l'extérieur).

.. runpython::
    :showcode:

    def exemple_fonction (p1) :
        p1[0] = 3
    a = [1]
    exemple_fonction (a)
    print (a)

mot-clé ``lambda``
++++++++++++++++++

Le mot-clé ``lambda`` permet de définir des fonctions au sein d'une expression.

.. runpython::
    :showcode:

    def fonction (x) :
        return x % 2
    li  = [ 3,4,5]
    li2 = map (fonction, li)
    print (list(li2))

Peut-être écrit comme :

.. runpython::
    :showcode:

    li  = [ 3,4,5]
    li2 = map (lambda x : x%2, li)
    print (list(li2))

Et si on veut ajouter un paramètre à la fonction ``lambda`` :

.. runpython::
    :showcode:

    li  = [ 3,4,5]
    k   = 2
    li2 = map (lambda x, y=k: x % y, li)
    print(list(li2))

mot-clé ``yield``
+++++++++++++++++

La programmation fonctionnelle est de plus en plus utilisée.
En python, elle se décline sous la forme d'itérateur.

.. runpython::
    :showcode:

    def iterate_double_on_list(l) :
        for x in l :
            yield x*2
    print (iterate_double_on_list( [4,5,6]))

La fonction itère sur un ensemble mais ne fait rien tant qu'on ne parcourt pas l'ensemble qu'elle génère :

.. runpython::
    :showcode:

    def iterate_double_on_list(l) :
        for x in l :
            yield x*2

    for x in iterate_double_on_list( [4,5,6]) :
        print (x)

La version 3 du langage python a changé des fonctions pour qu'elle retourne
un itérateur sur un ensemble et non l'ensemble lui-même.

Classes
=======

Les classes sont un moyen de définir de nouveaux types modifiables
de variables. Peu de programmes ne les utilisent pas. Une classe est
un ensemble d'attributs (ou variables) et de méthodes (ou fonctions).
Un programme utilisant les classes est orienté objet. Il est possible
de faire les mêmes choses avec ou sans classes mais leur utilisation
rend d'ordinaire les grands programmes plus facile à comprendre et à
construire.

Déclaration d'une classe
++++++++++++++++++++++++

Pour déclarer une classe, on procède comme suit :

.. runpython::
    :showcode:
    :process:

    class ma_classe :
        def __init__ (self, att1, att2, att3) :
            self.att1 = att1
            self.att2 = att2
            self.att3 = att3
            self.att4 = att1 * att2 * att3

    a = ma_classe (-1,1,2) # déclare une variable de type ma_classe
    print (a.att1)  # affiche -1
    print (a.att2)  # affiche 3
    print (a.att3)  # affiche 4
    print (a.att4)  # affiche -12

Lors de la déclaration de la variable ``a``,
le langage python exécute la méthode ``__init__`` aussi appelée constructeur.
Elle permet de définir les attributs de la classe directement à partir
des paramètres ou comme le résultat d'un calcul ou d'une fonction.
Le constructeur comme toutes les autres méthodes possède comme
premier paramètre ``self`` qui permet d'accéder aux attributs
et aux méthodes de la classe. Le programme suivant est équivalent au premier.

.. runpython::
    :showcode:
    :process:

    class ma_classe :
        def __init__ (self, att1, att2, att3) :
            self.att1 = att1
            self.att2 = att2
            self.att3 = att3
            self.att4 = self.calcule4 ()

        def calcule4 (self) :
            return self.att1 * self.att2 * self.att3

    a = ma_classe (-1,1,2) # déclare une variable de type ma_classe
    print (a.att1)           # affiche -1
    print (a.att2)           # affiche 3
    print (a.att3)           # affiche 4
    print (a.att4)           # affiche -12

Attributs et méthodes
+++++++++++++++++++++

Les attributs sont déclarés le plus souvent à l'intérieur du
constructeur, plus généralement à l'intérieur de toute méthode,
voire à l'extérieure de la classe. Pour y faire référence à
l'intérieur d'une méthode on fait précéder le nom de l'attribut
de ``self.``, à l'extérieur de la classe, c'est le nom de l'instance
suivi d'un point ``.`` qui précède le nom de l'attribut comme le
montre le précédent exemple.

Une méthode est déclarée à l'intérieur de la classe. Elle accepte
invariablement au moins un paramètre qui est ``self`` comme dans le
précédent exemple. Les règles d'accès sont les mêmes que pour les
attributs. Elles acceptent également la récursivité et les paramètres
par défaut à l'exception du premier. Chaque instance de classe est
également munie d'un dictionnaire ``__dict__`` qui recense tous les attributs.

.. runpython::
    :showcode:
    :process:

    class ma_classe :
        def __init__ (self, att1, att2, att3) :
            self.att1 = att1                    # attribut
            self.att2 = att2                    # attribut
            self.att3 = att3                    # attribut
            self.att4 = att1 * att2 * att3      # attribut

        def calcule (self,x) :                   # méthode
            return self.att1 * self.att2 * self.att3 * x

    a = ma_classe (1,2,3)
    print (a.att1)                 # affiche 1
    print (a.__dict__ ["att1"])    # affiche aussi 1, ligne équivalente à la précédente
    print (a.calcule(2))           # appel d'une méthode

Méthodes statiques
++++++++++++++++++

Les méthodes statiques sont comme des fonctions : elle ne nécessite
pas d'instance d'un object pour être appelée.

.. runpython::
    :showcode:
    :process:

    class ma_classe :
        def __init__ (self, att1, att2, att3) :
            # ...
            pass

        @staticmethod
        def calcule_static (x,y) :         # méthode statique
            return x * y

    print (ma_classe.calcule_static(2,3))  # appel d'une méthode statique

Opérateurs
++++++++++

Les opérateurs sont des méthodes qui permettent une manipulation
plus simple des objets. Leur nom est fixé par convention par
le langage python, ils commencent et terminent par ``__``.

::

    class ma_classe :
        def __init__ (self, att1, att2, att3) :
            self.att1 = att1
            self.att2 = att2
            self.att3 = att3
            self.att4 = att1 * att2 * att3

        def __add__ (self, a) :
             return ma_classe (self.att1 + a.att1, self.att2 + a.att2, \
                           self.att3 + a.att3, self.att4 + a.att4)

    a = ma_classe (1,2,3)
    b = ma_classe (4,5,6)
    c = a + b              # n'a de sens que si l'opérateur __add__ a été redéfini

Il existe un opérateur spécifique pour chaque opération, cet opérateur
permet de donner un sens à une addition, une soustraction, ...,
de deux instances d'une classe. L'opérateur ``__str__`` retourne une
chaîne de caractères et est appelé par l'instruction ``print``.
L'opérateur ``__cmp__`` retourne un entier permettant à des
instances de la classe d'être comparées et triées par une liste.

Copie d'instances
+++++++++++++++++

Les instances de classes sont des objets modifiables, comme pour les listes,
une simple affectation ne signifie pas une copie mais un second nom pour
désigner le même objet.

.. runpython::
    :showcode:
    :process:

    class ma_classe :
        def __init__ (self, att1, att2, att3) :
            self.att1 = att1
            self.att2 = att2
            self.att3 = att3
            self.att4 = att1 * att2 * att3

    a = ma_classe (1,2,3)
    b = a
    b.att1 = -16
    print (a.att1)  # affiche -16
    print (b.att1)  # affiche -16

Il faut donc copier explicitement l'instance pour obtenir le résultat souhaité.

.. runpython::
    :showcode:
    :process:

    class ma_classe :
        def __init__ (self, att1, att2, att3) :
            self.att1 = att1
            self.att2 = att2
            self.att3 = att3
            self.att4 = att1 * att2 * att3

    a = ma_classe (1,2,3)
    import copy
    b = copy.copy (a)
    b.att1 = -16
    print (a.att1)  # affiche 1
    print (b.att1)  # affiche -16

Lorsque une classe inclut une variable de type classe,
il faut utiliser la fonction ``deepcopy`` et non ``copy``.

Héritage
++++++++

L'héritage est l'intérêt majeur des classes et de la programmation
orientée objet. Lorsqu'une classe hérite d'une autre, elle hérite
de ses attributs et de ses méthodes. Le simple fait d'hériter
crée donc une classe équivalente.

::

    class ma_classe :
        def __init__ (self, att1, att2, att3) :
            self.att1 = att1
            self.att2 = att2
            self.att3 = att3
            self.att4 = att1 * att2 * att3

    class ma_classe2 (ma_classe) :      # héritage simple
        pass                            # pour dire que la classe est vide

Mais hériter permet de faire deux choses :

#. ajouter des attributs et ajouter des méthodes
#. modifier le comportement d'une méthode existante

.. runpython::
    :showcode:
    :process:

    class ma_classe :
        def __init__ (self, att1) :
            self.att1 = att1
            self.att2 = self.calcul ()

        def calcul (self) :
            return self.att1 ** 2

    class ma_classe2 (ma_classe) :
        def calcul (self) :
            # dans cette méthode, on change le comportement
            # de la méthode calcul tout en se servant de celui
            # de la classe mère
            return ma_classe.calcul (self) * self.att1

    a = ma_classe (2)
    b = ma_classe2 (2)
    print (a.att2)   # affiche 4 = 2 * 2
    print (b.att2)   # affiche 8 = (2*2) * 2

Décorateur
++++++++++

Le langage python permet quelques simplifications de code avec
les décorateurs comme dans l'exemple suivant :

.. runpython::
    :showcode:
    :process:

    def makebold(fn):
        def wrapped():
            return "<b>" + fn() + "</b>"
        return wrapped

    def makeitalic(fn):
        def wrapped():
            return "<i>" + fn() + "</i>"
        return wrapped

    @makebold
    @makeitalic
    def hello():
        return "hello world"

    print (hello()) ## returns <b><i>hello world</i></b>

Il est possible aussi de définir des propriétés ou **properties**.
Cela permet de séparer l'affectation de l'accès à un membre d'une
classe sans changer la notation :

.. runpython::
    :showcode:
    :process:

    class C(object):
        def __init__ (self) :
            self._p = 1
        @property
        def p(self):
            return self._p
        @p.setter
        def p(self, val):
            self._p = val * 2

    obj = C()
    print (obj.p)  # utilise p_get, affiche 1
    obj.p = 5      # utilise p_set
    print (obj.p)  # utilise p_get affiche 10

Fichiers
========

L'écriture et la lecture dans un fichier s'effectuent toujours de
la même manière. On ouvre le fichier en mode écriture ou lecture,
on écrit ou on lit, puis on ferme le fichier, le laissant disponible
pour une utilisation ultérieure. Ce paragraphe ne présente pas l'écriture
ou la lecture dans un format binaire car celle-ci est peu
utilisée dans ce langage.

Ecriture dans un fichier texte
++++++++++++++++++++++++++++++

L'écriture dans un fichier texte s'effectue toujours selon le même schéma :

::

    f = open ("nom-fichier", "w") # ouverture en mode écriture "w" ou écriture ajout "a"

    f.write (  s )                # écriture de la chaîne de caractères  s
    f.write (  s2 )               # écriture de la chaîne de caractères  s2
    ...

    f.close ()  # fermeture

Certains codes sont fort utiles lors de l'écriture de fichiers texte :

* ``\n`` : passage à la ligne \\
* ``\t`` : insertion d'une tabulation, indique un passage à la colonne
  suivante dans le logiciel Excel

**Version 3.x :** une autre écriture est possible qui permet d'éviter
l'appel à la méthode ``close``.

::

    with open ("nom-fichier", "w") as f :
        f.write (  s )
        f.write (  s2 )

L'usage d'un encoding est fréquent lorsqu'on manipule des fichiers issus d'Internet.
Le plus répandu est ``utf8``. Il est spécifié en-tête des pages web
téléchargées. L'exemple qui suit n'est valable qu'avec la version 3.
Il est recommandé de l'utiliser dès qu'on manipule les encodings.

::

    with open ("nom-fichier", "w", encoding = "utf8") as f :
        f.write (  s )
        f.write (  s2 )

Lecture dans un fichier texte
+++++++++++++++++++++++++++++

La lecture est le symétrique de l'écriture. En voici un exemple,
la seule chose qui change d'un programme à l'autre est ce qu'on fait des lignes extraites.

::

    f = open ("essai.txt", "r")   # ouverture du fichier en mode lecture
    l = f.readlines ()            # lecture de toutes les lignes,
                                  #   elles sont placées dans une liste
    f.close ()                    # fermeture du fichier

    for s in l : print (s)        # on affiche les lignes à l'écran

**Version 3.x :** la même syntaxe avec le mot-clé ``with`` et l'encoding existe.

Lors le programme précédent lit une ligne dans un fichier,
le résultat lu inclut le ou les caractères
(``\backslash n \; \backslash r`` qui marquent la fin d'une ligne.
C'est pour cela que la lecture est parfois suivie d'une
étape de nettoyage.

::

    with open ("essai.txt", "r") as f:  # ouverture du fichier en mode lecture
        l = f.readlines ()              # lecture de toutes les lignes,
                                        # elles sont placées dans une liste placées dans une liste

    l_net = []                      # contiendra la liste nettoyée des lignes du fichier
    for s in l :
        s2 = s.replace ("\n", "")   # on supprime le code de fin de ligne \n
        s2 = s2.replace ("\r", "")  # on supprime le code de fin de ligne \r
                                    #                   (Windows uniquement)
          s2 = s2.strip("\r\n")       # cette ligne est équivalente aux deux précédentes
        l_net.append (s2)           # on ajoute le résultat à la liste nettoyée

Les fichiers textes ont de nombreux formats, on peut
citer HTML ou XML qui sont des formats à balises.
Leur lecture utilise des modules comme ``HTMLParser`` ou ``xml.sax``
dont la description sort du cadre de ce document.
Un autre format est souvent utilisé avec le logiciel *Excel*.
Lorsqu'on enregistre une feuille de calcul sous format texte,
le fichier obtenu est organisé en colonnes : sur une même ligne,
les informations sont disposées en colonnes délimitées par un
séparateur qui est souvent une tabulation (``\t``) ou un point virgule.

::

    nom  ; prénom ; livre
    Hugo  ; Victor  ; Les misérables
    Kessel ; Joseph  ; Le lion
    Woolf ; Virginia  ; Mrs Dalloway
    Calvino ; Italo  ; Le baron perché

Pour lire ce fichier, il est nécessaire de scinder chaque ligne en
une liste de chaînes de caractères. On utilise pour cela la
méthode ``split`` des chaînes de caractères.

::

    with open ("essai.txt", "r") as f:  # ouverture du fichier en mode lecture
        l = f.readlines ()              # lecture de toutes les lignes, placées dans une liste

    for s in l :
        s2 = s.replace ("\n", "")   # on supprime le code de fin de ligne \n
        s2 = s2.replace ("\r", "")  # on supprime le code de fin de ligne \r (Windows uniquement)
        case = s2.split (";")
        if len (case) >= 3 :
            print (case [1], " ", case [0], " a écrit ", case [2])

Modules
=======

Le concept de module permet de répartir différentes parties d'un programme sur plusieurs fichiers.
Il existe deux types de modules : ceux disponibles sur Internet (programmés par d'autres)
et ceux que l'on programme soi-même. Les premiers sont souvent fournis avec un programme
d'installation automatique ou dans le cas où ils sont manquants, des instructions
permettant de l'installer. Les seconds sont écrits dans le même répertoire que le fichier
principal. On enregistre le module suivant sous le nom ``geometrie.py``.

::

    # définition du module geometrie.py

    def carre (x) :
        return x ** 2

    class point :
        def __init__ (self,x,y) :
            self.x, self.y = x,y

        def norme (self) :
            return (self.x ** 2 + self.y ** 2) ** 0.5

Pour utiliser une fonction ou une classe du module
``geometrie.py``, on utilise une des syntaxes suivantes :

* Première syntaxe :

  ::

      import geometrie
      print (geometrie.carre (1.5))
      p = geometrie.point (1,2)

* Deuxième syntaxe :

  ::

      import geometrie as GEO  # on donne un pseudonyme au module geometrie
      print (GEO.carre (1.5))
      p = GEO.point (1,2)

* Troisième syntaxe : le module est utilisé très souvent, même un pseudonyme
  est trop long, il faut néanmoins s'assurer que les modules importés
  de cette même manière n'incluent pas des fonctions ou classes
  portant des noms identiques. Dans ce cas, c'est toujours le dernier qui gagne.

  ::

      from  geometrie import *
      print (carre (1.5))
      p = point (1,2)

Dans le cas des modules installés, les trois syntaxes d'utilisation
sont aussi valables. On voit aussi souvent apparaître dans un module la condition :

::

    if __name__ == "__main__" :
        # quelques instructions ici

Ces instructions ne sont exécutées que si le module est
utilisé en tant que programme principal. Lorsque ce fichier
est importé, elles ne sont jamais exécutées. Cela permet
d'écrire des instructions qui permettent de vérifier si le
module ne contient pas d'erreurs. Une fois cette
étape effectuée, il ne sert à rien de la répéter à chaque
fois que le module est importé. C'est pourquoi elles ne
sont exécutées que si la condition
``if __name__ == "__main__" :`` est vérifiée, c'est-à-dire si le
module est le programme principal et non un module.

Exceptions
==========

Le petit programme suivant déclenche une erreur parce qu'il effectue une division par zéro.

::

    def inverse (x):
        y = 1.0 / x
        return y
    b = inverse (0)
    print (b)

Il déclenche une erreur ou ce qu'on appelle une *exception*.

::

    Traceback (most recent call last):
      File "cours.py", line 2, in ?
        y = 1.0 / x
    ZeroDivisionError: float division

Le mécanisme des exceptions permet au programme de "rattraper"
les erreurs, de détecter qu'une erreur s'est produite et d'agir
en conséquence afin que le programme ne s'arrête pas :

.. runpython::
    :showcode:

    def inverse (x):
        y = 1.0 / x
        return y
    try :
        b = inverse (0)  # déclenche une exception
        print (b)
    except :
        print ("le programme a déclenché une erreur")

On protège la partie du code à l'aide des mots-clés ``try``
et ``except``. Entre ces deux instructions, s'il se produit
une erreur, le programme passe immédiatement à ce qui suit l'instruction
``except``. On peut même récupérer le message d'erreur correspondant :

.. runpython::
    :showcode:

    def inverse (x):
        y = 1.0 / x
        return y
    try :
        print (inverse (2))
        print (inverse (0))
    except Exception as exc:
        print ("exception de type ", exc.__class__)
             # affiche exception de type  exceptions.ZeroDivisionError
        print ("message ", exc)
             # affiche le message associé à l'exception

On peut aussi décider que le programme agira différemment selon l'erreur
produite. Dans l'exemple suivant, le programme teste d'abord si l'erreur
est de type ``ZeroDivisionError`` auquel cas il affiche le message *division par zéro*.
Pour un autre type d'erreur, il regarde s'il y a d'autres instructions
``except`` qui s'y rapportent. S'il y en a une, il exécute les
lignes qui la suivent, sinon, le programme s'arrête et déclenche une erreur.

::

    def inverse (x):
        y = 1.0 / x
        return y
    try :
        print ((-2.1) ** 3.1)
        print (inverse (2))
        print (inverse (0))
    except ZeroDivisionError:
        print ("division par zéro")
    except Exception as exc:
        print ("erreur insoupçonnée : ", exc.__class__)
        print ("message ", exc)

Les instructions ``try`` et ``except`` peuvent apparaître dans le programme
principal, dans une boucle, un test, une fonction, s'imbriquer les unes
dans les autres. Il est possible de déclencher soi-même une exception
avec l'instruction ``raise`` et ou de définir ses propres exceptions
en créant une classe héritant d'une classe d'exception.
L'exemple suivant regroupe tous ces cas.

.. runpython::
    :showcode:
    :process:

    class AucunChiffre (Exception) :
        """chaîne de caractères contenant
        aussi autre chose que des chiffres"""

        def __init__(self, s, f = "") :
            Exception.__init__(self, s)
            self.s = s
            self.f = f

        def __str__(self) :
            return """exception AucunChiffre, lancée depuis la fonction """ + self.f + \
            " avec le paramètre " + self.s

    def conversion (s) :
        """conversion d'une chaîne de caractères en entier"""
        if not s.isdigit () :
            raise AucunChiffre, (s, "conversion")
        return int (s)

    try :
        s = "123a"
        i = conversion (s)
        print (s, " = ", i)
    except AucunChiffre as exc :
        print (AucunChiffre.__doc__, " : ", exc)
        print ("fonction : ", exc.f)

Erreurs, confusions fréquentes
==============================

Variables
+++++++++

Chaîne de caractères = tableau de caractères
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Une chaîne de caractères est un tableau de caractères :
pour accéder à un caractère, on procède comme pour une liste.

.. runpython::
    :showcode:

    s = "abcdefghijklmnopqrstuvwxyz"
    print (s [4])    # affiche "e"
    print (s [4:6])  # affiche "ef"

Guillemets ou pas
^^^^^^^^^^^^^^^^^

Doit-on mettre des guillemets ou non~?

::

    l  = [ un, deux, trois, quatre ]
    up = []
    for i in range (0, len (l)) :
        up.append ( l [i].upper () )

Le code précédent ne fonctionne pas car il n'y a pas de
guillemets autour de ``un``, ``deux``, ``trois``, ``quatre``.
Le langage considère alors ces quatre mots comme des variables :
un identificateur qui désigne une information. Mais comme ces
variables n'existent pas, ces identifiants ne sont reliés à
aucun contenu et l'interpréteur python ne comprend pas.

Un mot entouré de guillemets (ou d'apostrophes) définit un contenu.
Sans guillemet (ou apostrophe), il définit une variable qui permet
de manipuler un contenu tout simplement en donnant la possibilité
au programmeur de le nommer. Autrement dit, pour manipuler une
chaîne de caractères, il faut affecter ce contenu à une variable.
Les guillemets n'apparaissent plus par la suite car on doit
utiliser la variable pour la manipuler.

Boucles
+++++++

``range`` ou pas ``range``
^^^^^^^^^^^^^^^^^^^^^^^^^^

Les deux programmes suivant sont équivalents. La seule
différence réside dans l'écriture dans la boucle ``for``
qui utilise dans le premier cas la fonction ``range`` et dans l'autre non.

::

    l  = [ "un", "deux", "trois", "quatre" ]
    up = []
    for i in range (0, len(l)) :
        up.append ( l [i].upper() )

Lorsqu'on utilise la fonction ``range``, on dispose lors
de la boucle de deux informations, l'indice ``i`` et l'élément ``l [i]``.
Si l'indice n'est pas utile, il est possible de simplifier la boucle comme suit.

::

    l  = [ "un", "deux", "trois", "quatre" ]
    up = []
    for m in l :
        up.append ( m.upper() )

En général, on se sert de la boucle qui utilise la fonction ``range`` dans deux cas :

#. On souhaite faire des opérations sur les éléments qui précèdent
   ou suivent l'élément en question, ce qui nécessite de connaître l'indice.
#. On parcourt deux listes de même taille à la fois : l'indice
   désigne la position de deux éléments, un dans chaque liste.

Initialisation
^^^^^^^^^^^^^^

Une boucle est souvent utilisée pour faire une somme, calculer
un maximum : garder un unique résultat en parcourant une liste.
Une boucle de ce type est toujours précédée d'une étape d'initialisation
qui consiste à donner une valeur au résultat : celle qu'il
aurait si la liste était vide.

::

    l = [ "un", "deux", "trois", "quatre" ]
    s = ""
    for m in l :
        s += m # concaténation des mots en une seule chaîne de caractères

Fonctions
+++++++++

Différence entre ``print`` et ``return``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A la fin d'un calcul, afin de voir son résultat, on utilise souvent
l'instruction ``print``. On peut se demander alors si à la fin de
chaque fonction, il ne faudrait pas utiliser l'instruction ``print``.
A quoi servirait alors l'instruction ``return`` ?
On suppose qu'un calcul est en fait le résultat de trois calculs à la suite :

::

    a = calcul1 (3)
    b = calcul2 (a)
    c = calcul3 (b) # c résultat souhaité et affiché

Chaque terme ``calculx`` cache une fonction or seul le résultat
de la dernière nous intéresse et doit être affiché. Pour les
deux premières, la seule chose importante est que leur
résultat soit transmis à la fonction suivante et ceci ne
peut se faire que grâce à l'instruction ``return``.
L'instruction ``print`` insérée dans le code de la fonction ``calcul1``
ou ``calcul2`` permettra d'afficher le résultat mais ne le transmettra
pas : l'instruction ``return`` est donc indispensable, ``print`` facultative.

En revanche, dans la dernière fonction ``calcul3``, il est
possible de se passer de ``return`` et de se contenter
uniquement d'un ``print``. Cependant, il est conseillé
d'utiliser quand même ``return`` au cas où le résultat
de la fonction ``calcul3`` serait utilisé par une autre
fonction, ``calcul4`` par exemple.

.. runpython::
    :showcode:

    def calcul1(x) :
        return x+3
    y = calcul1(4)
    print (y)            # affiche None
                         # car la fonction calcul1 ne retourne pas de résultat, elle l'affiche

Cela peut provoquer des erreurs lorsqu'on essaye d'utiliser ce résultat dans un calcul par la suite.

::

    def calcul1(x):
        print (x+3)
    def calcul2(x):
        return calcul1(x) + 5
    y = calcul2(4)     # affiche l'erreur

::

    ported operand type(s) for +: 'NoneType' and 'int'

Il faut retenir que l'instruction ``print`` n'a aucun impact sur le résultat
d'un programme.

Trois conseils pour écrire un programme
=======================================

Des petites fonctions
+++++++++++++++++++++

Pour plusieurs raisons :

#. Il est plus facile de corriger un programme qui est
   constitué de petites fonctions plutôt que de quelques
   grandes. Chaque fonction peut être vérifiée séparément.
#. Il est plus facile de réutiliser des petites fonctions.
#. Il est plus facile de répartir le travail sur plusieurs personnes.

Il vaut mieux éviter les variables globales qui sont considérées que comme des paramètres cachés.

Séparer les calculs, le chargement des données, l'interface graphique
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Pour plusieurs raisons :

#. Il est plus facile de vérifier un calcul s'il est dans
   une fonction indépendante plutôt que caché dans le
   code d'une interface graphique.
#. C'est facile de faire un calcul une fois lorsqu'un
   utilisateur appuie sur un bouton, si on veut faire ce calcul
   cent fois, on ne peut pas lui demander d'appuyer cent fois
   sur le même bouton.
#. Les calculs ou le chargement des données peuvent être
   utilisés dans d'autres programmes.

Utiliser des tests unitaires
++++++++++++++++++++++++++++

Ces fonctions peuvent être exécutées au début du programme
pour vérifier que certaines parties du programme fonctionnent
toujours même après les avoir modifiées.

L'exemple suivant considère une fonction qui doit retourner
une somme réelle même si les éléments de la liste sont
entiers. On écrit la fonction qui vérifie cela.

::

    def somme_double(liste):
        return 1.0 * sum(liste)

    def test_somme_double():
        y = somme_double([ 1 ]) / 2
        if y == 0:
            raise Exception ("valeur > 0 attendue")

    if __name__ == "__main__" :
        test_somme_double()

Si plus tard, quelqu'un modifie la fonction
``somme_double`` en enlevant la multiplication parce qu'il
considère cela inutile. La fonction de test provoquera une erreur.
Elle est là pour rappeler que la fonction a été programmée pour
retourner un nombre réel et que quiconque l'utilise
s'attend à ce qu'elle retourne ce type de résultat.

::

    Traceback (most recent call last):
      File "conseil.py", line 10, in <module>
        test_somme_double()
      File "conseil.py", line 7, in test_somme_double
        if y == 0 : raise Exception ("valeur > 0 attendue")
    Exception: valeur > 0 attendue

Trucs et astuces
================

Partager du code
++++++++++++++++

Il existe aujourd'hui des solutions qui permettent d'éviter
les envois de programme par email. Des outil comme *DropBox*,
*SkyDrive*, *GoogleDrive* permettent de partager un répertoire.
Un même répertoire peut être partagé sur plusieurs ordinateurs
et plusieurs personnes. Une modification (y compris
une suppression) sur l'une des répliques sera propagée sur
tous les ordinateurs dès qu'ils sont connectés à Internet.

Il est possible de coupler cette solution avec *SVN* ou *TortoiseSVN*
qui sont des logiciels de suivis de source. On garde à la
fois la dernière version et l'historique des modifications.

Moteurs de recherche
++++++++++++++++++++

Lorsqu'on ne comprend un message d'erreur, il est souvent utile de
recopier le texte dans un moteur de recherche (Google, Bing, ...).
Il est très rare de ne pas réussir à trouver d'indices.


text:
AIPUT scores new customer for its Camgate Centre business park at Heathrow Airport
posted on 11th June 2020 by Eddie Saunders
Aberdeen Standard Investments' AIPUT fund (Airport Industrial Property Unit Trust) has announced the completion of contracts with Rygor Commercials for the long-term occupancy of a recently-refurbished 28,000 sq ft unit at The Camgate Centre, Heathrow Airport. The scheme is located to the south of the airport's dedicated cargo zone, with major nearby airport-related occupiers, including dnata, Swissport and Gate Gourmet. Other AIPUT customers at its Camgate Centre location include Kinnarps and Straight Freight.
Rygor Commercials is a dedicated Mercedes commercial vehicle dealership, offering a range of services covering sales, aftersales and maintenance. This represents a significant expansion for Rygor at Heathrow, with the company planning to operate its new Camgate Centre location as a dedicated truck centre, and its existing site off Stanwell Road is set to focus on the van business.
The self-contained 28,000 sq ft industrial warehouse underwent a comprehensive speculative refurbishment by AIPUT with a building specification that delivers enhanced security, safety and flexibility for the occupier. The warehouse unit benefits from one of the largest secure service yards in the area.
Fraser Green, Portfolio Manager for Aberdeen Standard Investments, said: "The welcome addition of Rygor Commercials as a new customer at the Camgate Centre, shows that even in the most challenging of markets – such as in the context of Covid-19 – demand remains strong for AIPUT's prime Heathrow industrial floorspace.
"This new lease agreement with Rygor Commercials delivers on AIPUT's long-term vision to drive continuing growth in our high-quality portfolio of key industrial locations serving Heathrow."
Sean Joyce, Service Manager at Rygor Commercials, commented: "We are very excited about the new truck site and the opportunities it will bring for both our customers. The site is conveniently located just a mile down the road from our existing Heathrow branch, which will in turn become our Rygor Heathrow van site. Furthermore it is only 3.5 miles from the M25 and less than 5 miles from the M4.
"This new site will give us a great platform to build on the fantastic relationship we have with all our existing customers, as well as welcoming new ones to Rygor."
The Camgate Centre forms an integral part of AIPUT's 2.1m sq ft portfolio of industrial warehousing serving Heathrow Airport.
Strong and smooth air cargo growth at Brussels Airport
HKIA cargo volume continues to grow in November

redpajama_set_name: RedPajamaCommonCrawl


In a highly efficient single unit, the Mueller Model SGSS Starting Gas Separator/Silencer effectively removes entrained lubricating liquids from air or gas starters, and reduces the noise associated with discharging starting air or gas to acceptable levels. With no moving parts, the SGSS has been a reliable component in installations across North America for two decades. Like all Mueller products it is designed for low maintenance and built to last.


text:
Get to Know This New Injury Management Acronym
It's time to give your injuries PEACE and LOVE.
November 23, 2020 Susan Lacke
If you get injured, knowing this injury acronym can help you know the right steps toward recovery.
Almost every athlete knows the standard advice for pulled muscles, ankle sprains and other soft-tissue injuries: RICE, an acronym for rest, ice, compression, and elevation. But in recent years, experts have begun to question whether these steps do more harm than good.
"Many injury-management practices are founded on beliefs, rather than science," explained physiotherapist and clinical scientist Blaise Dubois. "The science—when there is science—is not always black and white."
Dubois cites the "I" in RICE as one example. American sports doctor Dr. Gabe Mirkin coined the term 'RICE' in 1978, using the assumption that ice tamps down inflammation. But in 2015, he backtracked on this initial hypothesis, writing that research shows ice "may delay healing, instead of helping." As it turns out, inflammation is actually a good thing for a soft-tissue injury, as it forces the body to rush healing resources to the injured area via increased blood flow.
Related: 8 Reasons Triathletes Get injured
To replace the outdated method, Dubois and his team of researchers developed a new injury-management protocol acronym published in the British Journal of Sports Medicine encourages PEACE and LOVE.
PEACE and LOVE takes a comprehensive, evidence-based approach to injury management. The first word, PEACE, focuses on immediate care:
Avoid Anti-Inflammatories
The latter half of the protocol, LOVE, outlines steps for rehabilitation:
Vascularization
"In addition to addressing how anti-inflammatory modalities, like pills and ice, slow down repair of the affected tissues, we included education, which is key in the world of over-medication, over-investigation, and over-treatment," said Dubois. By adding "education," the approach is the first injury-management protocol to address the "Dr. Google" phenomenon that plagues so many athletes. Trying to find a quick fix on the internet often does more harm than good.
The psychosocial component is also addressed with the addition of "optimism," or conditioning the brain for optimal recovery. Research shows optimistic patient expectations are associated with better outcomes and prognosis. In fact, beliefs and emotions about an injury explain more of the variation in symptoms following an ankle sprain than the degree of pathophysiology—the more you catastrophize your injury, the more you'll be limited by your symptoms.
Another important addition to the protocol can be found in the final two letters: VE, for vascularization and exercise. Previous injury-management strategies have not included movement, despite evidence showing that pain-free aerobic exercise should be started a few days after injury to boost motivation and increase blood flow to the injured structures and accelerate repair.
"Taking care of soft-tissue injuries is not only for the first week," explained Dubois. "Managing soft-tissue injuries is more than short-term damage control. Similar to other injuries, clinicians should aim for favorable long-term outcomes and treat the person with the injury, rather than the injury of the person."
Race Fueling
A Nutritional Strategy to Help Your Injury
Christina Strudwick
How to Eat and Exercise to Reduce Inflammation
Freya Drohan
When Is It Time to Go See a Physical Therapist?
Dana Reid, DPT


116 Post Office Rd. Enfield, Ct.
ATTENTION ALL BUYERS AND REAL ESTATE AGENTS! We are currently selling this beautiful and spacious newly rehabbed home. Please contact us at (860) 749-1000 with any questions you may have.


text:
Q: Does glass emit ultraviolet light? I'm fully aware that glass absorbs light in the ultraviolet band.  Moreover, glass does not absorb any light which has a longer wavelength than that of the UV light, making it transparent.
This makes the UV photon the lowest energy photon that can be absorbed by glass. In other words, the UV photon moves the electron's energy from ground state (K) to the lowest excited state (L). Thus, making the only way the electron can fall back to lower energy level by moving from L shell to K shell, releasing a photon with the same energy as the one absorbed, emitting ultraviolet light. Is this true ?

A: *

*Use black body radiation, it always emit $\textbf{some}$ light in ultra violate  region.

*When you electron poped out of the allowed excited states, the usual classical model was to treat it as a free electron. The free electrons usually  bounce around and interact with the surrounding electrons in other latices, which effectively distrusted the energy to other latices, thus you almost always won't be able to absorb glass emit UV light, rather heat and bunch of other photons.

A:
Moreover, glass does not absorb any light which has a longer wavelength than that of the UV light, making them transparent.

This statement isn't correct for a couple of reasons.
First of all, it's too absolute.  Glass does absorb some light in the visible band.  Its just that it is a poor absorber there and most visible light is transmitted.  But some is not none.
Second, depending on the specifics of the glass, it will have some stronger absorbance bands in the IR.  It is not completely transparent at all wavelengths longer than visible.  These are much preferred modes for transmission at low energy.
So there's no mechanism for glass to emit UV under normal conditions.

A:
Hi! So it is pretty common to mistake what glass does. Glass actually absorbs some wavelengths in the upper end of the spectrum (is you look at a typical glass pane from the side, you would see hints of green due to defects, and thinking about energy transitions, the smallest energy transition you could make is from you 1s shell splittings, which leads to that big bump on the right side.)
As for the question, by itself, without any external source, glass will not (I day will not but technically, highly improbable) emit UV light (light of wavelength ~ 10 to 380 nm) When shined with a UV light source though, yes, glass will absorb UV light. However, since, as shown in the picture above, we have multiple other states that we can jump to (right side), then the absorbed UV light may rather decay to the other longer wavelengths like IR. So, if UV is absorbed, yes some UV leaks out, but most of them will come out as IR or longer)
Tldr:  UV is absorbed. Yes some UV leaks out, but most of them will come out as IR or longer)

A: Any object will emit radiation. The spectrum depends on its temperature and of its electronic properties. A ideal black body will emit the famous black body spectrum. A real material emits this spectrum multiplied with a wave length dependent emissivity.  This emissivity simply equals the absorptivity. Glass has thus high emissivity in the UV but the blackbody intensity is extremely low at temperatures below melting. The net result is what should be a very low emission. If found a perfect blackbody  at 1200K emits 2 nanowatt/m2 above 300 nm. http://www.spectralcalc.com/blackbody_calculator/blackbody.php

A: When a photon interacts with an atom three things can happen:

*

*elastic scattering, the photon keeps its energy and changes angle

*inelastic scattering, the photon gives part of its energy to the atom and changes angle

*absorption, the photon gives all its energy to the atom
In your case it is a common misconception to think that UV light will be all absorbed by the glass.
When glass reflects visible light, like a mirror image, that is 1., elastic scattering.
In your case, when UV light or IR light (non visible) enters the glass deeper into the material, that is 2., inelastic scattering, or 3. absoption. Inelastic scattering will happen as the photons give their energy to the molecules in the glass lattice and transform into the vibrational energy of the molecules (heat the glass).
Absorption can happen too with glass, and will too heat up the material.
The question is only the ratio of the three interactions, but all will happen. With glass,

*

*visible light will mostly be reflected (1. elastic scattering) or will be refracted (will travel through the glass)

*non-visible light will mostly be inelastically scattered deeper in the material, and some will be absorbed heating up the material.
In your case, UV light will mostly be inelastically scattered or absorbed by the glass, heating it up.
Now the UV light that glass emits, is depending on the lattice structure of the glass, and the vibrational motions (heat energy) of the molecules in the lattice. Glass can emit UV light spontaneously too, because of the structure of the lattice, but it can do it too because the absorbed light will be re-emitted at a different frequency, glass can emit UV even if no UV is absorbed.

A: I would think some UV is also absorbed by quantum electrodynamic effects similarly to visible light. According to QED (such a great pun from Feynman), depending on the thickness of the glass and wavelength of light, any photon beam will have 4 - 20% of it's photons 'phased out' by other photons due to QED. I would presume this is the same for UV. As mentioned above, non-radiative transitions, inelastic scattering, absorption and the like are responsible for heating the glass, which is really just the visible photons being emitted as IR photons.

redpajama_set_name: RedPajamaStackExchange


text:
Q: Formulário não executa update Criei um formulário de edição, onde coloco no action o caminho para o arquivo de update e o botão do tipo submit. Mas clico no botão a página não é redirecionada e nem ocorre o update, não ocorre nada que está no arquivo de update, segue abaixo o código de update, quem tiver sugestões do que está errado agradeço.
<?php
$conexao = mysqli_connect('', '', '', ' ');
if(!$conexao){
    echo "";
}
$id               = $_GET['id'];
$descricao        = $_POST['descricao'];

$sql  = "UPDATE nome_tabela1 SET descricao1 = '$descricao' where id = '$id'";

$sqlF = "UPDATE nome_tabela2 SET descricao2 = ''$descricao'' where id = '$id'";

$result         = mysqli_query($conexao, $sql);
$result         = mysqli_query($conexao, $sqlF);

if ($result) {
    echo "";
}else{
    echo "";
}

mysqli_free_result($result);

Formulário:
    <?php
    $id = $_GET['id'];
    $conexao = mysqli_connect('', '', '', '');
    if(!$conexao){
        echo "";
    }
    ?>
    <form class="form-horizontal tasi-form" method="POST" action="php/editar_contrato.php">

           <?php
              $result = mysqli_query($conexao, "SELECT * FROM tabela WHERE id = '$id'");
              while($exibe = mysqli_fetch_array($result)){?>
              <input type="hidden" name="id" value="<?php echo $exibe['id']?>"/>

            Descrição

                 <input type="text" class="form-control" name="descricao" required="required" value="<?php echo $exibe['cont_descricao'] ?>">

   </form>
    <?php
      }
    ?>

        <input class="btn btn-success btn-sm pull-right" type="submit" value="Salvar" name="salvar">

        <input class="btn btn-default btn-sm pull-right" type="reset" value="Cancelar" name="cancelar">

A: Assumindo que você já verificou que a página existe. O botão submit precisa estar dentro do form
  <?php
    $id = $_GET['id'];
    $conexao = mysqli_connect('', '', '', '');
    if(!$conexao){
        echo "";
    }
    ?>
    <form class="form-horizontal tasi-form" method="POST" action="php/editar_contrato.php">

           <?php
              $result = mysqli_query($conexao, "SELECT * FROM tabela WHERE id = '$id'");
              while($exibe = mysqli_fetch_array($result)){?>
              <input type="hidden" name="id" value="<?php echo $exibe['id']?>"/>

            Descrição

                 <input type="text" class="form-control" name="descricao" required="required" value="<?php echo $exibe['cont_descricao'] ?>">

    <?php
      }
    ?>

        <input class="btn btn-success btn-sm pull-right" type="submit" value="Salvar" name="salvar">

        <input class="btn btn-default btn-sm pull-right" type="reset" value="Cancelar" name="cancelar">

  </form>


A responsible disclosure is not fun. Especially if the stakes are high and the timeline tight.
On 17th of September a vulnerability was found that could, in the very worst case, have led to a real on-chain double spend. I will not go into the nature of the bug, how it was found and who resolved it (although that story is great and an amazing example of efficiency). Instead, I will focus on what it would take (or rather have taken) for an attacker to actually exploit the vulnerability and what he would stand to gain from it. There is a lot of misinformation about this in the media right now.
The attacker has to be a miner and he would have to create a block that includes a specially crafted transaction that spends the same input twice in the same transaction. This transaction cannot be one that he picked up from the network, where such a transaction would not propagate. Think of it as handing over the same twenty Swiss Francs bill twice in one payment at the grocery store. The grocery store actually received forty Swiss Francs even though you only spent one twenty Swiss Francs bill. The total monetary supply just increased by twenty Swiss Francs. This is why the bug is often dubbed as an 'inflation bug'. The bug originated in the bitcoin core node software – this is run by companies dealing with or accepting bitcoin as well as individuals or developers in order to independently verify the information that they get from the blockchain. Since version 0.15.0 (September 2017) it no longer recognized such transactions as invalid.
After the bug was found, only few hours passed before version 0.16.3 was released and as of now already 19% of publicly visible nodes run on that version[i].
A miner running such an attack however runs the risk that despite many nodes not noticing the creation of money, other players will. He runs the risk that the betrayal of the network rules is picked up by humans instead of nodes. If this happens quickly enough, the operators of nodes, especially of economically relevant ones at exchanges will manually override and ignore this block. All it takes for this is one input in the bitcoin core node terminal. All preparations for such a step are taken. This would subsequently lead to a split in the blockchain, where nodes with observant operators follow a different chain than those nodes that do not. However, there is still a risk that the attacker can get his unjustly gained coins to an exchange, sell them there and withdraw the proceeds in fiat or a different cryptocurrency before the exchange notices the split and freezes operation. Given the mentioned efficiency and careful observation of certain individuals, the risk of such an attack, especially in economically damaging amounts, is very low.
It all comes down to two things. Firstly, what does the attack cost the attacker and secondly, how fast is the network likely to notice the anomaly and work around the culprit before he can take his profit.
Since the attacker has to be a miner and put his inflating transaction into a block which would otherwise have been valid, he is losing out on the reward for the block, yet still has to cover the production cost of that block. If the attack is unsuccessful, he just lost 12.5 BTC (plus fees), or at current rates roughly CHF 80k. This represents his investment.
To the second point, for the likelihood of discovery, that very much depends on the level of automation. Above, I only mentioned the manual, human means of discovery, but this is certainly not all. Projects like Statoshi or Bitcoin Optech continually monitor all possible network parameters. Fork monitors run different node software to determine any deviations. Developers do that to notice deviations between their software to bitcoin core and actually any bitcoin node will notify its operator if it determines that it is running on a minority chain, i.e. if there is a chain that is at least six blocks longer, but the node determines that chain to be invalid.
There are mechanisms in place to monitor the network for inconsistencies. In that context, the fact that the commit that enabled this bug only happened last September is very good news. Older versions are therefore not affected.
As of right now, 64% of nodes are secure, only 31% are vulnerable and 5% of publicly visible nodes do not send a standard version identifier, which means that it is unknown if they are affected or not. Those numbers obviously come after 19% of nodes have already updated to 0.16.3, but even if we assume that all of those have previously been on an affected version 0.15.0 to 0.16.2, this means that in the worst case scenario, there are still 31% of nodes that have not been vulnerable at the time of disclosure.
This rather high number, together with tools that monitor anomalies in the network, make it very unlikely that an attacker would be able to successfully spend his unjustly gained coins before the community notices and self-adjusts.
As a corollary to this: We do know that this exploit has not been executed in the past. For the very simple reason that pre-vulnerability nodes, running lower versions are purposely still up, running and in sync with the vulnerable ones.
Above considerations are valid for BTC. Smaller networks skew the numbers significantly. If it is cheaper to create a block, or rather if the opportunity cost of missing out on one, is smaller, the investment for the attacker goes down. Moreover, if there are fewer nodes and fewer developers monitoring the network, the likelihood of success goes up massively.
[i] For this and the further number of nodes, I source the information from https://coin.dance/nodes. This gives an indication about the network. Getting exact numbers is impossible though, since many nodes do not publicly advertise their existence.


text:
Q: how to add an action on UITextView return/search key?(swift 2) I have a UITextView which I am using as text entry in a translation application. When the user presses return/search then I want to do some action e.g. searching for word from textView. I want to do some action like we do with IBAction.

A: Set up delegate of the textView.  Than add shouldChangeTextInRange  for detecting of the return/search buttons and performAction for you're custom action.
    override func viewDidLoad() {
        super.viewDidLoad()

        self.textView.delegate = self
    }

    func textView(textView: UITextView, shouldChangeTextInRange  range: NSRange, replacementText text: String) -> Bool {
      if (text == "\n") {
         textView.resignFirstResponder()
         performAction()
      }
      return true
    }

    func performAction() {

    }


text:
This is the 50th anniversary of the NEA and to celebrate they are publishing "Our Story" from their recipients around the country. With gratitude for their generous contributions to Talking Hands Talking Feet and Songs To Educate, here is our little story.
Every year since 2008, our company, Talking Hands Talking Feet has received generous grants from NEA for our curriculum based performing arts programs in Santa Fe schools, under the fiscal sponsorship of Partners In Education.
Here is the remarkable story behind it.
It began in 1996 in our Seattle living room with a group of friends who also had young children. We would often have family gatherings where we would play music and dance, sing songs and tell stories. The biggest challenge was finding compelling children songs that engaged the whole family and songs that opened doorways to new learning. So we started writing original songs with story and dance accompaniment. We soon realized it was a marvelous springboard of discovery into the natural worlds, the human body, language, geography, numbers and counting and the kaleidoscopic world of human beings.
Our parent friends loved these songs. So, in September 1997, in response to their enthusiastic encouragement, we opened our home to the public and started music, movement and story workshops for parents and children every Saturday morning. We called it Talking Hands Talking Feet.
We have always believed in and practiced the arts as a vehicle for natural education. This was how we raised our sons. If you truly wish to learn something of value, give it a form of expression! Start with the most fundamental of human arts – music, rhythm, movement, language, symbol, story and song. To our ongoing wonder, delight and discovery, parents and their little ones couldn't get enough of Talking Hands Talking Feet.
Thus it began. It steadily grew year by year. We created a record label and produced our first albums. We moved from Seattle to Boulder to Santa Fe, always experimenting and expanding what was becoming a substantial curriculum of arts integrated educational songs.
In 2005, many hundreds of family workshops later, our youngest son's first grade teacher in Santa Fe, New Mexico asked us to help with an end of school year performance which involved orchestrating four classrooms in a songful extravaganza. It went so well that the following year the teachers asked us to do it again, this time with our own original songs and that we would be paid to do it! So we developed our first thematic 12 week performing arts program for four 1st and 2nd grade classrooms called "In Tribute To The Earth". Thus, Talking Hands Talking Feet curriculum based performing arts programs were born.
Now, nine years later, Talking Hands Talking Feet has received grants from the NEA through New Mexico Arts to do our original 12 week curriculum based performing arts programs every year in several schools in Santa Fe, New Mexico.
The range of content has expanded to 140 songs with movement and story accompaniment including inspiring lesson plans that help teachers bring subjects alive. The songs cover a diverse range of themes with a spirit of discovery, compelling humor and humanity; and now have personally touched the lives of thousands of young students.
This inspired us to share these arts integrated programs around the world through our online resource for teachers and parents called www.SongsToEducate.com.
It is remarkable how many children years later tell us how they love and remember the songs and the experience of learning through Talking Hands Talking Feet. We are so thankful to the National Endowment for the Arts and to New Mexico Arts for making this possible and reaching thousands of students in Santa Fe.
With value and gratitude,
Paul and Melanie Zeir
147. Foster Emotional Intelligence 149. Learn To Express, Express To Learn
Arts Integrated Education, Professional Development


Happy Aloha Friday, the day to kick back and relax... Well, unless you're like me and you have a graduation to get ready for, then there's not a whole lot of relaxing going on! #1, The Princess is graduating today, and if it weren't for all the things I need to get done, I'd probably be crying already!
What was your class song?, or What song makes you think of High School?
Dancin' With Myself by Billy Idol brings me back to high school every time I hear it.
I honestly don't remember my class song but it was a good song.
And so far, no song reminds me of school at all.
I don't remember our class song. Atomic Dog by George Clinton reminds me of high school. It was the song playing when I arrived at my first high school dance.
I don't remember if we had a class song . . . it was so long ago! LOL! But any song from the 80's reminds me of high school.
Hi! Stopping by from the Alexa hop (and I'm your newest follower!). I'll be honest...I don't recall if we had a class song, either. However, it has been...23 years. Eek!


text:
Fall, 2002: The Tempest by William Shakespeare
"The Tempest is a play by William Shakespeare, believed to have been written in 1610–11, and thought by many critics to be the last play that Shakespeare wrote alone. It is set on a remote island, where Prospero, the rightful Duke of Milan, plots to restore his daughter Miranda to her rightful place using illusion and skillful manipulation. He conjures up a storm, the eponymous tempest, to lure his usurping brother Antonio and the complicit King Alonso of Naples to the island. There, his machinations bring about the revelation of Antonio's lowly nature, the redemption of the King, and the marriage of Miranda to Alonso's son, Ferdinand." (no royalties)
Another play with fairies and lots of fun characters--and a little magic (until the fishing line with which you are "invisibly" lifting a tray of food breaks mid show and the tech get the debris out of the way just fast enough to save a robed actor backing off stage for his part from tripping on it and ruining his cool exit!
Spring, 2003: Li'l Abner by
This was certainly a challenge as it required over 50 actors to cover all the parts! Mr. Schoonover even got a cameo as "the BIG Man" that emerges from a smaller actor taking the infamous Yokumberry Tonic"!
"Al Capp's world famous characters have been placed in an upbeat musical extravaganza. It is a satisfying mixture of hillbilly nonsense and sharp, critical humor that appeals to the sophisticated theatregoer as well as the child within us all.
The curtain opens on "A Typical Day" in Dogpatch, U.S.A. where the motley and lovable characters who inhabit this burgh introduce themselves to the audience. There is the homely Scragg family and Marryin' Sam, as well as Earthquake McGoon, Daisy Mae, Li'l Abner and Mammy Yokum. It only takes a moment to see that leisure time is at the heart of the local economy and drinking Kickapoo Joy Juice, fishing and the popular Sadie Hawkins Day Dance are the favorite pastimes for Dogpatch's citizens.
What starts out as a calm day down at the fishing hole is quickly interrupted for Abner and his friends when a "Cornpone Meetin'" is called in the town square by Senator Jack S. Phogbound. This can mean one of two things-either an event of national importance has occurred, or there's to be "a hideous change in the Dogpatch way of life." Sure enough, a change is in the wind because the government has completed a study finding Dogpatch to be "the most unnecessary, no-account" place in the whole country, thereby setting the stage for evacuation of the town so that atomic testing can take place.
Consternation abounds among the townsfolk. If they are to be evacuated, Dogpatch's annual Sadie Hawkins Day Dance will be cancelled. And that means that Daisy Mae won't have a chance to catch her sweetheart Li'l Abner in what is the only way that boy can join girl in Dogpatch. Oh no! A solution must be found-something that proves their town is a "necessary" place after all. An extensive search ensues and Mammy finally comes up with the item to save the town from extinction-it's the Yokumberry tonic which she has fed her muscle-bound son, Abner, every day of his 'natcherel life. The potion is sped off to Washington for further testing, and it looks like Dogpatch and its way of life will be saved.
The communal sigh of relief doesn't last long before things take another twist. It seems that while Abner is interested in doing the "100% Red-Blooded American" thing, and will give his potion to the U.S. of A., General Bullmoose wants to control the potion himself. If Abner won't sell it to him, Bullmoose will get it some other way, namely in the form of his shapely girlfriend Appasionata Von Climax. Suddenly Daisy Mae's future as Mrs. Abner Yokum looks grim, and she and the rest of Dogpatch descend on Washington to save Abner from Bullmoose and Appasionata.
The evening before the Yokumberry tonic is to be released as the cure-all for puny men who want to be strong, a flaw is found in the formula. Abner's life is saved, but once again the town of Dogpatch is in jeopardy. Isn't there anything that can be done to save it from becoming a nuclear wasteland? Just as all seems lost, Jubilation T. Cornpone, Dogpatch's founder, saves the day. It seems his statue was declared a "national shrine" by Abraham Lincoln, given all that Cornpone had done in bringing down the Confederacy during the Civil War. The day is truly saved: Abner can marry Daisy Mae and everyone settles down for a peaceful life of rustic simplicity in Dogpatch, U.S.A." (licensed by Tams Witmark www.tamswitmark.com)
Fall, 2003: You Can't Take It With You by George S. Kaufman and Moss Hart
Spring, 2004: The Wizard of Oz (RSC version)
This time we tackled the traditional Royal Shakespeare Company version with all the songs we know and love and a few more that didn't make the cut in the movie version!


text:
Past six days
Dublin 3 house prices: Fairview, East Wall, North Strand, Ballybough, Marino
Young professionals are attracted to amenities such as Dollymount Strand, for swimming and watersports
BRYAN MEADE
CSO median house price: €420,000
2021 prediction: up 4%-5%
International buyers — those returning home, as well as foreign professionals working in Ireland — were out in force. As a result, values were stable and there were competing bidders for some homes, according to Melanie Brady, branch manager with agent Sherry FitzGerald.
"Prices have held strong and, where competition has been great, many properties have achieved higher prices, compared with 2019," she said.
Fairview is full of mature, redbrick Victorian properties
WOJTEK BARTKOWSKI
"This is evident in all strata of value in the D3 marketplace, from the affordable up into the higher, million-plus values.
"The international market has certainly been a factor, adding buyers with good financial circumstances into the mix, and this has pushed the values in many a bidding war or with parties


John Laing rules out seeking new LSE stock listing | City A.M.
construction company John Laing is not seeking a flotation, its chief executive said yesterday, denying a report it was eying a £600m London Stock Exchange listing by end of 2010.
"The company is not being floated, I can tell you categorically," Adrian Ewer said, after describing the report as "total rubbish".
Separately, an article published last week by trade magazine Infrastructure Journal said John Laing, which is owned by fund manager Henderson Group, was looking to tap public equity markets via a float of an infrastructure fund.
"The company first thought about this notion in 2005 and has been thinking about it ever since. It is something that at some point in time the company may do," Ewer said.
"That is just part of the way in which we might recycle capital to invest in new infrastructure projects," Ewer said, declining to give detail on the sum the company would seek to raise.


Tealights on every table and an elevated view of the pines and Draper Lake set a tranquil mood at Basmati's. The restaurant fuses fresh local ingredients with Asian flavors in a casual, yet sophisticated atmosphere – the perfect setting for an intimate dinner for two. Basmati's marries fusion cuisine from the Gulf Coast, the East Coast, and the Far East, and sources local, organic ingredients that bring out subtle flavors in each dish. Their sushi is a local favorite, and the drink menu includes a full bar as well as an extensive wine list. Reservations are recommended.
The Terrace is a family run, classic fine dining restaurant with a Greek tradition (just off 30A on Hwy 98). Mediterranean inspired cuisine like Chargrilled shrimp with a citrus butter and herbed beurre blanc as well as Lamb Chops in a red wine reduction transport you to the Greek isles. Evan a cozy night over cocktails is a treat at The Terrace. The martini list features over a dozen combinations and the extensive wine list pairs perfectly with tapas that are only available at the bar.
With panoramic views of the Gulf of Mexico, a chic dining room, and exceptional service. Pescado has everything you need for a cozy night out in South Walton. The creative chef driven menu is updated frequently, guaranteeing new flavors based on what local ingredients are available. The kitchen balances locally sourced ingredients with a fine dining approach that also includes sourcing fish from New Zealand, Pacific caught Salmon, and Halibut from Washington, for example. Pescado also has an in-house sommelier that can suggest pairings for each dish.
Restaurant Paradis is an intimate fine dining eatery with a warm neighborhood vibe and understated Wine Country elegance. The seasonal, chef-driven menu champions fresh seasonal ingredients that celebrate local produce and fresh Gulf seafood, along with prime steaks and fine wines. Paradis prides itself on impeccable service, with a close-knit staff that makes every guest feel special.
George's features a cozy, yet airy indoor dining space in an Old Florida cottage that is as intimate as they come. By infusing coastal fare with global flavors, the menu features seasonal dishes alongside tried and true favorites. True to tradition, each dish is presented with a generous helping of love. You will also love George's in-house sommelier and seasonally curated wine list - perfect for pairing with locally sourced, organic produce and the freshest seafood available.
With a handful of candlelit tables, an intimate bar, live music, and black and white movies projected onto the wall in the courtyard, Edward's is one of the finest dining experiences you could share with a loved one. Double French doors open to a chef's counter where true foodies can grab a stool and watch the kitchen work their magic. Farm fresh ingredients are featured, including local seafare and vegetables, embracing the restaurant's Southern influence. Edward's also features about 115 wines, a truly extensive selection, especially considering the restaurant's size, for a one-of-a-kind experience.
Since seating is limited in cozy dining spots, reservations are recommended. For more restaurant stories, ratings, and reviews, be sure to check out the SoWal Dining Guide. And there are always friendly and knowledgeable friends in the SoWal Dining Forum – along with the latest happenings and specials. Follow the SoWal Facebook page for updates from the beach.


At Marymount Primary we encourage conflict resolution strategies which promote the dignity of all. For further information please refer to our Grievance Brochure.
Situations of conflict arise in the school community – we are human. Conflict is a necessary ingredient for growth and change in an individual and in a community or organization. Conflict is a sign of difference in a community. As Christians however we have an obligation to work at resolving conflicts peacefully, with due respect for the dignity of all people involved. We have an obligation also to restore relationships broken or affected by the conflict. We have an obligation also, through open, honest and respectful communication, to avoid initiating unnecessary conflict.
Differences in opinion might lead to conflict if there is either no room for negotiation or little attempt from either person or group to listen to and respect the rights of another to express a point of view. As Christians we are compelled to broaden our understanding and acceptance of difference. In fact, we are called to celebrate difference.
The documents below outline Brisbane Catholic Education's (BCE) approach to managing and resolving complaints from students, parents and guardians. This procedure applies to all BCE employees and must be read in conjunction with the BCE Student, Parent and Guardian Complaints Management policy and Code of Conduct.


text:
import Application from "@ember/application";
import EmberObject from "@ember/object";

const BaseApp = Application.extend({
    modulePrefix: 'my-app'
});

BaseApp.initializer({
    name: 'my-initializer',
    initialize(app) {
        app.register('foo:bar', EmberObject.extend({ foo: 'bar' }));
    }
});

BaseApp.instanceInitializer({
    name: 'my-instance-initializer',
    initialize(app) {
        app.lookup('foo:bar').get('foo');
    }
});

const App1 = BaseApp.create({
    rootElement: '#app-one',
    customEvents: {
        paste: 'paste'
    }
});

const App2 = BaseApp.create({
    rootElement: '#app-two',
    customEvents: {
        mouseenter: null,
        mouseleave: null
    }
});

const App3 = BaseApp.create();

const App3Instance1 = App3.buildInstance(); // $ExpectType ApplicationInstance

const App3Instance2 = App3.buildInstance({ foo: 'bar' }); // $ExpectType ApplicationInstance

redpajama_set_name: RedPajamaGithub


text:
Kayvon Webster
About Kayvon Webster
ABOUT EMPLOYEE
Kayvon's Story
A native of Miami, Florida, Webster attended Monsignor Edward Pace High School in Miami Gardens, Florida, where he was a letterman in football and track. In football, he saw action on both sides of the ball and as a return specialist and was a two-time first team All-Dade selection. During his junior season, he caught 30 passes for 500 yards with eight touchdowns on offense, while also adding 65 tackles, four sacks, seven forced fumbles and 10 fumble recoveries on defense. Academically, he carried a 3.0 GPA. Regarded as a three-star recruit by Rivals.com, Webster was rated as the 28th-best safety in the nation, 29th according to Scout.com. He was also ranked as the 32nd-best prospect as an athlete by ESPN.com. He chose USF over scholarship offers from Miami, Florida and Auburn, among others. Webster was selected 90th overall by the Denver Broncos in the third round of the 2013 NFL Draft and played for the Los Angeles Rams, Houston Texans, New Orleans Saints, and the Washington Redskins. After his football career, Kayvon dived into entrepreneurship where he would become the owner and creator of the VYBE 305 Restaurant, employing 15 amazing team members while also investing in other food and beverage brands.
My Professional
Velit eius illo a commodi veniam beatae.
Genuine Passion
Ability to Skilfully Multitask
Not A Lone Wolf
Able To Take Criticism
Endurance and Stamina
They are ready to treat you
Starex Smith
Reservation Contact us
Wednesday - Friday
4:00 pm - 11 : 00 pm
11:00 am - 3 : 00 pm
5:00 pm - 8 : 00 pm


The Hummingbird Studio Suite has a separate entrance, kitchenette, and fireplace.
This beautiful Hummingbird self-contained studio suite has all the comforts required while traveling away from home. The private suite boasts an equipped kitchenette—counter height fridge, microwave, induction cooktop, coffee maker, toaster, kettle, pots and pans, and dishware—private sitting area with a gas fireplace and flat-screen cable TV, queen-size bed (all linens provided), 4-piece bathroom with soakertub/shower and heated floor. There is a double futon for a second person, should it be needed, or extra playpen/crib for an infant available upon request.
Enjoy the peaceful forest (the bird sanctuary preserve) from your window. Outside, breathe in the fresh West Coast air while sitting on the cozy cedar deck looking over the gardens and natural pond. Watch birds feast at a bird feeder. Around the yard, cook your catch of the day on an outdoor BBQ, eat outdoors in a common picnic area, or roast marshmallows around a crackling fire in the firepit.
Wireless internet connection (WiFi) available.
Shoulder season and weekly stay rates available (please inquire).
Thank you for not smoking in this suite or on the wooden deck.
We appreciate your respecting our no-pet policy.
Enjoy private suites in our garden setting located near beaches, botanical gardens and a forested bird sanctuary reserve.
© Cobble Wood & Bird Sanctuary Guesthouses, Tofino | Developed by World Web Technologies Inc.