From a704c1a1a6d735aee2d404afeaa9d4e6c1eb1e8c Mon Sep 17 00:00:00 2001 From: Denis Arrivault <denis.arrivault@lif.univ-mrs.fr> Date: Wed, 7 Feb 2018 17:57:13 +0100 Subject: [PATCH] Adding io functions for Automata --- COPYING | 2 +- copyrightstamp.txt | 10 +- examples/3.pautomac_light.train.json | 1 + examples/3.pautomac_light.train.yaml | 67 ++++++ examples/automaton_io.py | 11 + examples/json_save.ipynb | 300 +++++++++++++++++++++++++-- examples/json_save.py | 13 -- examples/simple_automata.json | 1 + examples/simple_automata.json.gv | 15 ++ examples/simple_automata.json.gv.pdf | Bin 0 -> 11284 bytes examples/simple_automata.yaml | 23 ++ examples/simple_automata.yaml.gv | 15 ++ examples/simple_automata.yaml.gv.pdf | Bin 0 -> 11284 bytes examples/test.json | 1 - splearn/__init__.py | 2 +- splearn/automaton.py | 69 ++++-- splearn/serializer.py | 171 ++++++++++++--- test.json | 1 - 18 files changed, 610 insertions(+), 92 deletions(-) create mode 100644 examples/3.pautomac_light.train.json create mode 100644 examples/3.pautomac_light.train.yaml create mode 100644 examples/automaton_io.py delete mode 100644 examples/json_save.py create mode 100644 examples/simple_automata.json create mode 100644 examples/simple_automata.json.gv create mode 100644 examples/simple_automata.json.gv.pdf create mode 100644 examples/simple_automata.yaml create mode 100644 examples/simple_automata.yaml.gv create mode 100644 examples/simple_automata.yaml.gv.pdf delete mode 100644 examples/test.json delete mode 100644 test.json diff --git a/COPYING b/COPYING index 001fbed..947f926 100644 --- a/COPYING +++ b/COPYING @@ -1,6 +1,6 @@ New BSD License -Copyright (c) DATE, The SCIKIT-SPLEARN developers. +Copyright (c) 2016-DATE, The SCIKIT-SPLEARN developers. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/copyrightstamp.txt b/copyrightstamp.txt index 05ecaee..a87735f 100644 --- a/copyrightstamp.txt +++ b/copyrightstamp.txt @@ -1,17 +1,17 @@ ######### COPYRIGHT ######### -Copyright(c) DATE +Copyright(c) 2016-DATE ----------------- * LabEx Archimède: http://labex-archimede.univ-amu.fr/ -* Laboratoire d'Informatique Fondamentale : http://www.lif.univ-mrs.fr/ +* Laboratoire d'Informatique et Systèmes : http://www.lis-lab.fr/ Contributors: ------------ -* François Denis <francois.denis_AT_lif.univ-mrs.fr> -* Rémi Eyraud <remy.eyraud_AT_lif.univ-mrs.fr> -* Denis Arrivault <contact.dev_AT_lif.univ-mrs.fr> +* François Denis <francois.denis_AT_lis-lab.fr> +* Rémi Eyraud <remi.eyraud_AT_lis-lab.fr> +* Denis Arrivault <contact.dev_AT_lis-lab.fr> * Dominique Benielli <dominique.benielli_AT_univ-amu.fr> Description: diff --git a/examples/3.pautomac_light.train.json b/examples/3.pautomac_light.train.json new file mode 100644 index 0000000..e77f615 --- /dev/null +++ b/examples/3.pautomac_light.train.json @@ -0,0 +1 @@ +{"automaton": {"transitions": [{"numpy.ndarray": {"values": [[0.045121209595118526, -0.24038969827843812, 0.34944999592135073, -0.2811680730534614, -0.2140252337749723], [0.0692580056243754, -0.30062293462828926, 0.20641375368520323, -0.14960814319757162, -0.5580573163749147], [0.029801151921765866, -0.13866480809160275, 0.18362212572805375, -0.20969545230657946, -0.14481622025561033], [0.005699344003197941, -0.023385825120200612, -0.0660066537398175, 0.10749935271465784, -0.1510365460415996], [-0.020086551931478853, 0.09026347555230403, -0.005525585655539282, -0.03135531709030631, 0.24329022420477361]], "dtype": "float64"}}, {"numpy.ndarray": {"values": [[0.07744772079170577, 0.09007073705761888, -0.3047220063293004, 0.2767624549859125, 0.2028939603062788], [-0.0990298048367086, -0.08061846818727912, 0.2585317069225045, -0.12086330214608965, -0.11085207725068019], [-0.061710792028537555, -0.06244151779954693, 0.12007654564862041, 0.0025063746277926833, -0.15679674731455712], [-0.002736973749965318, -0.009005721984277385, -0.0004600329590919212, -0.008550426472005884, -0.05375464678968064], [0.030987327588710818, 0.03972680066723204, -0.049971133509102365, 0.0035769411874977224, 0.14182576205856343]], "dtype": "float64"}}, {"numpy.ndarray": {"values": [[-0.06791915236220329, -0.1135793765908807, 0.3795539260405443, -0.21784979894047046, -0.22977695089937855], [0.11596642335411368, 0.14914956804629215, -0.1335750837668692, -0.008916063072030857, 0.3484153673774847], [0.011730817547426591, 0.01927380053195553, 0.04142658345867102, -0.03534658856098166, 0.02316491010895659], [0.0073289110755416255, 0.005536509132796289, -0.02245608295066666, 0.03611543477693135, -0.03851433900140641], [-0.010589894686551481, -0.010626616553723545, -0.0005431056456618302, -0.02556747670016023, 0.04984888818929077]], "dtype": "float64"}}, {"numpy.ndarray": {"values": [[0.0727621142778044, -0.01571955768557908, 0.07428592814589835, -0.10369861539250237, 0.024753473688334762], [-0.05607105449779192, -0.08896207276035564, 0.2763822539752204, -0.23711255828386232, 0.07372294122304948], [-0.007391294007753285, -0.04874179796387578, -0.6291239733858517, 0.4681627652157708, 0.09251699239093028], [-0.007110224931878148, -0.056233177358980875, -0.3660665856762066, -0.013297798115226096, 0.649103317749269], [0.0023355150085570832, -0.021561151264484168, 0.09096243479437624, -0.3843882349306193, 0.6616477207948629]], "dtype": "float64"}}], "type": "classic", "nbL": 4, "nbS": 5, "initial": {"numpy.ndarray": {"values": [-0.0004934419970497477, 0.003063469710791532, -0.0440739320155803, -0.10777702616547354, -0.0866391379316936], "dtype": "float64"}}, "final": {"numpy.ndarray": {"values": [0.07757136847945034, -0.02422029400314446, -0.4468125366321277, 0.6277320840897538, -0.554674433356226], "dtype": "float64"}}}} \ No newline at end of file diff --git a/examples/3.pautomac_light.train.yaml b/examples/3.pautomac_light.train.yaml new file mode 100644 index 0000000..125acbb --- /dev/null +++ b/examples/3.pautomac_light.train.yaml @@ -0,0 +1,67 @@ +automaton: + final: + numpy.ndarray: + dtype: float64 + values: [0.07757136847945034, -0.02422029400314446, -0.4468125366321277, 0.6277320840897538, + -0.554674433356226] + initial: + numpy.ndarray: + dtype: float64 + values: [-0.0004934419970497477, 0.003063469710791532, -0.0440739320155803, + -0.10777702616547354, -0.0866391379316936] + nbL: 4 + nbS: 5 + transitions: + - numpy.ndarray: + dtype: float64 + values: + - [0.045121209595118526, -0.24038969827843812, 0.34944999592135073, -0.2811680730534614, + -0.2140252337749723] + - [0.0692580056243754, -0.30062293462828926, 0.20641375368520323, -0.14960814319757162, + -0.5580573163749147] + - [0.029801151921765866, -0.13866480809160275, 0.18362212572805375, -0.20969545230657946, + -0.14481622025561033] + - [0.005699344003197941, -0.023385825120200612, -0.0660066537398175, 0.10749935271465784, + -0.1510365460415996] + - [-0.020086551931478853, 0.09026347555230403, -0.005525585655539282, -0.03135531709030631, + 0.24329022420477361] + - numpy.ndarray: + dtype: float64 + values: + - [0.07744772079170577, 0.09007073705761888, -0.3047220063293004, 0.2767624549859125, + 0.2028939603062788] + - [-0.0990298048367086, -0.08061846818727912, 0.2585317069225045, -0.12086330214608965, + -0.11085207725068019] + - [-0.061710792028537555, -0.06244151779954693, 0.12007654564862041, 0.0025063746277926833, + -0.15679674731455712] + - [-0.002736973749965318, -0.009005721984277385, -0.0004600329590919212, -0.008550426472005884, + -0.05375464678968064] + - [0.030987327588710818, 0.03972680066723204, -0.049971133509102365, 0.0035769411874977224, + 0.14182576205856343] + - numpy.ndarray: + dtype: float64 + values: + - [-0.06791915236220329, -0.1135793765908807, 0.3795539260405443, -0.21784979894047046, + -0.22977695089937855] + - [0.11596642335411368, 0.14914956804629215, -0.1335750837668692, -0.008916063072030857, + 0.3484153673774847] + - [0.011730817547426591, 0.01927380053195553, 0.04142658345867102, -0.03534658856098166, + 0.02316491010895659] + - [0.0073289110755416255, 0.005536509132796289, -0.02245608295066666, 0.03611543477693135, + -0.03851433900140641] + - [-0.010589894686551481, -0.010626616553723545, -0.0005431056456618302, -0.02556747670016023, + 0.04984888818929077] + - numpy.ndarray: + dtype: float64 + values: + - [0.0727621142778044, -0.01571955768557908, 0.07428592814589835, -0.10369861539250237, + 0.024753473688334762] + - [-0.05607105449779192, -0.08896207276035564, 0.2763822539752204, -0.23711255828386232, + 0.07372294122304948] + - [-0.007391294007753285, -0.04874179796387578, -0.6291239733858517, 0.4681627652157708, + 0.09251699239093028] + - [-0.007110224931878148, -0.056233177358980875, -0.3660665856762066, -0.013297798115226096, + 0.649103317749269] + - [0.0023355150085570832, -0.021561151264484168, 0.09096243479437624, -0.3843882349306193, + 0.6616477207948629] + type: classic diff --git a/examples/automaton_io.py b/examples/automaton_io.py new file mode 100644 index 0000000..59559e3 --- /dev/null +++ b/examples/automaton_io.py @@ -0,0 +1,11 @@ +from splearn.automaton import Automaton +from graphviz import Source + +input_file = 'simple_automata' +format = ['json', 'yaml'] +for f in format: + A = Automaton.read(input_file + "." + f, format=f) + dot = A.get_dot(title = "Simple Automata") + src = Source(dot) + src.render(input_file + '.' + f + '.gv', view=True) + diff --git a/examples/json_save.ipynb b/examples/json_save.ipynb index 5acc828..1af50f6 100644 --- a/examples/json_save.ipynb +++ b/examples/json_save.ipynb @@ -30,7 +30,7 @@ "source": [ "from splearn.datasets.base import load_data_sample\n", "from splearn.tests.datasets.get_dataset_path import get_dataset_path\n", - "from splearn import Spectral\n", + "from splearn import Spectral, Automaton, Serializer\n", "train_file = '3.pautomac_light.train'\n", "data = load_data_sample(adr=get_dataset_path(train_file))\n", "sp = Spectral()\n", @@ -39,26 +39,296 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "Automaton.write(sp.automaton, train_file + \".json\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "str1 = Serializer.data_to_json(sp.automaton)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "A = Serializer.json_to_data(str1) " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "str2 = Serializer.data_to_json(A)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "str1 == str2" + ] + }, + { + "cell_type": "code", + "execution_count": 8, "metadata": {}, "outputs": [ { - "ename": "AttributeError", - "evalue": "'dict' object has no attribute 'iteritems'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m<ipython-input-2-2625a21006a9>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0msp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mautomaton\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite_json\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"test.json\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m~/Codes/scikit-splearn/splearn/automaton.py\u001b[0m in \u001b[0;36mwrite_json\u001b[0;34m(self, jsonFileName)\u001b[0m\n\u001b[1;32m 695\u001b[0m \"transitions\":self.transitions, \"type\":self.type}\n\u001b[1;32m 696\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mjsonFileName\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'w'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0moutfile\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 697\u001b[0;31m \u001b[0mjson\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdump\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mSerializer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata_to_json\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moutfile\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 698\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 699\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mread_json\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mjsonFileName\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/Codes/scikit-splearn/splearn/serializer.py\u001b[0m in \u001b[0;36mdata_to_json\u001b[0;34m(self, data)\u001b[0m\n\u001b[1;32m 45\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 46\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mdata_to_json\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 47\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mjson\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdumps\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__serialize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 48\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 49\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mjson_to_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/Codes/scikit-splearn/splearn/serializer.py\u001b[0m in \u001b[0;36m__serialize\u001b[0;34m(self, data)\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdict\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 21\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 22\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__serialize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mk\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0miteritems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 23\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m\"py/dict\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__serialize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__serialize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mk\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0miteritems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mAttributeError\u001b[0m: 'dict' object has no attribute 'iteritems'" + "data": { + "text/plain": [ + "'{\"automaton\": {\"transitions\": [{\"numpy.ndarray\": {\"values\": [[0.045121209595118526, -0.24038969827843812, 0.34944999592135073, -0.2811680730534614, -0.2140252337749723], [0.0692580056243754, -0.30062293462828926, 0.20641375368520323, -0.14960814319757162, -0.5580573163749147], [0.029801151921765866, -0.13866480809160275, 0.18362212572805375, -0.20969545230657946, -0.14481622025561033], [0.005699344003197941, -0.023385825120200612, -0.0660066537398175, 0.10749935271465784, -0.1510365460415996], [-0.020086551931478853, 0.09026347555230403, -0.005525585655539282, -0.03135531709030631, 0.24329022420477361]], \"dtype\": \"float64\"}}, {\"numpy.ndarray\": {\"values\": [[0.07744772079170577, 0.09007073705761888, -0.3047220063293004, 0.2767624549859125, 0.2028939603062788], [-0.0990298048367086, -0.08061846818727912, 0.2585317069225045, -0.12086330214608965, -0.11085207725068019], [-0.061710792028537555, -0.06244151779954693, 0.12007654564862041, 0.0025063746277926833, -0.15679674731455712], [-0.002736973749965318, -0.009005721984277385, -0.0004600329590919212, -0.008550426472005884, -0.05375464678968064], [0.030987327588710818, 0.03972680066723204, -0.049971133509102365, 0.0035769411874977224, 0.14182576205856343]], \"dtype\": \"float64\"}}, {\"numpy.ndarray\": {\"values\": [[-0.06791915236220329, -0.1135793765908807, 0.3795539260405443, -0.21784979894047046, -0.22977695089937855], [0.11596642335411368, 0.14914956804629215, -0.1335750837668692, -0.008916063072030857, 0.3484153673774847], [0.011730817547426591, 0.01927380053195553, 0.04142658345867102, -0.03534658856098166, 0.02316491010895659], [0.0073289110755416255, 0.005536509132796289, -0.02245608295066666, 0.03611543477693135, -0.03851433900140641], [-0.010589894686551481, -0.010626616553723545, -0.0005431056456618302, -0.02556747670016023, 0.04984888818929077]], \"dtype\": \"float64\"}}, {\"numpy.ndarray\": {\"values\": [[0.0727621142778044, -0.01571955768557908, 0.07428592814589835, -0.10369861539250237, 0.024753473688334762], [-0.05607105449779192, -0.08896207276035564, 0.2763822539752204, -0.23711255828386232, 0.07372294122304948], [-0.007391294007753285, -0.04874179796387578, -0.6291239733858517, 0.4681627652157708, 0.09251699239093028], [-0.007110224931878148, -0.056233177358980875, -0.3660665856762066, -0.013297798115226096, 0.649103317749269], [0.0023355150085570832, -0.021561151264484168, 0.09096243479437624, -0.3843882349306193, 0.6616477207948629]], \"dtype\": \"float64\"}}], \"type\": \"classic\", \"nbL\": 4, \"nbS\": 5, \"initial\": {\"numpy.ndarray\": {\"values\": [-0.0004934419970497477, 0.003063469710791532, -0.0440739320155803, -0.10777702616547354, -0.0866391379316936], \"dtype\": \"float64\"}}, \"final\": {\"numpy.ndarray\": {\"values\": [0.07757136847945034, -0.02422029400314446, -0.4468125366321277, 0.6277320840897538, -0.554674433356226], \"dtype\": \"float64\"}}}}'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "str1" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'{\"automaton\": {\"transitions\": [{\"numpy.ndarray\": {\"values\": [[0.045121209595118526, -0.24038969827843812, 0.34944999592135073, -0.2811680730534614, -0.2140252337749723], [0.0692580056243754, -0.30062293462828926, 0.20641375368520323, -0.14960814319757162, -0.5580573163749147], [0.029801151921765866, -0.13866480809160275, 0.18362212572805375, -0.20969545230657946, -0.14481622025561033], [0.005699344003197941, -0.023385825120200612, -0.0660066537398175, 0.10749935271465784, -0.1510365460415996], [-0.020086551931478853, 0.09026347555230403, -0.005525585655539282, -0.03135531709030631, 0.24329022420477361]], \"dtype\": \"float64\"}}, {\"numpy.ndarray\": {\"values\": [[0.07744772079170577, 0.09007073705761888, -0.3047220063293004, 0.2767624549859125, 0.2028939603062788], [-0.0990298048367086, -0.08061846818727912, 0.2585317069225045, -0.12086330214608965, -0.11085207725068019], [-0.061710792028537555, -0.06244151779954693, 0.12007654564862041, 0.0025063746277926833, -0.15679674731455712], [-0.002736973749965318, -0.009005721984277385, -0.0004600329590919212, -0.008550426472005884, -0.05375464678968064], [0.030987327588710818, 0.03972680066723204, -0.049971133509102365, 0.0035769411874977224, 0.14182576205856343]], \"dtype\": \"float64\"}}, {\"numpy.ndarray\": {\"values\": [[-0.06791915236220329, -0.1135793765908807, 0.3795539260405443, -0.21784979894047046, -0.22977695089937855], [0.11596642335411368, 0.14914956804629215, -0.1335750837668692, -0.008916063072030857, 0.3484153673774847], [0.011730817547426591, 0.01927380053195553, 0.04142658345867102, -0.03534658856098166, 0.02316491010895659], [0.0073289110755416255, 0.005536509132796289, -0.02245608295066666, 0.03611543477693135, -0.03851433900140641], [-0.010589894686551481, -0.010626616553723545, -0.0005431056456618302, -0.02556747670016023, 0.04984888818929077]], \"dtype\": \"float64\"}}, {\"numpy.ndarray\": {\"values\": [[0.0727621142778044, -0.01571955768557908, 0.07428592814589835, -0.10369861539250237, 0.024753473688334762], [-0.05607105449779192, -0.08896207276035564, 0.2763822539752204, -0.23711255828386232, 0.07372294122304948], [-0.007391294007753285, -0.04874179796387578, -0.6291239733858517, 0.4681627652157708, 0.09251699239093028], [-0.007110224931878148, -0.056233177358980875, -0.3660665856762066, -0.013297798115226096, 0.649103317749269], [0.0023355150085570832, -0.021561151264484168, 0.09096243479437624, -0.3843882349306193, 0.6616477207948629]], \"dtype\": \"float64\"}}], \"type\": \"classic\", \"nbL\": 4, \"nbS\": 5, \"initial\": {\"numpy.ndarray\": {\"values\": [-0.0004934419970497477, 0.003063469710791532, -0.0440739320155803, -0.10777702616547354, -0.0866391379316936], \"dtype\": \"float64\"}}, \"final\": {\"numpy.ndarray\": {\"values\": [0.07757136847945034, -0.02422029400314446, -0.4468125366321277, 0.6277320840897538, -0.554674433356226], \"dtype\": \"float64\"}}}}'" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "str2" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "str3 = Serializer.data_to_yaml(sp.automaton)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "automaton:\n", + " final:\n", + " numpy.ndarray:\n", + " dtype: float64\n", + " values: [0.07757136847945034, -0.02422029400314446, -0.4468125366321277, 0.6277320840897538,\n", + " -0.554674433356226]\n", + " initial:\n", + " numpy.ndarray:\n", + " dtype: float64\n", + " values: [-0.0004934419970497477, 0.003063469710791532, -0.0440739320155803,\n", + " -0.10777702616547354, -0.0866391379316936]\n", + " nbL: 4\n", + " nbS: 5\n", + " transitions:\n", + " - numpy.ndarray:\n", + " dtype: float64\n", + " values:\n", + " - [0.045121209595118526, -0.24038969827843812, 0.34944999592135073, -0.2811680730534614,\n", + " -0.2140252337749723]\n", + " - [0.0692580056243754, -0.30062293462828926, 0.20641375368520323, -0.14960814319757162,\n", + " -0.5580573163749147]\n", + " - [0.029801151921765866, -0.13866480809160275, 0.18362212572805375, -0.20969545230657946,\n", + " -0.14481622025561033]\n", + " - [0.005699344003197941, -0.023385825120200612, -0.0660066537398175, 0.10749935271465784,\n", + " -0.1510365460415996]\n", + " - [-0.020086551931478853, 0.09026347555230403, -0.005525585655539282, -0.03135531709030631,\n", + " 0.24329022420477361]\n", + " - numpy.ndarray:\n", + " dtype: float64\n", + " values:\n", + " - [0.07744772079170577, 0.09007073705761888, -0.3047220063293004, 0.2767624549859125,\n", + " 0.2028939603062788]\n", + " - [-0.0990298048367086, -0.08061846818727912, 0.2585317069225045, -0.12086330214608965,\n", + " -0.11085207725068019]\n", + " - [-0.061710792028537555, -0.06244151779954693, 0.12007654564862041, 0.0025063746277926833,\n", + " -0.15679674731455712]\n", + " - [-0.002736973749965318, -0.009005721984277385, -0.0004600329590919212, -0.008550426472005884,\n", + " -0.05375464678968064]\n", + " - [0.030987327588710818, 0.03972680066723204, -0.049971133509102365, 0.0035769411874977224,\n", + " 0.14182576205856343]\n", + " - numpy.ndarray:\n", + " dtype: float64\n", + " values:\n", + " - [-0.06791915236220329, -0.1135793765908807, 0.3795539260405443, -0.21784979894047046,\n", + " -0.22977695089937855]\n", + " - [0.11596642335411368, 0.14914956804629215, -0.1335750837668692, -0.008916063072030857,\n", + " 0.3484153673774847]\n", + " - [0.011730817547426591, 0.01927380053195553, 0.04142658345867102, -0.03534658856098166,\n", + " 0.02316491010895659]\n", + " - [0.0073289110755416255, 0.005536509132796289, -0.02245608295066666, 0.03611543477693135,\n", + " -0.03851433900140641]\n", + " - [-0.010589894686551481, -0.010626616553723545, -0.0005431056456618302, -0.02556747670016023,\n", + " 0.04984888818929077]\n", + " - numpy.ndarray:\n", + " dtype: float64\n", + " values:\n", + " - [0.0727621142778044, -0.01571955768557908, 0.07428592814589835, -0.10369861539250237,\n", + " 0.024753473688334762]\n", + " - [-0.05607105449779192, -0.08896207276035564, 0.2763822539752204, -0.23711255828386232,\n", + " 0.07372294122304948]\n", + " - [-0.007391294007753285, -0.04874179796387578, -0.6291239733858517, 0.4681627652157708,\n", + " 0.09251699239093028]\n", + " - [-0.007110224931878148, -0.056233177358980875, -0.3660665856762066, -0.013297798115226096,\n", + " 0.649103317749269]\n", + " - [0.0023355150085570832, -0.021561151264484168, 0.09096243479437624, -0.3843882349306193,\n", + " 0.6616477207948629]\n", + " type: classic\n", + "\n" ] } ], "source": [ - "sp.automaton.write_json(\"test.json\")" + "print(str3)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "Ajs = Automaton.read(train_file + \".json\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[array([[ 0.04512121, -0.2403897 , 0.34945 , -0.28116807, -0.21402523],\n", + " [ 0.06925801, -0.30062293, 0.20641375, -0.14960814, -0.55805732],\n", + " [ 0.02980115, -0.13866481, 0.18362213, -0.20969545, -0.14481622],\n", + " [ 0.00569934, -0.02338583, -0.06600665, 0.10749935, -0.15103655],\n", + " [-0.02008655, 0.09026348, -0.00552559, -0.03135532, 0.24329022]]),\n", + " array([[ 0.07744772, 0.09007074, -0.30472201, 0.27676245, 0.20289396],\n", + " [-0.0990298 , -0.08061847, 0.25853171, -0.1208633 , -0.11085208],\n", + " [-0.06171079, -0.06244152, 0.12007655, 0.00250637, -0.15679675],\n", + " [-0.00273697, -0.00900572, -0.00046003, -0.00855043, -0.05375465],\n", + " [ 0.03098733, 0.0397268 , -0.04997113, 0.00357694, 0.14182576]]),\n", + " array([[-0.06791915, -0.11357938, 0.37955393, -0.2178498 , -0.22977695],\n", + " [ 0.11596642, 0.14914957, -0.13357508, -0.00891606, 0.34841537],\n", + " [ 0.01173082, 0.0192738 , 0.04142658, -0.03534659, 0.02316491],\n", + " [ 0.00732891, 0.00553651, -0.02245608, 0.03611543, -0.03851434],\n", + " [-0.01058989, -0.01062662, -0.00054311, -0.02556748, 0.04984889]]),\n", + " array([[ 0.07276211, -0.01571956, 0.07428593, -0.10369862, 0.02475347],\n", + " [-0.05607105, -0.08896207, 0.27638225, -0.23711256, 0.07372294],\n", + " [-0.00739129, -0.0487418 , -0.62912397, 0.46816277, 0.09251699],\n", + " [-0.00711022, -0.05623318, -0.36606659, -0.0132978 , 0.64910332],\n", + " [ 0.00233552, -0.02156115, 0.09096243, -0.38438823, 0.66164772]])]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Ajs.transitions" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "Automaton.write(sp.automaton, train_file + \".yaml\", \"yaml\")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "Ayl = Automaton.read(train_file + \".yaml\", \"yaml\")" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[array([[ 0.04512121, -0.2403897 , 0.34945 , -0.28116807, -0.21402523],\n", + " [ 0.06925801, -0.30062293, 0.20641375, -0.14960814, -0.55805732],\n", + " [ 0.02980115, -0.13866481, 0.18362213, -0.20969545, -0.14481622],\n", + " [ 0.00569934, -0.02338583, -0.06600665, 0.10749935, -0.15103655],\n", + " [-0.02008655, 0.09026348, -0.00552559, -0.03135532, 0.24329022]]),\n", + " array([[ 0.07744772, 0.09007074, -0.30472201, 0.27676245, 0.20289396],\n", + " [-0.0990298 , -0.08061847, 0.25853171, -0.1208633 , -0.11085208],\n", + " [-0.06171079, -0.06244152, 0.12007655, 0.00250637, -0.15679675],\n", + " [-0.00273697, -0.00900572, -0.00046003, -0.00855043, -0.05375465],\n", + " [ 0.03098733, 0.0397268 , -0.04997113, 0.00357694, 0.14182576]]),\n", + " array([[-0.06791915, -0.11357938, 0.37955393, -0.2178498 , -0.22977695],\n", + " [ 0.11596642, 0.14914957, -0.13357508, -0.00891606, 0.34841537],\n", + " [ 0.01173082, 0.0192738 , 0.04142658, -0.03534659, 0.02316491],\n", + " [ 0.00732891, 0.00553651, -0.02245608, 0.03611543, -0.03851434],\n", + " [-0.01058989, -0.01062662, -0.00054311, -0.02556748, 0.04984889]]),\n", + " array([[ 0.07276211, -0.01571956, 0.07428593, -0.10369862, 0.02475347],\n", + " [-0.05607105, -0.08896207, 0.27638225, -0.23711256, 0.07372294],\n", + " [-0.00739129, -0.0487418 , -0.62912397, 0.46816277, 0.09251699],\n", + " [-0.00711022, -0.05623318, -0.36606659, -0.0132978 , 0.64910332],\n", + " [ 0.00233552, -0.02156115, 0.09096243, -0.38438823, 0.66164772]])]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Ayl.transitions" ] }, { @@ -85,7 +355,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.3" + "version": "3.5.2" } }, "nbformat": 4, diff --git a/examples/json_save.py b/examples/json_save.py deleted file mode 100644 index ae9eea1..0000000 --- a/examples/json_save.py +++ /dev/null @@ -1,13 +0,0 @@ -from splearn.datasets.base import load_data_sample -from splearn.tests.datasets.get_dataset_path import get_dataset_path -from splearn import Spectral -from splearn.automaton import Automaton -train_file = '3.pautomac_light.train' -data = load_data_sample(adr=get_dataset_path(train_file)) -sp = Spectral() -sp.fit(X=data.data) - -sp.automaton.write_json("test.json") -A = Automaton(1,1,[]).read_json("test.json") -print(A) - diff --git a/examples/simple_automata.json b/examples/simple_automata.json new file mode 100644 index 0000000..ab271a8 --- /dev/null +++ b/examples/simple_automata.json @@ -0,0 +1 @@ +{"automaton": {"final": {"numpy.ndarray": {"values": [0.15, 0.9], "dtype": "float64"}}, "initial": {"numpy.ndarray": {"values": [0.5, 0.8], "dtype": "float64"}}, "transitions": [{"numpy.ndarray": {"values": [[0.5, 0.15], [0.9, 0]], "dtype": "float64"}}, {"numpy.ndarray": {"values": [[0, 0], [0, -0.15]], "dtype": "float64"}}], "type": "classic", "nbS": 2, "nbL": 2}} diff --git a/examples/simple_automata.json.gv b/examples/simple_automata.json.gv new file mode 100644 index 0000000..0fd62e2 --- /dev/null +++ b/examples/simple_automata.json.gv @@ -0,0 +1,15 @@ +//Simple Automata +digraph { + 0 [label="0 +______ +> 0.50 +0.15 >"] + 1 [label="1 +______ +> 0.80 +0.90 >"] + 0 -> 0 [label="0:0.50"] + 0 -> 1 [label="0:0.15"] + 1 -> 0 [label="0:0.90"] + 1 -> 1 [label="1:-0.15"] +} diff --git a/examples/simple_automata.json.gv.pdf b/examples/simple_automata.json.gv.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bcedcde8006bcfa94c68c2c82199bd53b985503d GIT binary patch literal 11284 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 GaRC6!_DhEV literal 0 HcmV?d00001 diff --git a/examples/simple_automata.yaml b/examples/simple_automata.yaml new file mode 100644 index 0000000..b85b6ae --- /dev/null +++ b/examples/simple_automata.yaml @@ -0,0 +1,23 @@ +automaton: + final: + numpy.ndarray: + dtype: float64 + values: [0.15, 0.9] + initial: + numpy.ndarray: + dtype: float64 + values: [0.5, 0.8] + nbL: 2 + nbS: 2 + transitions: + - numpy.ndarray: + dtype: float64 + values: + - [0.5, 0.15] + - [0.9, 0] + - numpy.ndarray: + dtype: float64 + values: + - [0, 0] + - [0, -0.15] + type: classic diff --git a/examples/simple_automata.yaml.gv b/examples/simple_automata.yaml.gv new file mode 100644 index 0000000..0fd62e2 --- /dev/null +++ b/examples/simple_automata.yaml.gv @@ -0,0 +1,15 @@ +//Simple Automata +digraph { + 0 [label="0 +______ +> 0.50 +0.15 >"] + 1 [label="1 +______ +> 0.80 +0.90 >"] + 0 -> 0 [label="0:0.50"] + 0 -> 1 [label="0:0.15"] + 1 -> 0 [label="0:0.90"] + 1 -> 1 [label="1:-0.15"] +} diff --git a/examples/simple_automata.yaml.gv.pdf b/examples/simple_automata.yaml.gv.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bcedcde8006bcfa94c68c2c82199bd53b985503d GIT binary patch literal 11284 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 GaRC6!_DhEV literal 0 HcmV?d00001 diff --git a/examples/test.json b/examples/test.json deleted file mode 100644 index e4d8477..0000000 --- a/examples/test.json +++ /dev/null @@ -1 +0,0 @@ -{"nbL": 4, "nbS": 5, "initial": {"py/numpy.ndarray": {"values": [-0.0004934419970497512, 0.0030634697107912346, -0.044073932015580415, -0.1077770261654714, -0.0866391379316952], "dtype": "float64"}}, "final": {"py/numpy.ndarray": {"values": [0.07757136847945045, -0.024220294003132026, -0.4468125366321221, 0.627732084089759, -0.554674433356224], "dtype": "float64"}}, "transitions": [{"py/numpy.ndarray": {"values": [[0.04512120959511772, -0.24038969827844062, 0.34944999592135334, -0.2811680730534579, -0.21402523377497645], [0.0692580056243761, -0.30062293462829204, 0.20641375368520157, -0.14960814319756124, -0.5580573163749153], [0.02980115192176571, -0.13866480809160409, 0.18362212572805459, -0.20969545230657607, -0.14481622025561292], [0.005699344003198349, -0.023385825120201414, -0.06600665373981851, 0.10749935271466007, -0.15103654604159977], [-0.02008655193147911, 0.09026347555230492, -0.005525585655539262, -0.031355317090308935, 0.2432902242047721]], "dtype": "float64"}}, {"py/numpy.ndarray": {"values": [[0.0774477207917058, 0.09007073705762021, -0.3047220063293013, 0.2767624549859105, 0.20289396030628148], [-0.09902980483670844, -0.08061846818727973, 0.25853170692250554, -0.12086330214608881, -0.11085207725068251], [-0.061710792028537534, -0.06244151779954751, 0.12007654564862075, 0.0025063746277943564, -0.1567967473145572], [-0.002736973749965403, -0.009005721984277787, -0.00046003295909181354, -0.008550426472005344, -0.053754646789681754], [0.030987327588710728, 0.03972680066723246, -0.04997113350910248, 0.0035769411874962344, 0.1418257620585633]], "dtype": "float64"}}, {"py/numpy.ndarray": {"values": [[-0.06791915236220235, -0.11357937659088102, 0.37955392604054394, -0.21784979894046635, -0.22977695089938127], [0.11596642335411328, 0.14914956804629287, -0.13357508376686902, -0.008916063072034974, 0.3484153673774836], [0.011730817547426673, 0.019273800531955612, 0.0414265834586712, -0.035346588560982, 0.02316491010895583], [0.007328911075541707, 0.005536509132796312, -0.022456082950666856, 0.03611543477693187, -0.038514339001406585], [-0.010589894686551544, -0.010626616553723532, -0.000543105645661794, -0.025567476700160314, 0.04984888818929034]], "dtype": "float64"}}, {"py/numpy.ndarray": {"values": [[0.07276211427780357, -0.0157195576855797, 0.07428592814590385, -0.10369861539249735, 0.024753473688328077], [-0.05607105449779142, -0.08896207276035666, 0.27638225397521243, -0.2371125582838589, 0.07372294122306285], [-0.007391294007753122, -0.048741797963875705, -0.6291239733858526, 0.46816276521577677, 0.09251699239093385], [-0.007110224931878467, -0.05623317735898056, -0.36606658567620365, -0.013297798115225407, 0.6491033177492604], [0.002335515008556511, -0.021561151264484414, 0.09096243479437888, -0.38438823493062646, 0.6616477207948602]], "dtype": "float64"}}], "type": "classic"} \ No newline at end of file diff --git a/splearn/__init__.py b/splearn/__init__.py index 88d3dc0..ea4eddc 100644 --- a/splearn/__init__.py +++ b/splearn/__init__.py @@ -1,5 +1,5 @@ from splearn.automaton import Automaton -#from splearn.spectral import Learning +from splearn.serializer import Serializer from splearn.spectral import Spectral from splearn.hankel import Hankel __version__ = "1.1.0" diff --git a/splearn/automaton.py b/splearn/automaton.py index ad971aa..35e48e3 100644 --- a/splearn/automaton.py +++ b/splearn/automaton.py @@ -3,7 +3,7 @@ """ import numpy as np -from splearn.serializer import Serializer + class Automaton(object): """ Define an automaton with parameters @@ -643,9 +643,9 @@ class Automaton(object): >>> from graphviz import Source >>> src = Source(dot) >>> src.render(dotfile + '.gv', view=True) - + - Input: - + :param Automaton self :param float threshold for the value to keep. If |weight| < threshold, the corresponding transition is not kept as an edge in the final dot string. @@ -688,25 +688,48 @@ class Automaton(object): out += label + "\"]\n" out += "}\n" return out - - def write_json(self, jsonFileName): - data = {"nbL":self.nbL, "nbS":self.nbS, "initial":self.initial, "final":self.final, - "transitions":self.transitions, "type":self.type} - data_str = Serializer().data_to_json(data) - with open(jsonFileName, 'w') as outfile: + + @staticmethod + def write(automaton_in, filename, format='json'): + """ write input automaton into a file with the given format. + + - Input: + + :param Automaton automaton_in: automaton to write into the file + :param str filename: the name of the file. If it does not exist, + the file is created. + :param str format: 'json' or yaml' + """ + from splearn.serializer import Serializer + if format == 'json': + data_str = Serializer.data_to_json(automaton_in) + elif format == 'yaml': + data_str = Serializer.data_to_yaml(automaton_in) + else: + raise ValueError("Invalid input format. Should be \"json\" or \"yaml\"") + with open(filename, 'w') as outfile: outfile.write(data_str) - - def read_json(self, jsonFileName): - with open(jsonFileName) as infile: + + @staticmethod + def read(filename, format='json'): + """ return an Automaton build with attributes read from a file + + - Input: + + :param str filename: the name of the input file. + :param str format: 'json' or yaml' + + - Output: + + :returns: the output automaton + :rtype: Automaton + """ + from splearn.serializer import Serializer + with open(filename) as infile: datastr = infile.read() - data = Serializer().json_to_data(datastr) - print(data) - keys = {"nbL", "nbS", "initial", "final", "transitions", "type"} - if not keys.issubset(set(data.keys())): - raise ValueError("The input json file should contain the following keys : \"" + '\", \"'.join(keys) + "\"") - self = Automaton(nbL=data["nbL"], nbS=data["nbS"], initial=data["initial"], final=data["final"], - transitions=data["transitions"], type=data["type"]) - - - - + if format == 'json': + return Serializer.json_to_data(datastr) + if format == 'yaml': + return Serializer.yaml_to_data(datastr) + raise ValueError("Invalid input format. Should be \"json\" or \"yaml\"") + \ No newline at end of file diff --git a/splearn/serializer.py b/splearn/serializer.py index b8645ac..2ba5e90 100644 --- a/splearn/serializer.py +++ b/splearn/serializer.py @@ -1,50 +1,157 @@ -''' -Created on 6 févr. 2018 - -@author: arrivault -''' +# -*- coding: utf-8 -*- +"""This module contains the Serializer class +""" import numpy as np -import json + +from splearn.automaton import Automaton class Serializer(object): - ''' - classdocs - ''' - - def __serialize(self, data): + """ Serializer is an helping object for data serialization + """ + + @staticmethod + def __serialize(data): if data is None or isinstance(data, (bool, int, float, str)): return data if isinstance(data, list): - return [self.__serialize(val) for val in data] + return [Serializer.__serialize(val) for val in data] if isinstance(data, dict): if all(isinstance(k, str) for k in data): - return {k: self.__serialize(v) for k, v in data.items()} - return {"py/dict": [[self.__serialize(k), self.__serialize(v)] for k, v in data.items()]} + return {k: Serializer.__serialize(v) for k, v in data.items()} + return {"dict": [[Serializer.__serialize(k), Serializer.__serialize(v)] for k, v in data.items()]} if isinstance(data, tuple): - return {"py/tuple": [self.__serialize(val) for val in data]} + return {"tuple": [Serializer.__serialize(val) for val in data]} if isinstance(data, set): - return {"py/set": [self.__serialize(val) for val in data]} + return {"set": [Serializer.__serialize(val) for val in data]} if isinstance(data, np.ndarray): - return {"py/numpy.ndarray": { + return {"numpy.ndarray": { "values": data.tolist(), "dtype": str(data.dtype)}} - raise TypeError("Type %s not data-serializable" % type(data)) + if isinstance(data, Automaton): + data_dict = {"nbL":data.nbL, "nbS":data.nbS, "initial":data.initial, "final":data.final, + "transitions":data.transitions, "type":data.type} + return {"automaton" : Serializer.__serialize(data_dict)} + raise TypeError("Type %s is not serializabled" % type(data)) - def __restore(self, dct): - if "py/dict" in dct: - return dict(dct["py/dict"]) - if "py/tuple" in dct: - return tuple(dct["py/tuple"]) - if "py/set" in dct: - return set(dct["py/set"]) - if "py/numpy.ndarray" in dct: - data = dct["py/numpy.ndarray"] + @staticmethod + def __restore_json(data_str): + if "dict" in data_str: + return dict(data_str["dict"]) + if "tuple" in data_str: + return tuple(data_str["tuple"]) + if "set" in data_str: + return set(data_str["set"]) + if "numpy.ndarray" in data_str: + data = data_str["numpy.ndarray"] + keys = {"values", "dtype"} + if not keys.issubset(set(data.keys())): + raise ValueError("The input data string (" + data_str + + ") should contain the following keys : \"" + + '\", \"'.join(keys) + "\"") return np.array(data["values"], dtype=data["dtype"]) - return dct + if "automaton" in data_str: + data = Serializer.__restore_json(data_str["automaton"]) + keys = {"nbL", "nbS", "initial", "final", "transitions", "type"} + if not keys.issubset(set(data.keys())): + raise ValueError("The input data string (" + data_str + + ") should contain the following keys : \"" + + '\", \"'.join(keys) + "\"") + return Automaton(nbL=data["nbL"], nbS=data["nbS"], initial=data["initial"], final=data["final"], + transitions=data["transitions"], type=data["type"]) + return data_str + + @staticmethod + def __restore_yaml(data_str): + if "dict" in data_str: + return dict(data_str["dict"]) + if "tuple" in data_str: + return tuple(data_str["tuple"]) + if "set" in data_str: + return set(data_str["set"]) + if "numpy.ndarray" in data_str: + data = data_str["numpy.ndarray"] + keys = {"values", "dtype"} + if not keys.issubset(set(data.keys())): + raise ValueError("The input data string (" + data_str + + ") should contain the following keys : \"" + + '\", \"'.join(keys) + "\"") + return np.array(data["values"], dtype=data["dtype"]) + if "automaton" in data_str: + data = Serializer.__restore_yaml(data_str["automaton"]) + keys = {"nbL", "nbS", "initial", "final", "transitions", "type"} + if not keys.issubset(set(data.keys())): + raise ValueError("The input data string (" + data_str + + ") should contain the following keys : \"" + + '\", \"'.join(keys) + "\"") + return Automaton(nbL=data["nbL"], nbS=data["nbS"], initial=Serializer.__restore_yaml(data["initial"]), + final=Serializer.__restore_yaml(data["final"]), + transitions=[Serializer.__restore_yaml(k) for k in data["transitions"]], + type=data["type"]) + return data_str + + @staticmethod + def data_to_json(data): + """ return a string into json format that does contains the input data. + + - Input: + + :param data: data composed by any types that is serializabled + + - Output: + + :returns: the output string + :rtype: str + """ + + import json + return json.dumps(Serializer.__serialize(data)) + + @staticmethod + def json_to_data(json_data_str): + """ return a data from input json string. + + - Input: + + :param json_data_str: the json input string + + - Output: + + :returns: the data + :rtype: deduced form the json input string + """ + + import json + return json.loads(json_data_str, object_hook=Serializer.__restore_json) - def data_to_json(self, data): - return json.dumps(self.__serialize(data)) + @staticmethod + def data_to_yaml(data): + """ return a string into yaml format that does contains the input data. + + - Input: + + :param data: data composed by any types that is serializabled + + - Output: + + :returns: the output string + :rtype: str + """ + import yaml + return yaml.dump(Serializer.__serialize(data)) - def json_to_data(self, s): - return json.loads(s, object_hook=self.__restore) + @staticmethod + def yaml_to_data(yaml_data_str): + """ return a data from input yaml string. + + - Input: + + :param yaml_data_str: the yaml input string + + - Output: + + :returns: the data + :rtype: deduced form the yaml input string + """ + import yaml + return Serializer.__restore_yaml(yaml.load(yaml_data_str)) diff --git a/test.json b/test.json deleted file mode 100644 index e4d8477..0000000 --- a/test.json +++ /dev/null @@ -1 +0,0 @@ -{"nbL": 4, "nbS": 5, "initial": {"py/numpy.ndarray": {"values": [-0.0004934419970497512, 0.0030634697107912346, -0.044073932015580415, -0.1077770261654714, -0.0866391379316952], "dtype": "float64"}}, "final": {"py/numpy.ndarray": {"values": [0.07757136847945045, -0.024220294003132026, -0.4468125366321221, 0.627732084089759, -0.554674433356224], "dtype": "float64"}}, "transitions": [{"py/numpy.ndarray": {"values": [[0.04512120959511772, -0.24038969827844062, 0.34944999592135334, -0.2811680730534579, -0.21402523377497645], [0.0692580056243761, -0.30062293462829204, 0.20641375368520157, -0.14960814319756124, -0.5580573163749153], [0.02980115192176571, -0.13866480809160409, 0.18362212572805459, -0.20969545230657607, -0.14481622025561292], [0.005699344003198349, -0.023385825120201414, -0.06600665373981851, 0.10749935271466007, -0.15103654604159977], [-0.02008655193147911, 0.09026347555230492, -0.005525585655539262, -0.031355317090308935, 0.2432902242047721]], "dtype": "float64"}}, {"py/numpy.ndarray": {"values": [[0.0774477207917058, 0.09007073705762021, -0.3047220063293013, 0.2767624549859105, 0.20289396030628148], [-0.09902980483670844, -0.08061846818727973, 0.25853170692250554, -0.12086330214608881, -0.11085207725068251], [-0.061710792028537534, -0.06244151779954751, 0.12007654564862075, 0.0025063746277943564, -0.1567967473145572], [-0.002736973749965403, -0.009005721984277787, -0.00046003295909181354, -0.008550426472005344, -0.053754646789681754], [0.030987327588710728, 0.03972680066723246, -0.04997113350910248, 0.0035769411874962344, 0.1418257620585633]], "dtype": "float64"}}, {"py/numpy.ndarray": {"values": [[-0.06791915236220235, -0.11357937659088102, 0.37955392604054394, -0.21784979894046635, -0.22977695089938127], [0.11596642335411328, 0.14914956804629287, -0.13357508376686902, -0.008916063072034974, 0.3484153673774836], [0.011730817547426673, 0.019273800531955612, 0.0414265834586712, -0.035346588560982, 0.02316491010895583], [0.007328911075541707, 0.005536509132796312, -0.022456082950666856, 0.03611543477693187, -0.038514339001406585], [-0.010589894686551544, -0.010626616553723532, -0.000543105645661794, -0.025567476700160314, 0.04984888818929034]], "dtype": "float64"}}, {"py/numpy.ndarray": {"values": [[0.07276211427780357, -0.0157195576855797, 0.07428592814590385, -0.10369861539249735, 0.024753473688328077], [-0.05607105449779142, -0.08896207276035666, 0.27638225397521243, -0.2371125582838589, 0.07372294122306285], [-0.007391294007753122, -0.048741797963875705, -0.6291239733858526, 0.46816276521577677, 0.09251699239093385], [-0.007110224931878467, -0.05623317735898056, -0.36606658567620365, -0.013297798115225407, 0.6491033177492604], [0.002335515008556511, -0.021561151264484414, 0.09096243479437888, -0.38438823493062646, 0.6616477207948602]], "dtype": "float64"}}], "type": "classic"} \ No newline at end of file -- GitLab