Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
script:python:new:api [2013/08/25 16:22] alfred [Árbol de directorios] |
script:python:new:api [2020/05/09 09:25] (actual) |
||
|---|---|---|---|
| Línea 75: | Línea 75: | ||
| <code python> | <code python> | ||
| str = 'Name: {user.name}, Age: {user.age}, Sex: {user.sex}'.format(user=user) | str = 'Name: {user.name}, Age: {user.age}, Sex: {user.sex}'.format(user=user) | ||
| + | </code> | ||
| + | Podemos hacer uso de ''!s'' y ''!r'' que llaman al str() y al repr() del objeto. Combinándolo queda: | ||
| + | <code python> | ||
| + | subscriber.connect("tcp://127.0.0.1:{port!s}".format(port=ZPORT)) | ||
| + | subscriber.connect("tcp://127.0.0.1:{0!s}".format(ZPORT)) | ||
| </code> | </code> | ||
| Línea 96: | Línea 100: | ||
| </code> | </code> | ||
| * Existen funciones para el [[script:python:new:api#expresiones_regulares|tratamiento de expresiones regulares]]. | * Existen funciones para el [[script:python:new:api#expresiones_regulares|tratamiento de expresiones regulares]]. | ||
| - | |||
| Línea 162: | Línea 165: | ||
| import os | import os | ||
| os.path.abspath(rel_path) # Devuelve el path absoluto al que apunta rel_path | os.path.abspath(rel_path) # Devuelve el path absoluto al que apunta rel_path | ||
| + | os.path.basename(obs_path) # Devuelve el nombre del fichero | ||
| os.mkdir(path) # Crea un directorio | os.mkdir(path) # Crea un directorio | ||
| os.sep # Devuelve el separador de directorios del sistema | os.sep # Devuelve el separador de directorios del sistema | ||
| Línea 197: | Línea 201: | ||
| from argparse import ArgumentParser | from argparse import ArgumentParser | ||
| parser = ArgumentParser() | parser = ArgumentParser() | ||
| - | parser.add_argument('-f', '--foo', help='foo help') | + | parser.add_argument('-f', '--foo', dest='foo', help='foo help') |
| args = parser.parse_args() | args = parser.parse_args() | ||
| print args.foo | print args.foo | ||
| </code> | </code> | ||
| - | |||
| ''add_argument'' permite, entre otros, los siguientes parámetros: | ''add_argument'' permite, entre otros, los siguientes parámetros: | ||
| * ''name'' o ''flags'': un nombre o lista de opciones, ejemplos: ''<nowiki>foo, -f, --foo</nowiki>'' | * ''name'' o ''flags'': un nombre o lista de opciones, ejemplos: ''<nowiki>foo, -f, --foo</nowiki>'' | ||
| Línea 487: | Línea 490: | ||
| c1.close() # cerramos la primera conexión | c1.close() # cerramos la primera conexión | ||
| </code> | </code> | ||
| + | Al hacer el connect podemos conectar con una DB ficticia en memoria usando ''":memory:"''. | ||
| === Insertar una fecha === | === Insertar una fecha === | ||
| <code python> | <code python> | ||
| Línea 503: | Línea 506: | ||
| db.commit() | db.commit() | ||
| </code> | </code> | ||
| - | |||
| ==== Datos binarios ==== | ==== Datos binarios ==== | ||
| Línea 575: | Línea 577: | ||
| ==== Logging ==== | ==== Logging ==== | ||
| + | * [[http://docs.python.org/2/library/logging.html]] | ||
| Niveles de log: ''DEBUG'', ''INFO'', ''WARNING'', ''ERROR'', ''CRITICAL'' \\ | Niveles de log: ''DEBUG'', ''INFO'', ''WARNING'', ''ERROR'', ''CRITICAL'' \\ | ||
| El nivel por defecto es ''WARNING''. \\ | El nivel por defecto es ''WARNING''. \\ | ||
| Línea 663: | Línea 666: | ||
| datefmt= | datefmt= | ||
| </code> | </code> | ||
| + | |||
| + | === Para mostrar información de la excepción === | ||
| + | <code python> | ||
| + | try: | ||
| + | open('/path/to/does/not/exist', 'rb') | ||
| + | except (SystemExit, KeyboardInterrupt): | ||
| + | raise | ||
| + | except Exception, e: | ||
| + | logger.error('Failed to open file', exc_info=True) | ||
| + | </code> | ||
| + | |||
| + | === Notas === | ||
| + | Desactivar el log: | ||
| + | <code python> | ||
| + | logging.getLogger().disabled = True | ||
| + | </code> | ||
| + | |||
| + | |||
| ==== Imports dinámicos ==== | ==== Imports dinámicos ==== | ||
| A partir del módulo ''imp'' podemos realizar imports por código. Este módulo tiene funciones como... | A partir del módulo ''imp'' podemos realizar imports por código. Este módulo tiene funciones como... | ||
| * ''load_module'' para cargar el módulo. | * ''load_module'' para cargar el módulo. | ||
| - | ===== Otros ===== | ||
| + | También podemos hacerlo: | ||
| + | <code python> | ||
| + | mod = __import__(name_module) | ||
| + | cls = getattr(mod, name_class) | ||
| + | </code> | ||
| + | |||
| + | O importar una ruta: | ||
| + | <code python> | ||
| + | def import_path (mpath): | ||
| + | from imp import load_source | ||
| + | from os import path | ||
| + | fname = path.basename(obs_path)[:-3] | ||
| + | return load_source(fname, mpath) | ||
| + | </code> | ||
| + | |||
| + | === Otra forma de importar === | ||
| + | Si la aplicación se abre desde, por ejemplo, otro path. | ||
| + | <code python> | ||
| + | import sys | ||
| + | from os.path import abspath | ||
| + | sys.path.append(abspath('.')) | ||
| + | from backend.css.tasks import parse_grammar | ||
| + | </code> | ||
| + | ==== UnitTesting ==== | ||
| + | * Deberemos hacer un import de ''unittest''. | ||
| + | * Las clases que implementen los tests heredarán ''unittest.TestCase''. | ||
| + | * Los tests serán los métodos de dicha clase, por convención su nombre empezará por ''test_''. | ||
| + | * Los ficheros de test también deberán tener un nombre que empiece por ''test_''. | ||
| + | * El método ''setUp(self)'' se ejecuta antes de cada test. | ||
| + | * El método ''tearDown(self)'' se ejecuta después de cada test. | ||
| + | * El siguiente comando realizará los tests dentro de ese directorio: | ||
| + | <code> | ||
| + | $ python -m unittest discover | ||
| + | </code> | ||
| + | * Otras formas de ejecutar tests: | ||
| + | <code> | ||
| + | $ python -m unittest test_random | ||
| + | $ python -m unittest test_random.TestSequenceFunctions | ||
| + | $ python -m unittest test_random.TestSequenceFunctions.test_shuffle | ||
| + | </code> | ||
| + | * Las comprobaciones que se pueden hacer son: | ||
| + | * ''assertEqual(expected, actual)'' | ||
| + | * ''assertNotEqual(notExpected, actual)'' | ||
| + | * ''assertTrue(expression)'' y ''assertFalse(expression)'' | ||
| + | * ''assertIsInstance(object, class)'' | ||
| + | |||
| + | <code python> | ||
| + | ''' | ||
| + | RULES OF TENNIS | ||
| + | * Each player can have either of these points in one game, described as 0-15-30-40. Each time a player scores, it advances of one position in the scale. | ||
| + | * A player at 40 who scores wins the set. Unless... | ||
| + | * If both players are at 40, we are in a *deuce*. If the game is in deuce, the next scoring player will gain an *advantage*. Then if the player in advantage scores he wins, while if the player not in advantage scores they are back at deuce. | ||
| + | ''' | ||
| + | from tennis import Set, Scores | ||
| + | from unittest import TestCase | ||
| + | |||
| + | class TestSetWinning(TestCase): | ||
| + | def test_score_grows(self): | ||
| + | set = Set() | ||
| + | self.assertEqual("0", set.firstScore()) | ||
| + | set.firstScores() | ||
| + | self.assertEqual("15", set.firstScore()) | ||
| + | self.assertEqual("0", set.secondScore()) | ||
| + | set.secondScores() | ||
| + | self.assertEqual("15", set.secondScore()) | ||
| + | def test_player_1_win_when_scores_at_40(self): | ||
| + | set = Set() | ||
| + | set.firstScores(3) | ||
| + | self.assertEqual(None, set.winner()) | ||
| + | set.firstScores() | ||
| + | self.assertEqual(1, set.winner()) | ||
| + | def test_player_2_win_when_scores_at_40(self): | ||
| + | set = Set() | ||
| + | set.secondScores(3) | ||
| + | self.assertEqual(None, set.winner()) | ||
| + | set.secondScores() | ||
| + | self.assertEqual(2, set.winner()) | ||
| + | def test_deuce_requires_1_more_than_one_ball_to_win(self): | ||
| + | set = Set() | ||
| + | set.firstScores(3) | ||
| + | set.secondScores(3) | ||
| + | set.firstScores() | ||
| + | self.assertEqual(None, set.winner()) | ||
| + | set.firstScores() | ||
| + | self.assertEqual(1, set.winner()) | ||
| + | def test_deuce_requires_2_more_than_one_ball_to_win(self): | ||
| + | set = Set() | ||
| + | set.firstScores(3) | ||
| + | set.secondScores(3) | ||
| + | set.secondScores() | ||
| + | self.assertEqual(None, set.winner()) | ||
| + | set.secondScores() | ||
| + | self.assertEqual(2, set.winner()) | ||
| + | def test_player_can_return_to_deuce_by_scoring_against_the_others_advantage(self): | ||
| + | set = Set() | ||
| + | set.firstScores(3) | ||
| + | set.secondScores(3) | ||
| + | self.assertEqual(None, set.winner()) | ||
| + | set.firstScores() | ||
| + | set.secondScores() | ||
| + | set.firstScores() | ||
| + | set.secondScores() | ||
| + | self.assertEqual(None, set.winner()) | ||
| + | self.assertEqual("40", set.firstScore()) | ||
| + | self.assertEqual("40", set.secondScore()) | ||
| + | |||
| + | class TestScoreNames(TestCase): | ||
| + | def test_score_names(self): | ||
| + | scores = Scores() | ||
| + | self.assertEqual("0", scores.scoreName(0)) | ||
| + | self.assertEqual("15", scores.scoreName(1)) | ||
| + | self.assertEqual("30", scores.scoreName(2)) | ||
| + | self.assertEqual("40", scores.scoreName(3)) | ||
| + | self.assertEqual("A", scores.scoreName(4)) | ||
| + | </code> | ||
| + | |||
| + | === Notas === | ||
| + | * [[https://wiki.python.org/moin/PythonTestingToolsTaxonomy|Librerías de TDD]] | ||
| + | ===== Otros ===== | ||