import re #regular expression (permet de décrire des chaines de caracteres)
[docs]class LifeError(ValueError):
"""class de base des erreurs life"""
pass
[docs]def importer_life(fichier):
"""Import des fichiers ".lif".
La première ligne du fichier life donne la version.
Trie et transfère les versions connues à une fonction spécifique.
En cas de version inconnue affichage d'un message d'erreur.
:param fichier: Chemin du fichier à importer.
:type fichier: str
"""
flux = open(fichier)
ligne = flux.readline()[:-1] # on enleve le \n
version = ligne.split(" ")[1] # lecture de la 2eme partie du split
dico_life = {"1.05":importer_life_105,
"1.06":importer_life_106}
if version in dico_life:
return dico_life[version](fichier)
else:
raise LifeError("Version {} inconnue!".format(version))
[docs]def importer_fichier(fichier):
"""Import de tout les fichiers reconnus.
Lecture du format de fichier.
Transfère dans une fonction spécifique.
En cas de format inconnu affichage d'un message d'erreur.
:param fichier: Chemin du fichier à importer.
:type fichier: str
"""
dico_ext = {"rle":importer_RLE,
"lif":importer_life}
extention = fichier.split(".")[-1] # lecture de la 2eme partie du split
if extention in dico_ext:
return dico_ext[extention](fichier)
else:
raise LifeError("Extention {} inconnue!".format(extention))
[docs]def importer_RLE(fichier):
"""Import des fichiers RLE.
Le fichier est comprimé en RLE
sur le format life de versions .05 et/ou .06.
Utilisation de l'expression regulière pour trouver
et sortir les caractères voulus.
Transformation des données de caractères
en données de position des cellules.
:param fichier: Chemin du fichier à importer.
:type fichier: str
"""
# r pour raw (eviter les "\" en definissant une chaine de caractères brute)
pattern = re.compile(r"(\d*)([.*ob$])") # "\d" = un nombre
flux = open(fichier)
# data est une liste de liste contenant (un nombre, un caractère)
data = pattern.findall(flux.read())
coord_vivantes = set()
x = 0
y = 0
for (n,char) in data:
if not n:
n = 1
else:
n = int(n)
if char in (".", "b"):
x = x + n
elif char == "$":
y = y + n
x = 0
elif char in ("*", "o"):
# distinction des coordonnées et ajout
for x_v in range(x, x + n):
coord_vivantes.add((x_v, y))
x = x+n
return coord_vivantes
[docs]def importer_life_105(fichier):
"""Import des fichiers ".lif" version 1.05.
Le life 1.05 est une représentation de la grille des cellules
en caractère.
Recherche des caractères correspondant à une cellule vivante
et récuperation des coordonnées des cellules vivantes.
:param fichier: Chemin du fichier à importer.
:type fichier: str
"""
coord_vivantes = set()
flux = open(fichier)
#[1:] = ne pas prendre la 1ère ligne (format)
lignes = list(flux.readlines())[1:]
for x in range(len(lignes)):
for y in range(len(lignes[x])): # ligne [x] = colonne
if lignes[x][y] == "*":
coord_vivantes.add((x,y))
return coord_vivantes
[docs]def importer_life_106(fichier):
"""Import des fichiers ".lif" version 1.06.
Le life 1.06 stoque uniquement les coordonnées de cellules vivantes.
Transformation des caractères de coordonnées en coordonnées.
:param fichier: Chemin du fichier à importer.
:type fichier: str
"""
coord_vivantes = set()
flux = open(fichier)
lignes = list(flux.redlines())[1:]
for ligne in lignes:
# ligne.strip enleve les espace, tab et \n
# au debut et a la fin de la ligne
# int etc = transforme les 2 chaines de caractères en nombre
# tuple = liste non modifiable (gain d'espace et de temps)
coord_vivantes.add(tuple([int(i) for i in ligne.strip().split(" ")]))
return coord_vivantes
[docs]def exporter_life_106(fichier, etat):
"""Export des fichiers ".lif" en version 1.06.
L'export ce fera en life 1.06 car c'est le plus facile a exporter
puisque que pour coder les coordonnées des cellules
on utilise les coordonnées de cellules vivantes.
Transformation des données utilisées dans le code en caracters
écrit en format life 1.06.
:param fichier: Chemin du fichier à importer.
:type fichier: str
"""
flux = open(fichier,"w")
for (x,y) in etat:
flux.write(" ".join([str(i) for i in (x,y)])+"\n")
[docs]def importer_MCell(fichier):
"""Import Mcell en stand by."""
pass