diff --git a/algo/poo/cours/DesignPatterns.txt b/algo/poo/cours/DesignPatterns.txt new file mode 100644 index 0000000..8f0a7e5 --- /dev/null +++ b/algo/poo/cours/DesignPatterns.txt @@ -0,0 +1,94 @@ +Les design patterns +===================== + +Les design patterns **ne sont pas** indépendants du langage. +Ils dépendent de l'implémentation. + +Le duck typing +------------------- + +En python, le duck typing est une forme extreme de programmation par interface. +Ne pas hériter dans des directions fausse + +exemple : une voiture ne peut hériter d'un moteur, parce que un moteur n'est pas une voiture. + +hold or wrap ? +-------------- + +**hold**:: + + O.S.method() + +Cela induit un couplage fort (cf la loi de Demeter) + +.. important:: law of Demeter : never more than one dot. + +wrap : a hold by private name, with a:: + + self.S.method() + +Ou bien une méthode getattr:: + + __getattr__() + +Gets coupling right. + + +wrapper can restrict, inheritance cannot restrict +-------------------------------------------------- + +:: + + class RestrictingWrapper(object): + + def __init__(self, w, block): + self._w = w + self._block = block + + def __getattr__(self, n): + if n in self._block: + raise AttributeError, n + return getattr(self._w, n) + +Pattern de création : singleton +------------------------------- + +# utiliser un module au lieu d'une classe + +in `toto.py`:: + + class Toto() + toto = Toto() + +in another module:: + + from toto import toto + +la factory +-------------- + +:: + + def load(pkg, obj): + m = __import__(pkg, {}, {}, [obj]) + return getattr(m, obj) + + cls = load('p1.p2.p3', 'c4') + + +template method (self delegation) +--------------------------------- + +# Abstract base class:: + + def OrganiseMethod() + def org_method(): + def do_this() + def do_that() + + def Concrete(OrganiseMethod) + def do_this(): ... + def do_that(): ... + +il est préférable de lever une NotImplementedError, ce qui revient à faire +une classe abstraite. diff --git a/algo/poo/cours/cesar.py b/algo/poo/cours/cesar.py deleted file mode 100644 index c3d25ac..0000000 --- a/algo/poo/cours/cesar.py +++ /dev/null @@ -1,61 +0,0 @@ -# coding: utf-8 -minuscules = 'abcdefghijklmnopqrstuvwxyz' -majuscules = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - -def rotation(chaine, x): - """ - Effectue une rotation de x caractères vers la droite: - >>> rotation('abcde', 2) - 'cdeab' - """ - return chaine[x:] + chaine[:x] - -def index(c, chaine): - """ - Trouve l'index de c dans la chaine: - >>> index('n', 'bonjour') - 2 - """ - for i in range(len(chaine)): - if (c == chaine[i]): - return i - return -1 - -def chiffre_minuscules(chaine, x): - """ - Chiffre une chaîne composée de minuscules - >>> chiffre_minuscules('bonjour', 3) - 'erqmrxu' - """ - r = rotation(minuscules, x) - resultat = '' - for lettre in chaine: - resultat = resultat + r[index(lettre, minuscules)] - return resultat - -def chiffre(chaine, x): - """ - Chiffre une chaîne quelconque - >>> chiffre('Bonjour les amis!', 3) - 'Erqmrxu ohv dplv!' - """ - r_min = rotation(minuscules, x) - r_maj = rotation(majuscules, x) - resultat = '' - for lettre in chaine: - if lettre in minuscules: - resultat = resultat + r_min[index(lettre, minuscules)] - elif lettre in majuscules: - resultat = resultat + r_maj[index(lettre, majuscules)] - else: - resultat = resultat + lettre - return resultat - -############################################################################# -# Programme principal -############################################################################# -print(chiffre_minuscules('bonjour', 3)) -print(chiffre('Bonjour les amis!', 3)) -print(chiffre('Erqmrxu ohv dplv!', 23)) -print(chiffre('Eudyr, yrxv dyhc ilql fhw hahuflfh!', 23)) - diff --git a/algo/poo/cours/classes.txt b/algo/poo/cours/classes.txt new file mode 100644 index 0000000..1ba2268 --- /dev/null +++ b/algo/poo/cours/classes.txt @@ -0,0 +1,452 @@ +Définir et manipuler des classes +================================= + +.. glossary:: + + objet + + Un object est une entité possédant un type, un état, et un comportement. + Un object correspondant généralement à une entité du monde réel, mais + cette entité peut être abstraite. + On parle aussi d'**instance**. + +**état d'un objet** : ensemble de propriétés auxquelles sont associées des +valeurs. + +Les variables de l'objet sont appelées des **attributs**. +le comportement d'un :term:`objet` : + +- des actions effectuées sur l'objet +- des appels faits sur l'objet + +envois de messages à l'objet = appel de **méthodes** + +programmation objet (première approche) +----------------------------------------- + + +- le type et le protocole d'un objet sont définis par sa classe +- une classe possède un ensemble d'attributs et de méthodes + +deux relations possibles +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. glossary:: + + heritage + + relation "est une espèce de " utilisée entre une classe et une autre classe + + instantiation + + relation "est une instance de " entre un objet et une classe + + +- est une instance de (objets par rapport à classe) +- est une espèce de (classe par rapport à classe, :term:`heritage`) + +**instance** + +- définition d'une classe +- instance de classe : on peut créer des objets à partir d'un type "classe" + (une classe est instanciable) + +>>> class A: +... pass +... +>>> a = A() + +:term:`heritage` : notation en python + +>>> class A: pass +... +>>> class B(A): pass +... +>>> b = B() +>>> type(b) == B +>>> isinstance(b, A) == True + +possibilité en python d'héritage multiple:: + + class A(B, C): pass + + +attribut d'objets et de classes +---------------------------------- + +>>> o = object() +>>> o + +>>> class C(object): pass +... +>>> class C: pass +... +>>> c = C() +>>> c.a = 3 +>>> c.a +3 +>>> vars(c) +{'a': 3} +>>> c.__dict__ +{'a': 3} +>>> C.__dict__ +{'__module__': '__main__', '__doc__': None} +>>> C.c = 5 +>>> C.__dict__ +{'c': 5, '__module__': '__main__', '__doc__': None} +>>> c.c +5 +>>> c.z = 3 +>>> c.z +3 +>>> c.__dict__ +{'a': 3, 'z': 3} +>>> C.__dict__ +{'c': 5, '__module__': '__main__', '__doc__': None} +>>> class MaKlass: +... def unefonction(self, x): +... print x +... +>>> MaKlass.__dict__ +{'__module__': '__main__', '__doc__': None, 'unefonction': } +>>> k = MaKlass() +>>> k.__dict__ +{} +>>> def autrefonc(self, x) + File "", line 1 + def autrefonc(self, x) + ^ +SyntaxError: invalid syntax +>>> def autrefonc(self, x): +... print x +... +>>> k.autrefonc = autrefonc +>>> k.__dict__ +{'autrefonc': } +>>> MaKlass.__dict__ +{'__module__': '__main__', '__doc__': None, 'unefonction': } +>>> MaKlass.unefonction(k, "toto") +toto +>>> k.unefonction("toto") +toto +>>> k.__dict__ +{'autrefonc': } +>>> MaKlass.toto = "test" +>>> k.__dict__ +{'autrefonc': } +>>> k.toto +'test' +>>> + + +le __dict__ avec l'héritage de classe +------------------------------------------- + + +>>> class A(object): pass +... +>>> A.__dict__ +dict_proxy({'__dict__': , '__module__': '__main__', '__weakref__': , '__doc__': None}) +>>> class B(A): +... b = 3 +... +>>> class C(B): +... c = 2 +... +>>> c = C() +>>> o = C() +>>> o.__dict__ +{} +>>> o.c +2 +>>> o.b +3 +>>> o.__class__ + +>>> o.__class__.__dict__ +dict_proxy({'__module__': '__main__', 'c': 2, '__doc__': None}) +>>> + + +method resolution object +----------------------------- + +>>> class A(object): pass +... +>>> A.__mro__ +(, ) +>>> class B(A): pass +... +>>> B.__mro__ +(, , ) +>>> class C(A, B): pass +... +Traceback (most recent call last): + File "", line 1, in +TypeError: Error when calling the metaclass bases + Cannot create a consistent method resolution +order (MRO) for bases A, B +>>> + + +introspection contre encapsulation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +voir un objet comme un espace de nommage. C'est plus **agile**. + +attributs et méthodes vus comme des ajouts dans l'espace de nommage + +>>> a.a = 2 +>>> def function(x): +... print x +... +>>> a.f = function +>>> a.f("hello") +hello +>>> + + +la nécessité d'un design objet +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +affichage d'une calculette, il faut créer un type `Touche` +qui contient deux désignations : `Chiffre` et `operation`:: + + type operation = Plus | Moins | Divise + type touche = Chiffre of int | Memoire | Op of operation + +soit, on définit un type touche, soit on ne définit pas ce type:: + + type operation = Plus | Moins | Divise + type memoire = Memoire + type chiffre = Chiffre + +- les structures de données (int, str, list, dict...) : types de base +- les structures de données utilisateur : les classes ! + +.. function:: type (objname) + + :param objname: l'objet dont on veut connaître le type + +Manipulations sur les classes et les objets +--------------------------------------------- + +En python un type et une classe c'est la même chose. Une classe +est un type standard. En python tout est objet, et tout provient d'un seul objet +(qui s'appelle ``object``). + +- encapsulation (cacher les attributs (variables d'état)) d'un objet. + +- interfaces : chaque aspect d'une classe peut être vu comme une interface. + +Une interface décrit un ensemble de comportements. +on peut considérer une interface comme un protocole d'utilisation d'un objet +dans un contexte donné. + +on peut alors créer des outils qui sauront traiter n'importe quel objet +pourvu qu'il respecte une ensemble d'interfaces. + +.. todo:: travailler l'héritage, l'aggrégation, la délégation + +Voici un exemple de classe `Voiture` : + +.. literalinclude:: snippets/heritage.py + :pyobject: Voiture + +j'instancie ma classe `Voiture` : + +>>> ma_voiture = Voiture("ma_marque", "150km/h") +>>> ma_voiture.roule() +'vroummm' +>>> ma_voiture.signaletique() +'constructeur : ma_marque, vitesse_max 150km/h' + +.. todo:: faire des traitements dans l'init + +- héritage (est une sorte de) +- polymorphisme : un objet apparait comme une instance d'une classe parente + +.. literalinclude:: snippets/heritage.py + :pyobject: Turbo + +>>> v = DoDoche("marque", 160) +>>> v.get_prix() +'7000' +>>> isinstance(v, Prix) +True +>>> + +mais l'objet conserve son identité : + +>>> type(v) + + +la fonction ``achete_voiture()`` sera appelée indépendamment du type de l'objet, +du moment que l'objet a une méthode `get_prix()`, c'est le duck typing, qu'il +est préférable de ramener au polymorphisme d'objet, ou bien utiliser les :mod:`abc` +(abstract base classes). + +.. literalinclude:: snippets/heritage.py + :pyobject: achete_voiture + +tout le code : + +.. literalinclude:: snippets/heritage.py + +:download:`télécharger le code ` + +- **l'aggrégation** + +un attribut est lui-même un objet (ce qui est fréquent en python)... + +.. literalinclude:: snippets/aggregation.py + +- **la délégation** + +la fonction "property" est un élément du design de python lui-même + +.. function:: property() + +les patrons de conception +--------------------------- + +- le patron **factory** + +.. literalinclude:: snippets/patrons.py + +:download:`télécharger usine (factory) ` + +- le patron **wrapper** + +:download:`télécharger wrapper ` + +.. literalinclude:: snippets/wrap.py + +exemple d'utilisation de `Wrap()` + +>>> class O: +... pass +... +>>> o = O() +>>> o.a = "blah" +>>> +>>> from wrap import Wrap +>>> w = Wrap("monwrap", o) +>>> w._name +'monwrap' +>>> w._w +<__main__.O instance at 0x7fbf177aaa28> +>>> w._w.a +'blah' +>>> w.a +'blah' +>>> w.u +Traceback (most recent call last): + File "", line 1, in + File "wrap.py", line 11, in __getattr__ + return getattr(self._w, name) +AttributeError: O instance has no attribute 'u' +>>> + +- le patron de conception **itérable** + +:download:`télécharger iterable ` + +.. literalinclude:: snippets/iterable.py + +- le patron **decorateur** + +:download:`télécharger decorateur ` + +.. literalinclude:: snippets/decorateur.py + +>>> def deco(func): +... func.attr = 'decorated' +... return func +... +>>> @deco +... def f(): pass +... +>>> f.attr +'decorated' +>>> + +autre exemple : les méthodes statiques + +>>> class A(object): +... @staticmethod +... def my_class_method(cls): +... # do stuff here + + +métaclasses +----------------- + +>>> class A: +... pass +... +>>> type(A) + +>>> class B(object): pass +... +>>> type(B) + +>>> help(type) + +>>> C = type('C', (), {}) +>>> C + +>>> + +>>> type(object) + +>>> type(type) + +>>> isinstance(type, object) +True +>>> isinstance(object, type) +True +>>> + +:: + + class MaMetaClasse(type): + """Exemple d'une métaclasse.""" + def __new__(metacls, nom, bases, dict): + """Création de notre classe.""" + print("On crée la classe {}".format(nom)) + return type.__new__(metacls, nom, bases, dict) + + class MaClasse(object): + __metaclass__ = MaMetaClasse + + +exemple : forcer l'implémentation d'un singleton avec les métaclasses + +:: + + class Singleton(type): + instance = None + def __call__(cls, *args, **kw): + if not cls.instance: + cls.instance = super(Singleton, cls).__call__(*args, **kw) + return cls.instance + + class ASingleton(object): + __metaclass__ = Singleton + + a = ASingleton() + b = ASingleton() + assert a is b + print(a.__class__.__name__, b.__class__.__name__) + + class BSingleton(object): + __metaclass__ = Singleton + + c = BSingleton() + d = BSingleton() + assert c is d + print(c.__class__.__name__, d.__class__.__name__) + assert c is not a + diff --git a/algo/poo/cours/conf.py b/algo/poo/cours/conf.py index 10c7b74..aadfb45 100644 --- a/algo/poo/cours/conf.py +++ b/algo/poo/cours/conf.py @@ -29,7 +29,7 @@ import os # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig', + 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig', 'sphinx.ext.todo', ] # ajout des cours avec solution des exercices ou non @@ -40,6 +40,7 @@ def setup(app): exercice = False correction = False +todo_include_todos = True # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] diff --git a/algo/poo/cours/index.txt b/algo/poo/cours/index.txt index ce3f89c..b25c47a 100644 --- a/algo/poo/cours/index.txt +++ b/algo/poo/cours/index.txt @@ -6,8 +6,12 @@ Introduction à l'algorithmique presentation fondement + mechanism + prompt langage programme modularite modules + classes + DesignPatterns annexes/index diff --git a/algo/poo/cours/prompt.txt b/algo/poo/cours/prompt.txt new file mode 100644 index 0000000..4dc3735 --- /dev/null +++ b/algo/poo/cours/prompt.txt @@ -0,0 +1,107 @@ +Interactions avec l'utilisateur +=============================== + +les prompts +-------------- + +`raw_input` ou `input` + +(raw_input renvoie une string, input essayes d'évaluer, soyez prudent...) + +>>> from subprocess import call +>>> filename = input("quel fichier voulez-vous afficher ?\n") +>>> call("cat " + filename, shell=True) + +.. _cmdlabel: + +le module :mod:`cmd` et les interpréteurs +-------------------------------------------- + +le monde des interpréteur ligne de commande... + +Peu après l'âge de bronze vint le temps de l'interpréteur ligne de commande, +c'est-à-dire quelque chose de plus spécifique que **l'application ligne de commande**, +ou que l'utilitaire ligne de commande. + + +Un interpréteur ligne de commande est un programme qui : + +- est forcément plein texte +- vous donne un prompt +- prends toutes ses entrées d'un coup +- produit une sortie (typiquement des lignes de texte) +- vous redonne un prompt + +Le shell unix est un bon exemple d'interpréteur ligne de commande. + +Un utilitaire ligne de commande est un programme unix-like qui prend toutes +les entrées d'un coup, et qui vous renvoie une sortie d'un coup. + +le module :mod:`cmd` : exemple d'utilisation + +.. module:: cmd + :synopsis: interpréteur ligne de commande + +.. literalinclude:: snippets/cli.py + +:download:`telecharger cmd ` + +:: + + >>> from cli import Cli + >>> prompt = Cli() + >>> prompt.cmdloop() + cli (command line interpreter) + (type help or ? for commands list) + #Prompt> ? + + Documented commands (type help ): + ========================================== + EOF exit + + Undocumented commands: + ====================== + cmd help quit + + #Prompt> + +pour ajouter une commande, utiliser simplement l'héritage:: + + >>> from cli import Cli + >>> class Prompt(Cli): + ... def do_hello(self, line): + ... print "hello %s", line + ... + >>> prompt = Prompt() + >>> prompt.cmdloop() + cli (command line interpreter) + (type help or ? for commands list) + #Prompt> ? + + Documented commands (type help ): + ========================================== + EOF exit + + Undocumented commands: + ====================== + cmd hello help quit + + #Prompt> hello world + + +.. todo:: faire un petit projet d'interpréteur ligne de commande du jeu C+/C- + +lire et écrire dans un fichier +------------------------------- + +les **handle de fichier** (file handles) + + +>>> +>>> fh = file('test', 'w') +>>> fh.write('hello world') +>>> fh.close() +>>> content = file('test', 'r').read() +>>> content +'hello world' +>>> diff --git a/algo/poo/cours/snippets/aggregation.py b/algo/poo/cours/snippets/aggregation.py new file mode 100644 index 0000000..3cb9c7b --- /dev/null +++ b/algo/poo/cours/snippets/aggregation.py @@ -0,0 +1,8 @@ +class A: + pass + +class B: + pass + +a = A() +a.b = B() diff --git a/algo/poo/cours/snippets/cli.py b/algo/poo/cours/snippets/cli.py new file mode 100644 index 0000000..8f65ba3 --- /dev/null +++ b/algo/poo/cours/snippets/cli.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python +# -*- coding: utf8 -*- +"""Command line interpreter +""" +import cmd + +# ____________________________________________________________ +# this Cli is a model of a basic use of a simple cmd +class Cli(cmd.Cmd): + def __init__(self): + cmd.Cmd.__init__(self) + self.doc_header = "Documented commands (type help ):" + self.undoc_header = "Undocumented commands" + self.prompt = "#Prompt> " + self.intro = """cli (command line interpreter) +(type help or ? for commands list)""" + self.ruler = "-" + + def emptyline(self): + print "Type 'exit' to finish withe the session or type ? for help." + + def default(self, line): + print "unknown command prefix" + print "*** unknown syntax : %s (type 'help' for help for a list of valid commands)"%line + self.emptyline() + + def do_exit(self, line): + """Exits from the console""" + return True + + def do_quit(self, line): + return True + + def do_EOF(self, args): + """Exit on system end of file character""" + return True + +# ____________________________________________________________ +# commands pre and post actions +# def precmd(self, line): +# return line +# def postcmd(self, stop, line): +# # if there is a problem, just return True : it stops everythings +# stop = True +# return stop # quit if stop == True +# ____________________________________________________________ +# program pre and post actions +# def preloop(self): +# # action for the beginning of the program +# pass + +# def postloop(self): +# # action for the end of the program +# print "exit cli" +# ____________________________________________________________ + +class HelloCli(Cli): + + def input_hello(self, line): + return line.replace(",", " and ") + + def output_hello(self, result): + print result + + def do_hello(self, line): + self.output_hello("hello, " + self.input_hello(line)) + #return False # if you want to stay into the cli + return True # if you want to exit + +if __name__ == '__main__': + prompt = HelloCli() + prompt.cmdloop("intro, modifies Cmd.intro") + diff --git a/algo/poo/cours/snippets/cmdline.py b/algo/poo/cours/snippets/cmdline.py new file mode 100644 index 0000000..0d3f32a --- /dev/null +++ b/algo/poo/cours/snippets/cmdline.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python + +""" +Module docstring. +""" + +import sys +import optparse + +def process_command_line(argv): + """ + Return a 2-tuple: (settings object, args list). + `argv` is a list of arguments, or `None` for ``sys.argv[1:]``. + """ + if argv is None: + argv = sys.argv[1:] + + # initialize the parser object: + parser = optparse.OptionParser( + formatter=optparse.TitledHelpFormatter(width=78), + add_help_option=None) + + # define options here: + parser.add_option( # customized description; put --help last + '-h', '--help', action='help', + help='Show this help message and exit.') + + settings, args = parser.parse_args(argv) + + # check number of arguments, verify values, etc.: + if args: + parser.error('program takes no command-line arguments; ' + '"%s" ignored.' % (args,)) + + # further process settings & args if necessary + + return settings, args + +def main(argv=None): + settings, args = process_command_line(argv) + # application code here, like: + # run(settings, args) + return 0 # success + +if __name__ == '__main__': + status = main() + sys.exit(status) diff --git a/algo/poo/cours/snippets/decorateur.py b/algo/poo/cours/snippets/decorateur.py new file mode 100644 index 0000000..8770886 --- /dev/null +++ b/algo/poo/cours/snippets/decorateur.py @@ -0,0 +1,10 @@ +def helloworld(ob): + print "Hello world" + return ob + +@helloworld +def myfunc(): + print "my function" + +myfunc() +print myfunc diff --git a/algo/poo/cours/snippets/heritage.py b/algo/poo/cours/snippets/heritage.py new file mode 100644 index 0000000..db2e19b --- /dev/null +++ b/algo/poo/cours/snippets/heritage.py @@ -0,0 +1,28 @@ +class Turbo(object): + def turbo(self): + return "VRRRRROUUUMMM" + +class Prix(object): + def get_prix(self): + raise NotImplementedError + +class Voiture(Prix, Turbo): + def __init__(self, constructeur, vitesse_max=160): + self.constructeur = constructeur + self.vitesse_max = vitesse_max + + def roule(self): + return "vroummm" + + def signaletique(self): + return "constructeur : {0}, vitesse_max {1}".format(self.constructeur, + self.vitesse_max) + +class DoDoche(Voiture): + def get_prix(self): + return "4000" + +def achete_voiture(voiture): + if not hasattr(voiture, "get_prix"): + raise TypeError("pas le bon type") + return "prix de la voiture: {0} euros".format(voiture.get_prix()) diff --git a/algo/poo/cours/snippets/iterable.py b/algo/poo/cours/snippets/iterable.py new file mode 100644 index 0000000..bce9444 --- /dev/null +++ b/algo/poo/cours/snippets/iterable.py @@ -0,0 +1,20 @@ +liste = ['blah', 'blih', 'bluh'] +iterateur = liste.__iter__() +print iterateur.next() +print iterateur.next() +print iterateur.next() +print iterateur.next() +#Traceback (most recent call last): +# File '', line 1, in ; +#StopIteration + +class Iterateur: + i = 0 + def next(self): + if self.i <= 10: raise StopIteration + self.i += 1 + return 2**self.i + def __iter__(self): return self + +iterateur = Iterateur() +for i in iterateur: print i diff --git a/algo/poo/cours/snippets/patrons.py b/algo/poo/cours/snippets/patrons.py new file mode 100644 index 0000000..808203b --- /dev/null +++ b/algo/poo/cours/snippets/patrons.py @@ -0,0 +1,18 @@ +class NotFoundError(Exception): + pass + +class MaClasse: + pass + +class MaClasseDeux: + pass + +binding = dict(un=MaClasse, deux=MaClasseDeux) + +def ma_factory(key): + if key in binding: + return binding[key]() + else: + return NotFoundError("keskece?") + + diff --git a/algo/poo/cours/snippets/pystartup b/algo/poo/cours/snippets/pystartup new file mode 100644 index 0000000..a4a48de --- /dev/null +++ b/algo/poo/cours/snippets/pystartup @@ -0,0 +1,28 @@ +# Add auto-completion and a stored history file of commands to your Python +# interactive interpreter. Requires Python 2.0+, readline. Autocomplete is +# bound to the Esc key by default (you can change it - see readline docs). +# +# Store the file in ~/.pystartup, and set an environment variable to point to +# it, e.g. "export PYTHONSTARTUP=/max/home/itamar/.pystartup" in bash. +# +# Note that PYTHONSTARTUP does *not* expand "~", so you have to put in the full +# path to your home directory. +import rlcompleter +import readline +readline.parse_and_bind("tab: complete") + +import os +histfile = os.path.join(os.environ["HOME"], ".pyhist") +try: + readline.read_history_file(histfile) +except IOError: + pass + +import atexit +atexit.register(readline.write_history_file, histfile) +del os, histfile + +# enhanced completion +#import rlcompleter2 +#rlcompleter2.setup() + diff --git a/algo/poo/cours/snippets/sorter.py b/algo/poo/cours/snippets/sorter.py new file mode 100644 index 0000000..373d2d8 --- /dev/null +++ b/algo/poo/cours/snippets/sorter.py @@ -0,0 +1,38 @@ +class Sorter: + def sort(self, list): + for i in range(len(list) - 1): + for j in range(i, len(list)): + if self.compareItems(list[i], list[j]): + list[i], list[j] = list[j], list[i] + + def getName(self): + return "Trieur de liste" + + def getDescription(self): + raise NotImplementedError + + def compareItems(self, item1, item2): + raise NotImplementedError + +class AscendantSorter(Sorter): + def compareItems(self, item1, item2): + return item1 >= item2 + def getDescription(self): + return "Tri par ordre normal" + def getName(self): + return "Ascendant" + +class DescendantSorter(Sorter): + def compareItems(self, item1, item2): + return item1 <= item2 + def getDescription(self): + return "Tri par ordre inverse" + +if __name__ == '__main__': + list = ['b', 'e', 'a', 'c', 'z'] + s = AscendantSorter() + s.sort(list) + print list + s = DescendantSorter() + s.sort(list) + print list diff --git a/algo/poo/cours/snippets/specialmethods.py b/algo/poo/cours/snippets/specialmethods.py new file mode 100644 index 0000000..88f6543 --- /dev/null +++ b/algo/poo/cours/snippets/specialmethods.py @@ -0,0 +1,10 @@ +class Zone(object): + def __init__(self, name, level=0): + self.name = name + self.level = level + + def __add__(self, other): + return Zone(self.name + other.name, level=self.level+other.level) + + def __cmp__(self, other): + return cmp(self.level, other.level) diff --git a/algo/poo/cours/snippets/wrap.py b/algo/poo/cours/snippets/wrap.py new file mode 100644 index 0000000..0a48215 --- /dev/null +++ b/algo/poo/cours/snippets/wrap.py @@ -0,0 +1,22 @@ +class Wrap(object): + def __init__(self, name, wrap): + self.slots = ('_name', '_w') + self._name = name or "wrapped_element" + self._w = wrap + + def __getattr__(self, name): + if name in self.slots: + return getattr(self, name) + else: + return getattr(self._w, name) + +# def get_w(self, name): +# return getattr(self._w, name) + +# def set_w(self, name, value): +# return setattr(self._w, name, value) + +# _w = property (get_w, set_w) + + def __repr__(self): + return "[W_Element %s]"% repr(self._name)