Merge pull request #63 from sepandhaghighi/data

Data Save and Load Structure
pull/67/head
Sepand Haghighi 2021-10-28 16:07:09 +03:30 zatwierdzone przez GitHub
commit 53bd7bedac
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
10 zmienionych plików z 153 dodań i 3 usunięć

Wyświetl plik

@ -6,7 +6,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
### Added
- `load_data` function
- `save_data_file` function
- `save_data` method
### Changed
- `data` parameter added to GenerativeImage `__init__`
- `depth` parameter added to `save_image` method
- `depth` parameter added to `save_fig_file` function
- `save_image` and `nft_storage` methods background bug fixed

Wyświetl plik

@ -188,6 +188,18 @@ Save generated image in higher resolutions
{'status': True, 'message': 'Everything seems good'}
```
### Save data
Save generated data into a file
```pycon
>>> g.save_data(file_adr="test.json")
```
So you can load it into a `GenerativeImage` instance later by
```pycon
>>> g = GenerativeImage(data=open('test.json', 'r'))
```
## Mathematical details
Samila is simply a transformation between a square-shaped space from the Cartesian coordinate system to any arbitrary coordination like [Polar coordinate system](https://en.wikipedia.org/wiki/Polar_coordinate_system).

Wyświetl plik

@ -2,4 +2,5 @@
"""Samila modules."""
from .genimage import GenerativeImage
from .params import Projection, VALID_COLORS, SAMILA_VERSION
from .errors import samilaDataError, samilaGenerateError
__version__ = SAMILA_VERSION

Wyświetl plik

@ -1,2 +1,14 @@
# -*- coding: utf-8 -*-
"""Samila errors."""
class samilaDataError(Exception):
"""Data error class."""
pass
class samilaGenerateError(Exception):
"""Generate error class."""
pass

Wyświetl plik

@ -3,7 +3,9 @@
import requests
import io
from .params import Projection, DEFAULT_PROJECTION, VALID_COLORS, NFT_STORAGE_API, NFT_STORAGE_SUCCESS_MESSAGE, FIG_SAVE_SUCCESS_MESSAGE, NO_FIG_ERROR_MESSAGE, OVERVIEW
import json
from .params import Projection, DEFAULT_PROJECTION, VALID_COLORS, NFT_STORAGE_API, NFT_STORAGE_SUCCESS_MESSAGE, FIG_SAVE_SUCCESS_MESSAGE, NO_FIG_ERROR_MESSAGE, DATA_PARSING_ERROR, DATA_TYPE_ERROR, OVERVIEW, DATA_SAVE_SUCCESS_MESSAGE
from .errors import samilaDataError
def float_range(start, stop, step):
@ -113,6 +115,31 @@ def nft_storage_upload(api_key, data):
return result
def save_data_file(data1, data2, file_adr):
"""
Save config as file.
:param data1: data 1
:type data1: list
:param data2: data 2
:type data2: list
:param file_adr: file address
:type file_adr: str
:return: result as dict
"""
data = {}
data['data1'] = data1
data['data2'] = data2
result = {"status": True, "message": DATA_SAVE_SUCCESS_MESSAGE}
try:
with open(file_adr, 'w') as fp:
json.dump(data, fp)
except Exception as e:
result["status"] = False
result["message"] = str(e)
return result
def save_fig_file(figure, file_adr, depth):
"""
Save figure as file.
@ -194,3 +221,20 @@ def is_same_data(data1, data2, precision=10**-5):
"""
is_same = map(lambda x, y: abs(x - y) < precision, data1, data2)
return all(is_same)
def load_data(data):
"""
Load data file.
:param data: prior generated data
:type data: (io.IOBase & file)
:return: (data1, data2)
"""
if isinstance(data, io.IOBase):
try:
data = json.load(data)
return data['data1'], data['data2']
except:
raise samilaDataError(DATA_PARSING_ERROR)
raise samilaDataError(DATA_TYPE_ERROR)

Wyświetl plik

@ -3,8 +3,10 @@
import random
import itertools
import matplotlib.pyplot as plt
from .functions import float_range, filter_color, filter_projection, nft_storage_upload, save_fig_file, save_fig_buf
from .functions import float_range, filter_color, filter_projection, nft_storage_upload, save_data_file, save_fig_file, save_fig_buf, load_data
from .errors import samilaGenerateError
from .params import *
from warnings import warn
class GenerativeImage:
@ -18,7 +20,7 @@ class GenerativeImage:
>>> GI = GenerativeImage(f1, f2)
"""
def __init__(self, function1, function2):
def __init__(self, function1=None, function2=None, data=None):
"""
Init method.
@ -26,7 +28,16 @@ class GenerativeImage:
:type function1: python or lambda function
:param function2: Function 2
:type function2: python or lambda function
:param data: prior generated data
:type data: (io.IOBase & file)
"""
if function1 is None or function2 is None:
if data is None:
warn(NOTHING_PROVIDED_WARNING, RuntimeWarning)
else:
warn(JUST_DATA_WARNING, RuntimeWarning)
if data is not None:
self.data1, self.data2 = load_data(data)
self.function1 = function1
self.function2 = function2
self.fig = None
@ -50,6 +61,8 @@ class GenerativeImage:
:type stop: float
:return: None
"""
if self.function1 is None or self.function2 is None:
raise samilaGenerateError(NO_FUNCTION_ERROR)
self.data1 = []
self.data2 = []
self.seed = seed
@ -133,3 +146,13 @@ class GenerativeImage:
:return: result as dict
"""
return save_fig_file(figure=self.fig, file_adr=file_adr, depth=depth)
def save_data(self, file_adr='data.json'):
"""
Save data into a file.
:param file_adr: file addresses
:type file_adr: str
:return: result as dict
"""
return save_data_file(self.data1, self.data2, file_adr)

Wyświetl plik

@ -26,7 +26,14 @@ VALID_COLORS = list(dict(mcolors.BASE_COLORS, **mcolors.CSS4_COLORS).keys())
NFT_STORAGE_API = "https://api.nft.storage/upload"
NFT_STORAGE_SUCCESS_MESSAGE = "Everything seems good."
FIG_SAVE_SUCCESS_MESSAGE = "Everything seems good."
DATA_SAVE_SUCCESS_MESSAGE = "Everything seems good."
NO_FIG_ERROR_MESSAGE = "No figure was found. First run `generate` and `plot` methods."
DATA_TYPE_ERROR = "Provided data file is not supported. It should be either file or io.IOBase."
DATA_PARSING_ERROR = "Provided data format is wrong. It should be in JSON format including data1 and data2 fields."
NO_FUNCTION_ERROR = "At least one of the given functions are None."
JUST_DATA_WARNING = "Just data is provided, generate method is not available in this mode."
NOTHING_PROVIDED_WARNING = "Neither function nor data is provided."
class Projection(Enum):

26
test/error_test.py 100644
Wyświetl plik

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
"""
>>> from samila import *
>>> import os
>>> from pytest import warns
>>> g = GenerativeImage(data="data.json")
Traceback (most recent call last):
...
samila.errors.samilaDataError: Provided data file is not supported. It should be either file or io.IOBase.
>>> with open('data.json', 'w') as fp:
... result = fp.write('test')
>>> g = GenerativeImage(data=open("data.json", 'r'))
Traceback (most recent call last):
...
samila.errors.samilaDataError: Provided data format is wrong. It should be in JSON format including data1 and data2 fields.
>>> g = GenerativeImage(lambda x,y: 0, lambda x,y: 0)
>>> g.generate(step=0.1)
>>> result = g.save_data('data.json')
>>> with warns(RuntimeWarning, match="Just data is provided, generate method is not available in this mode."):
... g = GenerativeImage(data=open('data.json', 'r'))
>>> g.generate()
Traceback (most recent call last):
...
samila.errors.samilaGenerateError: At least one of the given functions are None.
>>> os.remove('data.json')
"""

Wyświetl plik

@ -87,6 +87,9 @@ False
False
>>> result["message"]
'No internet connection!'
>>> result = g.save_data(file_adr="")
>>> result["status"]
False
>>> os.remove("test.png")
>>> os.remove("test2.png")
"""

Wyświetl plik

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
"""
>>> import os
>>> from samila import *
>>> from pytest import warns
>>> with warns(RuntimeWarning, match="Neither function nor data is provided."):
... g = GenerativeImage()
>>> g = GenerativeImage(lambda x,y: 0, lambda x,y: 0)
>>> g.generate(step=0.1)
>>> result = g.save_data()
>>> with warns(RuntimeWarning, match="Just data is provided, generate method is not available in this mode."):
... g_ = GenerativeImage(data=open('data.json', 'r'))
>>> g_.data1 == g.data1
True
>>> g_.data2 == g.data2
True
>>> os.remove('data.json')
"""