Starting Sheerka, learning Python
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
venv
|
||||||
|
.pytest_cache
|
||||||
|
.idea
|
||||||
|
__pycache__
|
||||||
@@ -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
|
||||||
@@ -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
@@ -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()
|
||||||
@@ -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)
|
||||||
Reference in New Issue
Block a user