Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data Save and Load Structure #63

Merged
merged 36 commits into from Oct 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
f5bf4fd
add : save_data_file added.
sadrasabouri Oct 22, 2021
8ce5bd5
add : save_data method. (#33)
sadrasabouri Oct 22, 2021
0c2d2ea
fix : minor issue fixed in save_data_file.
sadrasabouri Oct 22, 2021
dc3a64b
add : data parameter added.
sadrasabouri Oct 22, 2021
9f4c5da
add : samilaDataError.
sadrasabouri Oct 22, 2021
9c3355f
add : load_data function.
sadrasabouri Oct 22, 2021
ec53008
add : some error messages.
sadrasabouri Oct 22, 2021
0130e3f
log : changes logged.
sadrasabouri Oct 22, 2021
8620db4
fix : minor issue fixed.
sadrasabouri Oct 22, 2021
b701f6e
add : warning_test.py.
sadrasabouri Oct 22, 2021
936e2f9
fix : minor issues fixed.
sadrasabouri Oct 22, 2021
71b057e
edit : warning_test edited.
sadrasabouri Oct 22, 2021
7243553
fix : isinstance file --> IOBase.
sadrasabouri Oct 22, 2021
d84a556
fix : typo fixed.
sadrasabouri Oct 22, 2021
e855699
add : new line to warning_test.
sadrasabouri Oct 22, 2021
b784fad
add : samilaGenerateError.
sadrasabouri Oct 22, 2021
2c041a3
add : NO_FUNCTION_ERROR.
sadrasabouri Oct 22, 2021
9e4f85e
add : error_test.py.
sadrasabouri Oct 22, 2021
803a7f0
fix : None function on generate handled.
sadrasabouri Oct 22, 2021
a5e9c9e
edit : parsing edited.
sadrasabouri Oct 22, 2021
330de73
edit : load_data edite.
sadrasabouri Oct 22, 2021
df6c092
update : tests updated.
sadrasabouri Oct 22, 2021
f2f4c36
edit : tiny edit on error_test.py.
sadrasabouri Oct 22, 2021
d0e1062
update : warning_test updated.
sadrasabouri Oct 22, 2021
2339595
fix : error_test.py fixed.
sadrasabouri Oct 22, 2021
df2b301
fix : warning_test fixed.
sadrasabouri Oct 22, 2021
4169e09
fix : minor docstring issue fixed.
sadrasabouri Oct 22, 2021
5601281
fix : minor issue in load_data.
sadrasabouri Oct 22, 2021
79fb55b
fix : minor issue about save_data doc.
sadrasabouri Oct 23, 2021
9121ac3
edit : JUST_DATA_WARNING.
sadrasabouri Oct 23, 2021
3712727
update : README.md update.
sadrasabouri Oct 23, 2021
8f596da
update : tests updated.
sadrasabouri Oct 23, 2021
af2f49b
test : save_data error form added.
sadrasabouri Oct 25, 2021
c4a62f5
fix : test fixed.
sadrasabouri Oct 25, 2021
7738f41
update : README updated.
sadrasabouri Oct 28, 2021
5bed09b
add : errors imported to __init__.py.
sadrasabouri Oct 28, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions README.md
Expand Up @@ -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).

Expand Down
1 change: 1 addition & 0 deletions samila/__init__.py
Expand Up @@ -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
12 changes: 12 additions & 0 deletions samila/errors.py
@@ -1,2 +1,14 @@
# -*- coding: utf-8 -*-
"""Samila errors."""


class samilaDataError(Exception):
sepandhaghighi marked this conversation as resolved.
Show resolved Hide resolved
"""Data error class."""

pass


class samilaGenerateError(Exception):
sepandhaghighi marked this conversation as resolved.
Show resolved Hide resolved
"""Generate error class."""

pass
46 changes: 45 additions & 1 deletion samila/functions.py
Expand Up @@ -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):
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)
27 changes: 25 additions & 2 deletions samila/genimage.py
Expand Up @@ -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:
Expand All @@ -18,15 +20,24 @@ class GenerativeImage:
>>> GI = GenerativeImage(f1, f2)
"""

def __init__(self, function1, function2):
def __init__(self, function1=None, function2=None, data=None):
"""
Init method.

:param function1: Function 1
: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
Expand All @@ -50,6 +61,8 @@ def generate(
: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
Expand Down Expand Up @@ -133,3 +146,13 @@ def save_image(self, file_adr, depth=1):
: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)
7 changes: 7 additions & 0 deletions samila/params.py
Expand Up @@ -26,7 +26,14 @@
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):
Expand Down
26 changes: 26 additions & 0 deletions test/error_test.py
@@ -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')
"""
3 changes: 3 additions & 0 deletions test/overall_test.py
Expand Up @@ -87,6 +87,9 @@
False
>>> result["message"]
'No internet connection!'
>>> result = g.save_data(file_adr="")
>>> result["status"]
False
>>> os.remove("test.png")
>>> os.remove("test2.png")
"""
18 changes: 18 additions & 0 deletions test/warning_test.py
@@ -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')
"""