Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from model import LocalDatabaseModel
from view import ConsoleView
from presenter import Presenter

Presenter(LocalDatabaseModel(), ConsoleView()).run()
1 change: 1 addition & 0 deletions dsonames.json

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import json

class LocalDatabaseModel:
"""Modèle utilisant une base de donnée locale en JSON"""
def __init__(self):
# `utf-8` pour être sûr que le fichier est lu correctement quel que soit l'OS
with open("dsonames.json", "r+", encoding="utf-8") as f:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pourquoi ouvrir le fichier avec la permission r+, qui signifie lecture + écriture ? r, lecture seule, devrait être suffisant

self.values = json.load(f)
sorted(self.values)

def names(self):
"""Obtient la liste des noms, en anglais, des objets disponibles"""
result = []
for _, planet in self.values.items():
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for _, planet in self.values.items():
for planet in self.values.values():

result.append(planet["name"])
return result

def translated_names(self, language):
"""Obtient une correspondance entre noms et noms traduits dans la langue donnée."""
return [(p["name"], p[language]) for p in self.values.values() if language in p]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Est-ce normal que certaines planètes n'ont pas de nom traduit ? Devrions-nous le documenter ?

35 changes: 35 additions & 0 deletions presenter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class Presenter:
"""Presenter dans l'architecture MVP de l'app, qui gère les commandes utilisateur."""

def __init__(self, model, view):
"""Crée un Presenter avec un modèle et une view donnés."""
self.model = model
self.view = view
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_model et _view puisque ce sont des champs privés


def _show_list(self, lst):
"""Affiche la liste donnée via la view."""
self.view.show("\n".join(["- " + str(s) for s in lst]))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plutôt "* " pour une liste à puces, non ?


def onInput(self, command):
"""Gère l'entrée utilisateur d'une commande donnée."""
if command == "liste":
self._show_list(self.model.names())
return

parts = command.split(' ')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
parts = command.split(' ')
chunks = command.split(' ')

if parts[0] == "reccerche":
# TODO: Recherche partielle (ou peut-être expressions régulières ?)
names = self.model.names()
self._show_list([n for n in names if parts[0] in n])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self._show_list([n for n in names if parts[0] in n])
self._show_list([n for n in names if parts[1] in n])

return

if parts[0] == "traduire":
self._show_list(self.model.translated_names(parts[1]))
return

self.view.show("Commande inconnue")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pas génial


def run(self):
"""Gère l'entrée utilisateur d'une commande donnée."""
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ce commentaire de doc est dupliqué avec la méthode onInput

self.view.show("Bonjour! Cette application vous donne des informations sur les groupes d'étoiles.")
self.view.run(self, "Écrivez 'liste', 'recherche <texte>', ou 'traduire <langue>' (ou Ctrl+C): ")
50 changes: 50 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from unittest import TestCase

from model import LocalDatabaseModel
from presenter import Presenter

# Vérifions que les données soient bien chargées
class LocalDatabaseModelTests(TestCase):
def test_names(self):
m = LocalDatabaseModel()
self.assertIn("Sextans Dwarf Spheroidal Galaxy", m.names())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devrions-nous tester l'ordre des planètes ?


def test_translate(self):
m = LocalDatabaseModel()
self.assertIn(("Sextans Dwarf Spheroidal Galaxy", "Galaxie naine sphéroïdale du Sextant"), m.translated_names("fr"))


class FakeModel:
def names(self):
return ["X", "Y", "Z"]

def translated_names(self, language):
return [("X", "A"), ("Y", language), ("Z", "C")]

class FakeView:
def __init__(self, inputs):
self._inputs = inputs
self.outputs = []

def show(self, text):
self.outputs.append(text)

def run(self, presenter, prompt):
if len(self._inputs) > 0:
presenter.onInput(self._inputs[0])
self._inputs = self._inputs[1:]

class PresenterTests(TestCase):
def test_liste(self):
v = FakeView(["liste"])
p = Presenter(FakeModel(), v)
self.assertEqual([], v.outputs)
p.run()
self.assertEqual(["Bonjour! Cette application vous donne des informations sur les groupes d'étoiles.", "- X\n- Y\n- Z"], v.outputs)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Il existe des méthodes plus spécialisées que assertEqual, elles seraient utiles au cas où les tests échouent pour avoir des messages d'erreur plus clair


def test_traduire(self):
v = FakeView(["traduire fr"])
p = Presenter(FakeModel(), v)
self.assertEqual([], v.outputs)
p.run()
self.assertEqual(["Bonjour! Cette application vous donne des informations sur les groupes d'étoiles.", "- ('X', 'A')\n- ('Y', 'fr')\n- ('Z', 'C')"], v.outputs)
9 changes: 9 additions & 0 deletions view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class ConsoleView:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation ?

def show(self, text):
# Affiche `text` sur la console
print(text)

def run(self, presenter, prompt):
while True:
command = input(prompt)
presenter.onInput(command)