cgq-qgc/HydroSensorReader

Error when reading a Solinst levelogger file due to wrong decimal and data separators.

jnsebgosselin opened this issue · 18 comments

Trying to read a Solinst levelogger file and got this error:

Traceback (most recent call last):

  File "<ipython-input-16-f20f23fa1ab2>", line 77, in <module>
    solinst_file = hsr.SolinstFileReader(osp.join(dirname, file))

  File "C:\Users\User\HydroSensorReader\hydsensread\file_reader\compagny_file_reader\solinst_file_reader.py", line 28, in __init__
    self.__set_reader(wait_read)

  File "C:\Users\User\HydroSensorReader\hydsensread\file_reader\compagny_file_reader\solinst_file_reader.py", line 39, in __set_reader
    self._file, wait_read=wait_read)

  File "C:\Users\User\HydroSensorReader\hydsensread\file_reader\compagny_file_reader\solinst_file_reader.py", line 342, in __init__
    super().__init__(file_path, header_length, wait_read=wait_read)

  File "C:\Users\User\HydroSensorReader\hydsensread\file_reader\abstract_file_reader.py", line 193, in __init__
    self.read_file()

  File "C:\Users\User\HydroSensorReader\hydsensread\file_reader\abstract_file_reader.py", line 123, in read_file
    self._make_site()

  File "C:\Users\User\HydroSensorReader\hydsensread\file_reader\abstract_file_reader.py", line 149, in _make_site
    self._read_file_data_header()

  File "C:\Users\User\HydroSensorReader\hydsensread\file_reader\compagny_file_reader\solinst_file_reader.py", line 372, in _read_file_data_header
    self._date_list = self._get_date_list()

  File "C:\Users\User\HydroSensorReader\hydsensread\file_reader\compagny_file_reader\solinst_file_reader.py", line 411, in _get_date_list
    istart = data_header.index('Date')

ValueError: 'Date' is not in list

The reason is that this file use the , as decimal separator and the ; as data separator... this file was probably generated on a machine with Windows in French.

image

Pourquoi ne pas utiliser une REGEX pour spliter ça?? Ou un compte de ";" et ","....je sais pas...! Ou utiliser le 1er symbole dans [';' , ','] a partir du début...

Pourquoi ne pas utiliser une REGEX pour spliter ça?? Ou un compte de ";" et ","....je sais pas...! Ou utiliser le 1er symbole dans [';' , ','] a partir du début...

J'ai essayer d'utiliser un Sniffer dans le parser directement et ça marche... parfois... lol Ce n'est pas très robuste... surtout pour de petits fichiers.

Donc je pense que c'est la meilleure façon d'y aller avec un regex que l'on défini dans le reader et que l'on passe au parser.

Pour ce qui est d'utiliser Pandas, ça ne règlerait pas notre problème dans ce cas-ci je pense malheureusement. Ça ferait comme pour le Sniffer. Ça marcherait de temps en temps.

Oh oui...je me souviens d'avoir tellement sacré avec le sniffer... Pour pandas, t'as raison j'ai regardé la doc après et c'est pour ça que j'ai supprimé le message. Je me suis bien rendu compte que c'était me même trouble. Lol.

Mais je pense que le regex, on risque AUSSI de mal diviser les colonne. Le meilleur je pense que c'est de parcourir la première ligne et de voir, quel est le symbole qui sert de séparateur entre la date et la 2em colonne. Puis, l'utiliser.

Mais je pense que le regex, on risque AUSSI de mal diviser les colonne. Le meilleur je pense que c'est de parcourir la première ligne et de voir, quel est le symbole qui sert de séparateur entre la date et la 2em colonne. Puis, l'utiliser.

Oui, c'est ça que je voulais dire, un regex pour trouver le séparateur 👍

with open(osp.join(dirname, filename), 'r') as csvfile:
    data = csvfile.read()
    sep = re.search("\d\d\d\d.\d\d.\d\d([;,\t])\d\d.\d\d.\d\d", data).group(1)
    file_reader = csv.reader(csvfile, delimiter=sep , lineterminator='\n')

Ah ah ah! Et si la date est dans un autre format? MM JJ AAAA ou MMMM JJ AAAA ou......

PS: Je pensais que l'informatique c'était bien, jusqu'à ce que je doive parser une date.... Lol

Ah ah ah! Et si la date est dans un autre format? MM JJ AAAA ou MMMM JJ AAAA ou......

Bien on est faitte. C'est pour cela qu'en définissant le regex dans le reader, on a moins de chance que ça arrive...

Sinon, on pourrait toujours y aller avec :

sep = re.search("date([;,\t])time", data, flags=re.IGNORECASE).group(1)

Mais encore là, tu pourrais me dire que ça ne marchera pas si le nom ou l'ordre des colonnes changes :P

Mais je pense que je vais y aller avec ce regex "date([;,\t])time", c'est plus digeste et je ne sais pas, j'ai un bon feeling hehe

Ok. Essayons ça! Mais je mettrais quelque chose comme :

(\d{2,4}[ /-]{0,1}){3}([;,\t])\d\d.\d\d.\d\d

Ah ah ah ah ah! C'est clair! J'avais même pas remarqué que la ligne du dessus était plus facile! Maudit effet tunnel! Lol

Parfait, je vais proposer un PR et on itérera à partir de là.

Parfait! Bien vu quand même!

Aussi je me demandais tant qu'à y être, dans la CSVFileParser.read_file, est-ce que ce serait possible de remplacer :

for row in file_reader:
    self._file_content.append(row)

par

self._file_content = list(file_reader)

C'est que le append est problématique si jamais on veut recaller read_file pour x raison à partir du reader.

Ah ok, pour ne pas avoir une liste avec 2 fois les données? Ben oui je pense que c'est correct. Je ne voit pas quel problème ça pourrait causer sur le reste du package

Ah ok, pour ne pas avoir une liste avec 2 fois les données? Ben oui je pense que c'est correct. Je ne voit pas quel problème ça pourrait causer sur le reste du package

Oui exact. Parfait, je vais faire cette petite modification en plus alors, merci.

Le pire c'est que je pense que j'étais déjà passé sur ce problème....de double read et j'ai juste modifié les appels à read_file....J'étais niaiseux à ce moment la...Aussi, je ne pensais pas que le package allait être utilisé ailleurs!!! ^^

Aussi, je ne pensais pas que le package allait être utilisé ailleurs!!! ^^

Ahah, je compte l'utiliser pas mal. Je trouve que l'idée est vraiment bonne.

Ahah, je compte l'utiliser pas mal. Je trouve que l'idée est vraiment bonne.

Promis, quand je reviens en janvier, je vais travailler plus (+) dessus...!