Starting Sheerka, learning Python

This commit is contained in:
Kodjo Sossouvi
2019-07-18 23:55:14 +02:00
commit ab57a84956
9 changed files with 283 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
[*]
charset=utf-8
end_of_line=lf
insert_final_newline=false
indent_style=space
indent_size=4
[*.json]
indent_style=space
indent_size=2
# Tab indentation (no size specified)
[Makefile]
indent_style = tab
+4
View File
@@ -0,0 +1,4 @@
venv
.pytest_cache
.idea
__pycache__
+4
View File
@@ -0,0 +1,4 @@
test:
py.test tests
.PHONY: init test
+3
View File
@@ -0,0 +1,3 @@
f = open("MyFirstFile.txt", "w+")
f.close()
View File
+36
View File
@@ -0,0 +1,36 @@
class Concept:
"""
Default concept object
A concept is a the base object of our universe
Everything is a concept
"""
concepts_id = 0
def __init__(self, name, is_builtin=False):
self.name = name
self.is_builtin = is_builtin
self.pre = None # list of pre conditions before calling the main function
self.post = None # list of post conditions after calling the main function
self.main = None # main method
self.id = Concept.concepts_id
Concept.concepts_id = Concept.concepts_id + 1
self.props = [] # list of Property for this concept
self.functions = {} # list of helper functions
def __str__(self):
return f"({self.id}){self.name}"
def __repr__(self):
return f"({self.id}){self.name}"
class Property:
"""
Defines a behaviour of Concept
"""
def __init__(self, concept, value):
self.concept = concept
self.value = value
+84
View File
@@ -0,0 +1,84 @@
import os
from dataclasses import dataclass
from core.concept import Concept
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
@dataclass
class ReturnValue:
"""
Class that handle the return of a concept
To avoid using the try/except pattern for each and every call
To give context (ie return message) even when the call is successful
"""
status: bool
value: Concept
message: str = None
class Sheerka(Concept, metaclass=Singleton):
"""
Main controller for the project
"""
NAME = "Sheerka"
UNKNOWN_CONCEPT_NAME = "Unknown Concept"
ERROR_CONCEPT_NAME = "Error"
SUCCESS_CONCEPT_NAME = "Success"
def __init__(self):
super().__init__(Sheerka.NAME)
# ist of all concepts known be the system
self.concepts = []
# At a given point of time, (TODO: in a specific contexts), somme concepts are instantiated
# ex: File is a concept, but File('foo.txt') is an instance
self.instances = [] # list of actual instances
# List of the known rules by the system
# ex: hello => say('hello')
self.rules = []
self.create_builtin_concept()
def create_builtin_concept(self):
self.concepts.append(self)
self.concepts.append(Concept(Sheerka.UNKNOWN_CONCEPT_NAME))
self.concepts.append(Concept(Sheerka.SUCCESS_CONCEPT_NAME))
self.concepts.append(Concept(Sheerka.ERROR_CONCEPT_NAME))
def initialize(self, root_folder):
# create the folder configuration folder if needed
try:
if not os.path.exists(root_folder):
os.makedirs(root_folder)
except IOError as e:
return ReturnValue(False, self.get_concept(Sheerka.ERROR_CONCEPT_NAME, True), e)
return ReturnValue(True, self.get_concept(Sheerka.SUCCESS_CONCEPT_NAME, True))
def get_concept(self, name, is_builtin=False):
for concept in self.concepts:
if concept.name == name and concept.is_builtin == is_builtin:
return concept
return self.concepts[1]
@staticmethod
def concept_equals(concept1, concept2):
if concept1 is None and concept2 is None:
return True
if concept1 is None or concept2 is None:
return False
return concept1.id == concept2.id
+103
View File
@@ -0,0 +1,103 @@
#### Base syntax
How to define a new concept
concept newFile:
props:
name
pre:
import os
os.path.isfile(name) == False
post:
import os
os.path.isfile(name) == True
main:
f = open(name)
f.close()
__context__.add(newFile, name, f)
example
create a new file named MyFirstFile.txt => newFile("MyFirstFile.txt")
concept newFile:
props:
name
path
pre:
import os
os.path.isfile(path) == False
post:
import os
os.path.isfile(path) == True
main:
import os
f = open(name)
f.close()
sheeka.add(File(name, path))
concept open:
pre:
self.is_opened == False
post:
self.is_opened == True
main:
self.open
open the door => d = get_instance(door) && get_concept(open).call(d)
concept File:
props:
name
path
def open():
def close():
open the file toto.txt => get_concept(open).call(File(path="toto.txt", name="toto.txt))
concept is_the_opposite:
props:
a, b
test:
a.pre == not b.pre && a.post == b.post
print all concepts
concepts
print all
concept print:
main:
print(self)
concept all:
main:
self.find_all()
+34
View File
@@ -0,0 +1,34 @@
import os
from core.concept import Concept
from core.sheerka import Sheerka
def test_root_folder_is_created_after_initialization():
root_folder = "init_folder"
return_value = Sheerka().initialize(root_folder)
assert return_value.status, "initialisation should be successful"
assert Sheerka().concept_equals(return_value.value, Sheerka().get_concept("success"))
assert os.path.exists(root_folder), "init folder should be created"
def test_lists_of_concepts_is_initialized():
root_folder = "init_folder"
Sheerka().initialize(root_folder)
assert len(Sheerka().concepts) > 1
def test_null_concept_are_equals():
concept1 = Concept("test1")
concept2 = Concept("test2")
concept3 = Concept("test3")
assert not Sheerka.concept_equals(concept1, None)
assert not Sheerka.concept_equals(None, concept1)
assert not Sheerka.concept_equals(concept1, concept2)
assert not Sheerka.concept_equals(concept1, concept3)
assert Sheerka.concept_equals(None, None)
assert Sheerka.concept_equals(concept1, concept1)