Merge branch 'dev' of github.com:sepandhaghighi/samila into github-actions

pull/13/head
sadrasabouri 2021-09-29 08:53:38 +03:30
commit a5b7c5251a
9 zmienionych plików z 163 dodań i 4 usunięć

13
.github/ISSUE_TEMPLATE.md vendored 100644
Wyświetl plik

@ -0,0 +1,13 @@
#### Description
#### Steps/Code to Reproduce
#### Expected Behavior
#### Actual Behavior
#### Operating System
#### Python Version
#### Samila Version (Use : `samila.__version__`)

Wyświetl plik

@ -0,0 +1,7 @@
#### Reference Issues/PRs
#### What does this implement/fix? Explain your changes.
#### Any other comments?

18
CHANGELOG.md 100644
Wyświetl plik

@ -0,0 +1,18 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [0.1] - 2021-09-30
### Added
- `GenerativeImage` class
- `plot` method
- `generate` method
[Unreleased]: https://github.com/sepandhaghighi/samila/compare/v0.1...dev
[0.1]: https://github.com/sepandhaghighi/samila/compare/1058677...v0.1

23
LICENSE 100644
Wyświetl plik

@ -0,0 +1,23 @@
MIT License
Copyright (c) 2021 Sepand Haghighi
Copyright (c) 2021 Sadra Sabouri
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

2
requirements.txt 100644
Wyświetl plik

@ -0,0 +1,2 @@
matplotlib>=3.0.0

Wyświetl plik

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
"""Samila modules."""
from .genimage import GenerativeImage
from .params import Projection

Wyświetl plik

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
"""Samila functions."""
from .params import Projection, DEFAULT_PROJECTION
def float_range(start, stop, step):
"""
@ -17,3 +18,64 @@ def float_range(start, stop, step):
while start < stop:
yield float(start)
start += step
def distance_calc(s1, s2):
"""
Calculate Levenshtein distance between two words.
:param s1: first string
:type s1 : str
:param s2: second string
:type s2 : str
:return: distance between two string
References :
1- https://stackoverflow.com/questions/2460177/edit-distance-in-python
2- https://en.wikipedia.org/wiki/Levenshtein_distance
"""
if len(s1) > len(s2):
s1, s2 = s2, s1
distances = range(len(s1) + 1)
for i2, c2 in enumerate(s2):
distances_ = [i2 + 1]
for i1, c1 in enumerate(s1):
if c1 == c2:
distances_.append(distances[i1])
else:
distances_.append(
1 + min((distances[i1], distances[i1 + 1], distances_[-1])))
distances = distances_
return distances[-1]
def filter_color(color):
"""
Filter given color and return it
:param color: given color
:type color: str or tuple
:return: filtered version of color
"""
if isinstance(color, tuple):
return color
if isinstance(color, str):
from .params import VALID_COLORS
distance_list = list(map(lambda x: distance_calc(color, x),
VALID_COLORS))
min_distance = min(distance_list)
return VALID_COLORS[distance_list.index(min_distance)]
return None
def filter_projection(projection):
"""
Filter given projection.
:param projection: given projection
:type projection: Projection enum
:return: filtered version of projection
"""
if isinstance(projection, Projection):
return projection.value
return DEFAULT_PROJECTION

Wyświetl plik

@ -3,7 +3,7 @@
import random
import itertools
import matplotlib.pyplot as plt
from .functions import float_range
from .functions import float_range, filter_color, filter_projection
from .params import *
@ -35,17 +35,20 @@ class GenerativeImage:
self.data1 = []
self.data2 = []
self.seed = seed
random.seed(self.seed)
if seed is None:
self.seed = random.randint(0, 2 ** 20)
range1 = list(float_range(start, stop, step))
range2 = list(float_range(start, stop, step))
range_prod = list(itertools.product(range1, range2))
for item in range_prod:
random.seed(self.seed)
self.data1.append(self.function1(item[0], item[1]))
self.data2.append(self.function2(item[0], item[1]))
def plot(
self,
color=DEFAULT_COLOR,
bgcolor=DEFAULT_BACKGROUND_COLOR,
spot_size=DEFAULT_SPOT_SIZE,
size=DEFAULT_IMAGE_SIZE,
projection=DEFAULT_PROJECTION):
@ -54,6 +57,8 @@ class GenerativeImage:
:param color: point colors
:type color: str
:param bgcolor: background color
:type bgcolor: str
:param spot_size: point spot size
:type spot_size: float
:param size: figure size
@ -62,8 +67,21 @@ class GenerativeImage:
:type projection: str
:return: None
"""
color = filter_color(color) if not None else DEFAULT_COLOR
bgcolor = filter_color(
bgcolor) if not None else DEFAULT_BACKGROUND_COLOR
projection = filter_projection(projection)
fig = plt.figure()
fig.set_size_inches(size[0], size[1])
fig.set_facecolor(bgcolor)
ax = fig.add_subplot(111, projection=projection)
ax.scatter(self.data2, self.data1, alpha=0.1, c=color, s=spot_size)
ax.axis('off')
ax.set_facecolor(bgcolor)
ax.scatter(
self.data2,
self.data1,
alpha=DEFAULT_ALPHA,
edgecolors=color,
s=spot_size)
ax.set_axis_off()
ax.patch.set_zorder(-1)
ax.add_artist(ax.patch)

Wyświetl plik

@ -1,11 +1,26 @@
# -*- coding: utf-8 -*-
"""Samila params."""
import math
from enum import Enum
from matplotlib import colors as mcolors
DEFAULT_START = -1 * math.pi
DEFAULT_STOP = math.pi
DEFAULT_STEP = 0.01
DEFAULT_COLOR = "black"
DEFAULT_BACKGROUND_COLOR = "white"
DEFAULT_ALPHA = 0.1
DEFAULT_IMAGE_SIZE = (10, 10)
DEFAULT_SPOT_SIZE = 0.01
DEFAULT_PROJECTION = None
VALID_COLORS = list(dict(mcolors.BASE_COLORS, **mcolors.CSS4_COLORS).keys())
class Projection(Enum):
DEFAULT = DEFAULT_PROJECTION
POLAR = "polar"
AITOFF = "aitoff"
HAMMER = "hammer"
LAMBERT = "lambert"
MOLLWEIDE = "mollweide"
RECTILINEAR = "rectilinear"