Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Géométrie et distance

23 views
Skip to first unread message

Michael Grünewald

unread,
Feb 7, 2012, 1:18:54 AM2/7/12
to
Salut,

j'ai implémenté quelques classes représentant des figures dans le plan
(des points, des lignes brisées, …) et j'ai besoin de calculer des
distances entre deux objets ou des intersections.

J'aimerais avoir quelques indications sur la façon de s'en tirer habilement.


La méthode malhabile que j'utilise jusqu'ici consiste à ajouter une
méthode distance_to_<figure> à chaque classe qui doit calculer sa
distance à une <figure>. Le moins qu'on puisse dire est que ce n'est ni
très joli, ni très maintenable!

Je pensais créer une classe singleton «PlanStrategy» en charge de
calculer les distances (et les intersections) qui apprend des cas
particuliers et qui sait les généraliser. Par exemple, chaque classe de
figure est capable de se présenter comme une réunion de figures simples
dont on sait calculer les distances mutuelles et les intersections, et
cette présentation est utilisée par «PlanStrategy» pour traiter les cas
qu'il ne connaît pas.

Quelles sont les suggestions des développeurs chevronnés dans ce cas …
de figure?


J'ai débuté Python il y a deux semaines, le langage est très facile à
prendre en main quand on a de l'expérience de la programmation. Je
trouve que le tutoriel a quelques graves lacunes (le mot clef «return»
n'y apparaît même pas, il me semble!) mais fournit une introductiuon
efficace.

J'ai cependant quelques problèmes avec la mise au point des programmes,
je fais partie des gens qui font beaucoup de petites fautes
d'inattention et j'ai l'habitude que le compilateur les détecte toutes
pour moi. Quelles sont les techniques de débogages plus avancées que le
saupoudrage de «print» du code? Saupoudrage qui du reste n'est pas très
recommandé s'il s'agit de traquer une erreur causée par une mauvaise
valeur envoyée vers le code d'une bibliothèque. Y-a'il des outils pour
«tracer» le code, qui notamment afficheraient les affectations de variables?


Merci pour vos conseils et votre aide!
--
Michael

Nicolas

unread,
Feb 7, 2012, 3:57:00 AM2/7/12
to
>
> J'ai débuté Python il y a deux semaines, le langage est très facile à
> prendre en main quand on a de l'expérience de la programmation. Je
> trouve que le tutoriel a quelques graves lacunes (le mot clef «return»
> n'y apparaît même pas, il me semble!) mais fournit une introductiuon
> efficace.
>
Des introductions à Python, il y en a plein. Des simples, des
compliquées, en français, en anglais...

> J'ai cependant quelques problèmes avec la mise au point des programmes,
> je fais partie des gens qui font beaucoup de petites fautes
> d'inattention et j'ai l'habitude que le compilateur les détecte toutes
> pour moi. Quelles sont les techniques de débogages plus avancées que le
> saupoudrage de «print» du code? Saupoudrage qui du reste n'est pas très
> recommandé s'il s'agit de traquer une erreur causée par une mauvaise
> valeur envoyée vers le code d'une bibliothèque. Y-a'il des outils pour
> «tracer» le code, qui notamment afficheraient les affectations de
> variables?
>
Il y a des environnements de développements qui permettent de faire de
l'analyse de code. J'utilise Eclipse avec le plugin PyDev. Un peu lourd
mais très efficace. Il existe également d'autres solutions que je
n'utilise pas.

Nicolas

Michel Claveau - MVP

unread,
Feb 7, 2012, 8:15:26 AM2/7/12
to
Salut !

Pour calculer les distances, une simple fonction peut suffire.
Exemple :
# -*- coding: utf-8 -*-

import math

class point(object):

def __init__(self,x=0,y=0):
self.x=float(x)
self.y=float(y)


def distance(pdebut,pfin):
return math.sqrt(math.pow(pfin.y-pdebut.y,2)+math.pow(pfin.x-pdebut.x,2))


a=point(1,2)
b=point(8,3)
print distance(a,b)

print distance(point(5,6),point(2,2))





Pour déboguer, regarde la doc de Python sur le module pdb
C'est simple, mais déjà suffisant.


@-salutations
--
Michel Claveau

Alain Ketterlin

unread,
Feb 7, 2012, 10:46:50 AM2/7/12
to
Michael Grünewald <mich...@yahoo.de> writes:

> j'ai implémenté quelques classes représentant des figures dans le plan
> (des points, des lignes brisées, …) et j'ai besoin de calculer des
> distances entre deux objets ou des intersections.
>
> J'aimerais avoir quelques indications sur la façon de s'en tirer habilement.
>
> La méthode malhabile que j'utilise jusqu'ici consiste à ajouter une
> méthode distance_to_<figure> à chaque classe qui doit calculer sa
> distance à une <figure>. Le moins qu'on puisse dire est que ce n'est
> ni très joli, ni très maintenable!

Oui, mais il n'y a pas vraiment de solution, il n'y a pas de moyen
général de définir la distance. (Voir plus bas.)

En fait, le calcul de la distance va dans chaque cas dépendre du type
des deux figures impliquées. Les langages objets comme Python ne font de
liaison dynamique que sur un paramètre. Un langage comme... Common Lisp
(oui, Lisp, ou plutôt CLOS, son extension objet) te permet de choisir
une version en fonction de tous les types de paramètres.

> Je pensais créer une classe singleton «PlanStrategy» en charge de
> calculer les distances (et les intersections) qui apprend des cas
> particuliers et qui sait les généraliser. Par exemple, chaque classe
> de figure est capable de se présenter comme une réunion de figures
> simples dont on sait calculer les distances mutuelles et les
> intersections, et cette présentation est utilisée par «PlanStrategy»
> pour traiter les cas qu'il ne connaît pas.

C'est une très bonne idée. Vraiment. Il reste encore à définir ce qu'est
la distance (sûrement le min des distances des composants). Mais le
principe est très bien, je trouve.

[...]
> J'ai cependant quelques problèmes avec la mise au point des
> programmes, je fais partie des gens qui font beaucoup de petites
> fautes d'inattention et j'ai l'habitude que le compilateur les détecte
> toutes pour moi. Quelles sont les techniques de débogages plus
> avancées que le saupoudrage de «print» du code?

Il y a pdb (je n'ai jamais essayé, en général je m'en sors avec des
print...)

Si tu en arrives à des programmes assez compliqués, tu vas amèrement
regretter le typage statique. Mais c'est un autre débat. La réponse
habituelle pour python est : écrire des tests unitaires, des tas de
tests unitaires, etc.

-- Alain.

Michael Grünewald

unread,
Feb 7, 2012, 11:37:12 AM2/7/12
to
Nicolas wrote:
>> […] Je trouve que le tutoriel a quelques graves lacunes (le mot clef «return»
>> n'y apparaît même pas, il me semble!) mais fournit une introductiuon
>> efficace.
>>
> Des introductions à Python, il y en a plein. Des simples, des
> compliquées, en français, en anglais...

En l'occurence il s'agissait du tutoriel canonique appartenant à la doc
officielle.

>> J'ai cependant quelques problèmes avec la mise au point des programmes, […] Y-a'il des outils pour
>> «tracer» le code, qui notamment afficheraient les affectations de
>> variables?
>>
> Il y a des environnements de développements qui permettent de faire de
> l'analyse de code. J'utilise Eclipse avec le plugin PyDev. Un peu lourd
> mais très efficace. Il existe également d'autres solutions que je
> n'utilise pas.

Ok merci pour l'info.
--
Michael

Michael Grünewald

unread,
Feb 7, 2012, 11:38:52 AM2/7/12
to
Salut,

Michel Claveau - MVP wrote:
> Pour calculer les distances, une simple fonction peut suffire.
> Exemple :
> […]

merci pour ta réponse, mais es-tu bien sûr d'avoir lu la question? :-)

> Pour déboguer, regarde la doc de Python sur le module pdb
> C'est simple, mais déjà suffisant.

Merci, je regarderai le module pdb.
--
Michael

Michael Grünewald

unread,
Feb 7, 2012, 12:07:02 PM2/7/12
to
Bonjour Alain,

merci pour ta réponse,

Alain Ketterlin wrote:
> Michael Grünewald<mich...@yahoo.de> writes:
>
>> j'ai implémenté quelques classes représentant des figures dans le plan
>> (des points, des lignes brisées, …) et j'ai besoin de calculer des
>> distances entre deux objets ou des intersections. […]
>
> En fait, le calcul de la distance va dans chaque cas dépendre du type
> des deux figures impliquées. Les langages objets comme Python ne font de
> liaison dynamique que sur un paramètre. Un langage comme... Common Lisp
> (oui, Lisp, ou plutôt CLOS, son extension objet) te permet de choisir
> une version en fonction de tous les types de paramètres.

je ne comprends pas très bien ce que tu veux dire: «Python ne [fait] de
liaison dynamique que sur un paramètre.» La liaison dynamique, c'est
bien ce qu'on appelle aussi la résolution des méthodes? C'est-à dire
l'opération qui étant donné un objet et une méthode trouve la bonne
fonction a appeler?

La paramètre dont tu parles dans le cas de Python, c'est la classe de
l'objet, c'est ça (la valeur de retour de type)? Dans le cas de Lisp ,
je ne vois pas du tout ce que cela peut vouloir dire…

>> Je pensais créer une classe singleton «PlanStrategy» en charge de
>> calculer les distances (et les intersections) qui apprend des cas
>> particuliers et qui sait les généraliser. Par exemple, chaque classe
>> de figure est capable de se présenter comme une réunion de figures
>> simples dont on sait calculer les distances mutuelles et les
>> intersections, et cette présentation est utilisée par «PlanStrategy»
>> pour traiter les cas qu'il ne connaît pas.
>
> C'est une très bonne idée. Vraiment.

Merci! :) Manifestement je ne suis pas sur un trop mauvaise voie…

> Il reste encore à définir ce qu'est
> la distance (sûrement le min des distances des composants).

La distance de A à B (A, B parties du plan) est l'inf des distances
entre a et b, pour a dans A et b dans B. Donc effectivement, dans le
cas des unions finies, la distance est le min des distances des
composantes. Pour des objets à p et q composantes, cela fait p*q
distances à calculer, si on utilise cette approche générale.

>> J'ai cependant quelques problèmes avec la mise au point des
>> programmes, je fais partie des gens qui font beaucoup de petites
>> fautes d'inattention et j'ai l'habitude que le compilateur les détecte
>> toutes pour moi. Quelles sont les techniques de débogages plus
>> avancées que le saupoudrage de «print» du code?
>
> Il y a pdb (je n'ai jamais essayé, en général je m'en sors avec des
> print...)
>
> Si tu en arrives à des programmes assez compliqués, tu vas amèrement
> regretter le typage statique.

C'est déjà fait! :) J'ai implémenté un algorithme de triangulation de
Delaunay, cela m'a pris un temps complètement intolérable,
essentiellement à cause de fautes de frappe… j'ai regretté OCaml avec
lequel j'aurais réglé ça en une demi-journée au lieu de deux jours.

> Mais c'est un autre débat. La réponse
> habituelle pour python est : écrire des tests unitaires, des tas de
> tests unitaires, etc.

Très bien, je me plierai à ce nouveau mantra. Est-ce qu'il a des outils
ou des méthodologies spéciaux pour écrire les tests unitaires en Python?
--
Michael

Alain Ketterlin

unread,
Feb 7, 2012, 1:17:33 PM2/7/12
to
Michael Grünewald <mich...@yahoo.de> writes:

>>> j'ai implémenté quelques classes représentant des figures dans le plan
>>> (des points, des lignes brisées, …) et j'ai besoin de calculer des
>>> distances entre deux objets ou des intersections. […]
>>
>> En fait, le calcul de la distance va dans chaque cas dépendre du type
>> des deux figures impliquées. Les langages objets comme Python ne font de
>> liaison dynamique que sur un paramètre. Un langage comme... Common Lisp
>> (oui, Lisp, ou plutôt CLOS, son extension objet) te permet de choisir
>> une version en fonction de tous les types de paramètres.
>
> je ne comprends pas très bien ce que tu veux dire: «Python ne [fait]
> de liaison dynamique que sur un paramètre.» La liaison dynamique,
> c'est bien ce qu'on appelle aussi la résolution des méthodes? C'est-à
> dire l'opération qui étant donné un objet et une méthode trouve la
> bonne fonction a appeler?

C'est exactement cela.

> La paramètre dont tu parles dans le cas de Python, c'est la classe de
> l'objet, c'est ça (la valeur de retour de type)? Dans le cas de Lisp
> , je ne vois pas du tout ce que cela peut vouloir dire…

Si tu as o1.distance(o2) :
- c'est le type de o1 qui va déterminer la méthode
- mais le calcul effectif va dépendre des types de o1 et o2
Typiquement, la méthode appelée va tester le type de o2 (il y a des
astuces pour éviter les tests de type explicites).

En Lisp tu vas écrire (distance o1 o2) -- c'est un détail de syntaxe --
mais tu peux définir diverses versions de la fonction distance selon les
types de o1 et o2 (une première pour Point*Ligne, une pour Point*Point,
etc.) C'est juste une généralisation à plusieurs dimensions de la
"résolution des méthodes".

C'est ton cas : ce qui détermine la méthode à appeler, c'est le couple
des types des paramètres. Tu ne peux pas écrire cela dans un langage
object à la Python/C++/Java/etc. (en fait, dans tous sauf Lisp/CLOS et
Dylan, et peut-être quelques autres).

Bref.

[...]
>> Si tu en arrives à des programmes assez compliqués, tu vas amèrement
>> regretter le typage statique.
>
> C'est déjà fait! :) J'ai implémenté un algorithme de triangulation de
> Delaunay, cela m'a pris un temps complètement intolérable,
> essentiellement à cause de fautes de frappe… j'ai regretté OCaml avec
> lequel j'aurais réglé ça en une demi-journée au lieu de deux jours.

On est bien d'accord.

>> Mais c'est un autre débat. La réponse habituelle pour python est :
>> écrire des tests unitaires, des tas de tests unitaires, etc.
>
> Très bien, je me plierai à ce nouveau mantra. Est-ce qu'il a des
> outils ou des méthodologies spéciaux pour écrire les tests unitaires
> en Python?

Il y a quelques infos dans la page du module unittest, à
http://docs.python.org/library/unittest.html

-- Alain.

Paul Gaborit

unread,
Feb 7, 2012, 7:48:33 PM2/7/12
to

À (at) Tue, 07 Feb 2012 19:17:33 +0100,
Alain Ketterlin <al...@dpt-info.u-strasbg.fr> écrivait (wrote):

> C'est ton cas : ce qui détermine la méthode à appeler, c'est le couple
> des types des paramètres.

Effectivement.

> Tu ne peux pas écrire cela dans un langage object à la
> Python/C++/Java/etc. (en fait, dans tous sauf Lisp/CLOS et Dylan, et
> peut-être quelques autres).

Heu... Le polymorphisme permet pourtant exactement cela. Il est
explicite en Java et en C++ (et beaucoup d'autres langages orientés
objet à typage fort). Il est "simulable" en Python/Perl/Ruby bien que
non explicite.


--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>

Alain Reymond

unread,
Feb 8, 2012, 3:26:53 AM2/8/12
to
Bonjour,

Un excellent IDE Python est PyScripter
http://code.google.com/p/pyscripter/ :
- bon IDE, complètement automatique de code
- débogage, points d'arrêts, suivi des variables, analyse rétrospective,
etc...

Facilite la vie du développeur.

Cdlt.


AR

Alain Ketterlin

unread,
Feb 8, 2012, 5:51:50 AM2/8/12
to
Oui, mais pas avec deux arguments. Même pour C++ et Java. Il faut faire
l'équivalent de :

class A:
# dispatch
def distance(self,other):
return other.distance_to_A(self)
# versions spécialisées
def distance_to_A(self,other):
# ici on sait que other est de type A
return ...
def distance_to_B(self,other):
# ici on sait que other est de type B
return ...

class B:
# dispatch
def distance(self,other):
return other.distance_to_B(self)
# versions spécialisées
def distance_to_A(self,other):
# ici on sait que other est de type A
return ...
def distance_to_B(self,other):
# ici on sait que other est de type B
return ...

En CLOS on écrit des fonctions génériques [*] hors de toute classe, donc
aucun des paramètres ne prime sur les autres. On écrirait quelque chose
qui ressemble à :

(defmethod distance ((a A) (a A)) ...)
(defmethod distance ((a A) (b B)) ...)
(defmethod distance ((b B) (a A)) ...)
(defmethod distance ((b B) (b B)) ...)

Le dispatch se fait tout seul.

-- Alain.

[*] Le terme est mal choisi, mais à l'époque c'était cohérent.

Paul Gaborit

unread,
Feb 8, 2012, 7:32:20 AM2/8/12
to

À (at) Wed, 08 Feb 2012 11:51:50 +0100,
Alain Ketterlin <al...@dpt-info.u-strasbg.fr> écrivait (wrote):

> Oui, mais pas avec deux arguments. Même pour C++ et Java.

Vous avez tort dans les deux cas. Java et C++ intègrent une signature à
chaque méthode (et fonction dans le cas de C++). Cette signature
contient le nom de la méthode (ou fonction) ainsi que l'ordre et le type
des arguments.

> En CLOS on écrit des fonctions génériques [*] hors de toute classe, donc
> aucun des paramètres ne prime sur les autres. On écrirait quelque chose
> qui ressemble à :
>
> (defmethod distance ((a A) (a A)) ...)
> (defmethod distance ((a A) (b B)) ...)
> (defmethod distance ((b B) (a A)) ...)
> (defmethod distance ((b B) (b B)) ...)
>
> Le dispatch se fait tout seul.

Ce ne sont pas des fonctions génériques (les fonctions génériques sont
ce que proposent par exemple les templates du C++). C'est juste une
fonction polymorphique. Et on procède exactement de la même manière en
C++ !

Alain Ketterlin

unread,
Feb 8, 2012, 10:09:40 AM2/8/12
to
Paul Gaborit <Paul.G...@invalid.invalid> writes:

> À (at) Wed, 08 Feb 2012 11:51:50 +0100,
> Alain Ketterlin <al...@dpt-info.u-strasbg.fr> écrivait (wrote):
>
>> Oui, mais pas avec deux arguments. Même pour C++ et Java.
>
> Vous avez tort dans les deux cas. Java et C++ intègrent une signature à
> chaque méthode (et fonction dans le cas de C++). Cette signature
> contient le nom de la méthode (ou fonction) ainsi que l'ordre et le type
> des arguments.

Tu ne parles pas de la même chose que moi. (Peut-être parce que j'ai
oublié de préciser que les deux classes A et B dérivent de la même
classe.)

>> En CLOS on écrit des fonctions génériques [*] hors de toute classe, donc
>> aucun des paramètres ne prime sur les autres. On écrirait quelque chose
>> qui ressemble à :
>>
>> (defmethod distance ((a A) (a A)) ...)
>> (defmethod distance ((a A) (b B)) ...)
>> (defmethod distance ((b B) (a A)) ...)
>> (defmethod distance ((b B) (b B)) ...)
>>
>> Le dispatch se fait tout seul.
>
> Ce ne sont pas des fonctions génériques (les fonctions génériques sont
> ce que proposent par exemple les templates du C++).

Tu as tort d'avoir supprimé la note (signalée avec [*]) que j'avais pris
la précaution d'ajouter à mon message. En CLOS ça s'appelle des
fonctions génériques, définie avec defgeneric.

> C'est juste une fonction polymorphique.

Tu sous-estimes le problème. Ajoute une sous-classe A1 de A, et tu
comprendras : la surcharge devient inopérante (puisqu'elle utilise le
type statique).

> Et on procède exactement de la même manière en C++ !

Non, tu n'as pas compris le problème. Tu parles de résolution statique
de la surcharge alors que je parle de résolution dynamique sur plusieurs
types. Lis http://en.wikipedia.org/wiki/Multiple_dispatch

-- Alain.

Damien Wyart

unread,
Feb 9, 2012, 12:58:03 AM2/9/12
to
* Alain Ketterlin <al...@dpt-info.u-strasbg.fr> in fr.comp.lang.python:
> Non, tu n'as pas compris le problème. Tu parles de résolution statique
> de la surcharge alors que je parle de résolution dynamique sur
> plusieurs types. Lis http://en.wikipedia.org/wiki/Multiple_dispatch

Sur cette page, il y a justement plusieurs exemples en Python (certains
utilisant des modules spécifiques qui seraient peut-être un peu lourd
ici) qui pourraient peut-être être repris dans la cadre de la question
qui a initié ce fil de discussion.

--
DW

Laurent Claessens

unread,
Feb 9, 2012, 8:02:38 AM2/9/12
to
Il 07/02/2012 07:18, Michael Grünewald ha scritto:
> Salut,
>
> j'ai implémenté quelques classes représentant des figures dans le plan
> (des points, des lignes brisées, …) et j'ai besoin de calculer des
> distances entre deux objets ou des intersections.
>
> J'aimerais avoir quelques indications sur la façon de s'en tirer habilement.

Si tu as vraiment besoin de math, tu peux utiliser Sage (qui est un
module de mathématique symbolique pour python[1])

www.sagemath.org

ça te permet de calculer des intersections de n'importe quoi dont tu
connais les équations (pourvu que ce ne soit pas trop compliqué)


Si tu n'as rien d'autre que des droites, c'est sans doute très lourd
pour pas grand chose, mais si tu as des objets compliqués (courbes
paramétriques), alors c'est vraiment ce qu'il te faut.
Ça se programme en python.


Si ça t'intéresse, j'ai écrit un truc qui définit toutes sortes de
figures dans le plan (cercles, droites, courbes paramétrées, champ de
vecteurs, vecteurs normaux, tangents, intersections, ...) et qui exporte
les dessins en pstricks pour LaTeX :

http://student.ulb.ac.be/~lclaesse/phystricks-documentation/_build/html/index.html

Les sources sont ici :
http://gitorious.org/phystricks


Bonne aprème
Laurent


[1] C'est pas tout à fait vrai, mais en gros c'est ce que c'est.



Paul Gaborit

unread,
Feb 9, 2012, 10:45:36 AM2/9/12
to

À (at) Wed, 08 Feb 2012 16:09:40 +0100,
Alain Ketterlin <al...@dpt-info.u-strasbg.fr> écrivait (wrote):

> Paul Gaborit <Paul.G...@invalid.invalid> writes:
>
>> À (at) Wed, 08 Feb 2012 11:51:50 +0100,
>> Alain Ketterlin <al...@dpt-info.u-strasbg.fr> écrivait (wrote):
>>
>>> Oui, mais pas avec deux arguments. Même pour C++ et Java.
>>
>> Vous avez tort dans les deux cas. Java et C++ intègrent une signature à
>> chaque méthode (et fonction dans le cas de C++). Cette signature
>> contient le nom de la méthode (ou fonction) ainsi que l'ordre et le type
>> des arguments.
>
> Tu ne parles pas de la même chose que moi. (Peut-être parce que j'ai
> oublié de préciser que les deux classes A et B dérivent de la même
> classe.)

Et sans doute manque-t-il le fait que le choix se fait dynamiquement
(donc lors de l'exécution et non lors de la compilation). C'est l'aspect
qui m'avait échappé et que tu sous-entendais.

>> Ce ne sont pas des fonctions génériques (les fonctions génériques sont
>> ce que proposent par exemple les templates du C++).
>
> Tu as tort d'avoir supprimé la note (signalée avec [*]) que j'avais pris
> la précaution d'ajouter à mon message. En CLOS ça s'appelle des
> fonctions génériques, définie avec defgeneric.

L'appelation « générique » adoptée par CLOS ne me semble pas du tout
adaptée... Mais ce n'est pas grave si on sait de quoi on parle.

>> C'est juste une fonction polymorphique.
>
> Tu sous-estimes le problème. Ajoute une sous-classe A1 de A, et tu
> comprendras : la surcharge devient inopérante (puisqu'elle utilise le
> type statique).


C'est la comparaison avec C++ qui m'e enduit d'erreur ! C++ ne fait pas
(tout seul) de typage dynamique : pour qu'une méthode soit choisie
dynamiquement en fonction du type réel de l'objet pointé, il *faut* que
la méthode soit virtuelle. Et effectivement, pour aller plus loin (donc
en tenant compte des arguments), il faut écrire soi-même les tests
permettant de déterminer le type réel des arguments.

>> Et on procède exactement de la même manière en C++ !
>
> Non, tu n'as pas compris le problème. Tu parles de résolution statique
> de la surcharge alors que je parle de résolution dynamique sur plusieurs
> types. Lis http://en.wikipedia.org/wiki/Multiple_dispatch

C'est donc bien l'aspect dynamique de la chose qui est en cause.

En CLOS, que se passe-t-il en cas d'héritage multiple ?

Exemple :

B C
\ /
D

(D hérite de B et C).

Si j'ai définie des fonctions "génériques" (au sens CLOS) pour calculer
la distance entre des objets de type B ou C et si j'appelle la fonction
'distance' avec deux objets d1 et d2 (de type D), quelle est la fonction
'distance' qui sera choisie ? J'imagine qu'il y a une sorte de priorité
dans l'ordre d'héritage (à moins que CLOS n'accepte pas l'héritage
multiple).

Alain Ketterlin

unread,
Feb 9, 2012, 11:50:48 AM2/9/12
to
Paul Gaborit <Paul.G...@invalid.invalid> writes:

>> [...] http://en.wikipedia.org/wiki/Multiple_dispatch

> En CLOS, que se passe-t-il en cas d'héritage multiple ?
>
> Exemple :
>
> B C
> \ /
> D
>
> (D hérite de B et C).
>
> Si j'ai défini des fonctions "génériques" (au sens CLOS) pour calculer
> la distance entre des objets de type B ou C et si j'appelle la fonction
> 'distance' avec deux objets d1 et d2 (de type D), quelle est la fonction
> 'distance' qui sera choisie ? J'imagine qu'il y a une sorte de priorité
> dans l'ordre d'héritage (à moins que CLOS n'accepte pas l'héritage
> multiple).

Oui, il y a de l'héritage multiple. Chaque classe définit une liste
(ordonnée) de super-classes, et cet ordre local est maintenu dans le
parcours du graphe (qui doit être acyclique). Après, les classes sont
parcourues dans l'ordre d'un tri topologique (toutes les sous-classes
d'une classe A apparaissent avant A).

Dans l'exemple, si D est définie avec pour superclasses B puis C,
l'ordre de recherche est D B C pour chaque paramètre. Donc l'ordre des
méthodes est DD BD CD BD BB BC CD CB CC. La première qui existe est
appliquée. Si on avait A superclasse de B et C, l'ordre par paramètre
serait D B C A.

Déjà ça, c'est assez sport pour garder le contrôle, mais en plus CLOS
permet, dans une méthode, d'appeler la suivante (dans la liste des
méthodes possibles). Sans compter qu'on peut "garnir" des méthodes avec
des appels implicites "avant", "après" et "autour" de chaque méthode. Et
bien sûr on peut changer tout cela (par exemple en définissant une
fonction qui va choisir la méthode à appliquer).

Bref, c'est Common Lisp...

-- Alain.

Michael Grünewald

unread,
Feb 21, 2012, 12:43:31 PM2/21/12
to
Bonjour Alain,

Alain Reymond wrote:

> Un excellent IDE Python est PyScripter
> http://code.google.com/p/pyscripter/ :
> - bon IDE, complètement automatique de code
> - débogage, points d'arrêts, suivi des variables, analyse rétrospective,
> etc...

merci pour ta suggestion, je crois cependant comprendre que pyscripter
ne tourne que sous windows, et je ne peux donc pas l'utiliser sous mon
FreeBSD.
--
Michael

Michael Grünewald

unread,
Feb 21, 2012, 12:49:39 PM2/21/12
to
Bonjour Alain,

Alain Ketterlin wrote:
> […une réponse bien détaillée à laquelle j'ai mis beaucoup de temps à
répondre!…]

merci beaucoup pour ta réponse très complète! J'ai encore programmé
pendant deux semaines en Python, et je regrette chaque jour un peu plus
le typage statique de OCaml… celui qui trouve les erreurs quand on
change l'interface des fonctions et quand on change le nom d'un
paramètre au début d'une boucle.

Pour le débogage des programmes je reprends mes habitudes de programmeur
TeX: relire le code avant d'essayer de lire le message d'erreur! :-)
--
Michael

Michael Grünewald

unread,
Feb 21, 2012, 1:01:18 PM2/21/12
to
Bonjour Laurent,

Laurent Claessens wrote:
> Il 07/02/2012 07:18, Michael Grünewald ha scritto:
>> j'ai implémenté quelques classes représentant des figures dans le plan
>> (des points, des lignes brisées, …) et j'ai besoin de calculer des
>> distances entre deux objets ou des intersections.
>>
>> J'aimerais avoir quelques indications sur la façon de s'en tirer
>> habilement.
>
> Si tu as vraiment besoin de math, tu peux utiliser Sage (qui est un
> module de mathématique symbolique pour python[1])

merci pour ta réponse mais elle ne correspond pas du tout à ma question.
Mon problème n'est pas de résoudre l'exercice de 3ème qui consiste à
calculer l'intersection de deux droites dans un plan, mais de présenter
ces fonctions dans une interface agréable pour l'utilisateur et le
programmeur. C'est une question de génie logiciel, en quelque sorte.

> ça te permet de calculer des intersections de n'importe quoi dont tu
> connais les équations (pourvu que ce ne soit pas trop compliqué)

À mon avis «n'importe quoi» devient assez vite «trop compliqué». Quelle
représentation pour la réponse? S'il s'agit de donner des équations de
A inter B à partir des équations de A et de B, je peux le faire de tête! :)
--
Michael

Laurent Claessens

unread,
Feb 22, 2012, 4:27:51 AM2/22/12
to Michael Grünewald

> merci pour ta réponse mais elle ne correspond pas du tout à ma question.
> Mon problème n'est pas de résoudre l'exercice de 3ème qui consiste à
> calculer l'intersection de deux droites dans un plan, mais de présenter
> ces fonctions dans une interface agréable pour l'utilisateur et le
> programmeur. C'est une question de génie logiciel, en quelque sorte.


Ah ok. J'avais compris que tu cherchais à résoudre les équations.
J'avais pas bien compris que tu demandais essentiellement quelle
structure donner au logiciel. mea cupla.

>> ça te permet de calculer des intersections de n'importe quoi dont tu
>> connais les équations (pourvu que ce ne soit pas trop compliqué)
>
> À mon avis «n'importe quoi» devient assez vite «trop compliqué». Quelle
> représentation pour la réponse?

Juste pour l'exemple : l'intersection entre un cercle et un 1/x en
utilisant Sage en mode interactif :

sage: f(x,y)=x**2+y**2-4
sage: g(x)=1/x
sage: solve( [f(x,y)==0,y==g(x)],[x,y] )
[[x == -sqrt(sqrt(3) + 2), y == -1/sqrt(sqrt(3) + 2)], [x ==
sqrt(sqrt(3) + 2), y == 1/sqrt(sqrt(3) + 2)], [x == -sqrt(-sqrt(3) + 2),
y == -1/sqrt(-sqrt(3) + 2)], [x == sqrt(-sqrt(3) + 2), y ==
1/sqrt(-sqrt(3) + 2)]]

Sage donne donc la réponse sous forme de liste de liste. Chaque élément
est une liste [x==A,y==B]

Pour avoir la coordonnée x de la première intersection :
sage: S=solve( [f(x,y)==0,y==g(x)],[x,y] )
sage: S[0][0].rhs() #rhs=Right Hand Side
-sqrt(sqrt(3) + 2)


Bon, évidemment si le but est de faire un truc agréable à utiliser pour
l'utilisateur, il faut ajouter quelque couches pour cacher l'utilisation
de Sage ;)

Bonne aprème
Laurent

Alain Reymond

unread,
Feb 22, 2012, 6:30:48 AM2/22/12
to


Le 21/02/2012 18:43, Michael Grünewald a écrit :
>> Un excellent IDE Python est PyScripter
>> http://code.google.com/p/pyscripter/ :
>> - bon IDE, complètement automatique de code
>> - débogage, points d'arrêts, suivi des variables, analyse rétrospective,
>> etc...
>
> merci pour ta suggestion, je crois cependant comprendre que pyscripter
> ne tourne que sous windows, et je ne peux donc pas l'utiliser sous mon
> FreeBSD.

En effet.
D'après le site, ça tourne sous Ubuntu avec Wine. Peut-être tester avec
FreeBSD.

Alain

0 new messages