Skip to content

Commit b3f7abc

Browse files
add files
1 parent 2f5ada7 commit b3f7abc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1469
-0
lines changed

Pipfile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[[source]]
2+
3+
url = "https://pypi.python.org/simple"
4+
verify_ssl = true
5+
name = "pypi"
6+
7+
8+
[packages]
9+
10+
"neo4j-driver" = "*"
11+
numpy = "*"
12+
13+
[dev-packages]
14+

basic_types/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .nano_type import NanoType, NanoID

basic_types/nano_type.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from typing import Generic, TypeVar
2+
from uuid import uuid4, UUID
3+
4+
T = TypeVar('T')
5+
6+
7+
class NanoType(Generic[T]):
8+
def __init__(self, value: [T]):
9+
self._value: T = value
10+
11+
@property
12+
def value(self) -> T:
13+
return self._value
14+
15+
def __hash__(self):
16+
return self._value.__hash__()
17+
18+
def __eq__(self, other):
19+
if isinstance(other, NanoType):
20+
return self._value.__eq__(other._value)
21+
return self._value.__eq__(other)
22+
23+
def __ne__(self, other):
24+
return self._value.__ne__(other)
25+
26+
def __gt__(self, other):
27+
return self._value.__gt__(other)
28+
29+
def __lt__(self, other):
30+
return self._value.__lt__(other)
31+
32+
def __str__(self):
33+
return str(self.value)
34+
35+
def __repr__(self):
36+
return str(self.value)
37+
38+
39+
class NanoID(NanoType[UUID]):
40+
41+
@property
42+
def id(self) -> NanoType:
43+
return self
44+
45+
@classmethod
46+
def new_random(cls):
47+
return cls(uuid4())

config/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
local*

config/__init__.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from collections import defaultdict
2+
from .environment import Environment
3+
4+
# There are too many layers and too many files to this config system
5+
default_values = {
6+
'neo4j_url': 'bolt://localhost',
7+
'neo4j_user': 'neo4j',
8+
'neo4j_password': 'local neo hates security!'
9+
}
10+
11+
environment_box = Environment(None)
12+
13+
14+
def set_environment(environment_name):
15+
environment_box.name = environment_name
16+
17+
18+
def get(config_variable_name):
19+
# don't execute code in overrides till necessary
20+
from .overrides import overrides
21+
return overrides[environment_box.name].get(config_variable_name, default_values[config_variable_name])
22+
23+
24+
class Config(object):
25+
@property
26+
def neo4j_url(self):
27+
return get('neo4j_url')
28+
29+
@property
30+
def neo4j_user(self):
31+
return get('neo4j_user')
32+
33+
@property
34+
def neo4j_password(self):
35+
return get('neo4j_password')
36+
37+
38+
config: Config = Config()
39+
40+
import os
41+
42+
if 'ENVIRONMENT' not in os.environ:
43+
raise Exception("You must set an ENVIRONMENT variable. Sorry, I am very opinionated that we should not have a default value because it will mask misconfiguration issues later.")
44+
set_environment(os.environ['ENVIRONMENT'])

config/environment.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Environment(object):
2+
def __init__(self, name):
3+
self.name = name

config/overrides.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import json
2+
overrides = dict()
3+
4+
# There are too many layers and too many files to this config system
5+
overrides.update(**{
6+
'remote': {
7+
'neo4j_url': 'bolt://796bafef-staging.databases.neo4j.io',
8+
'neo4j_user': 'readonly',
9+
'neo4j_password': '0s3DGA6Zq'
10+
},
11+
'floyd': { # Todo: implement me?
12+
'neo4j_url': 'bolt://796bafef-staging.databases.neo4j.io',
13+
'neo4j_user': 'readonly',
14+
'neo4j_password': '0s3DGA6Zq'
15+
},
16+
'local': { # Just uses defaults
17+
18+
}
19+
})
20+
21+
with open('./config/local_overrides.json') as f:
22+
overrides.update(json.load(f))

data_sets/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .synthetic_review_prediction import runner
Binary file not shown.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Synthetic Review Prediction
2+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
# TODO: create a decorator to do this for us
3+
from .article_0 import runner as article_0_runner
4+
from .experiment_1 import runner as experiment_1_runner
5+
from .experiment_2 import runner as experiment_2_runner
6+
from .experiment_3 import runner as experiment_3_runner
7+
from .experiment_4 import runner as experiment_4_runner
8+
from .experiment_5 import runner as experiment_5_runner
9+
10+
runner = dict()
11+
runner.update(article_0_runner)
12+
runner.update(experiment_1_runner)
13+
runner.update(experiment_2_runner)
14+
runner.update(experiment_3_runner)
15+
runner.update(experiment_4_runner)
16+
runner.update(experiment_5_runner)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from .configure import DATASET_NAME, create_data_set_properties
2+
from .generate import run as _run
3+
4+
5+
def run(client):
6+
print(DATASET_NAME)
7+
return _run(client, create_data_set_properties())
8+
9+
runner = {
10+
DATASET_NAME: run
11+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from ..meta_classes import DataSetProperties
2+
from ..meta_classes.data_set_properties import PersonStyleWeightDistribution, PersonStyleWeight, ProductStyleWeight
3+
from ..utils import WeightedOption, Distribution
4+
from ..classes import PersonStylePreferenceEnum, ProductStyleEnum, Style
5+
from ..experiment_1.opinion_function import opinion_function
6+
from ..experiment_1.style_functions import person_style_function, product_style_function
7+
from graph_io.classes.dataset_name import DatasetName
8+
9+
DATASET_NAME = DatasetName('article_0')
10+
11+
12+
def create_data_set_properties() -> DataSetProperties:
13+
N_STYLES = 2
14+
styles = [Style(str(i)) for i in range(N_STYLES)]
15+
16+
for style in styles:
17+
ProductStyleEnum.register('LIKES_STYLE_'+style.value, style)
18+
PersonStylePreferenceEnum.register('HAS_STYLE_'+style.value, style)
19+
20+
data_set_properties = DataSetProperties(
21+
dataset_name=DATASET_NAME,
22+
n_reviews=20000,
23+
reviews_per_product=10,
24+
reviews_per_person_distribution=[
25+
WeightedOption[int](1, 0.25),
26+
WeightedOption[int](2, 0.25),
27+
WeightedOption[int](3, 0.25),
28+
WeightedOption[int](4, 0.25)
29+
],
30+
person_styles_distribution=PersonStyleWeightDistribution([
31+
PersonStyleWeight(x, 1) for x in PersonStylePreferenceEnum.iterate()
32+
]),
33+
product_styles_distribution=Distribution[ProductStyleWeight, ProductStyleEnum]([
34+
ProductStyleWeight(x, 1) for x in ProductStyleEnum.iterate()
35+
]),
36+
opinion_function=opinion_function,
37+
person_style_function=person_style_function,
38+
product_style_function=product_style_function,
39+
n_companies=0,
40+
person_company_number_of_relationships_distribution=[]
41+
)
42+
43+
return data_set_properties
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from ..classes import PersonWroteReview, ReviewOfProduct, IsGoldenFlag
2+
import random
3+
4+
from ..meta_classes import DataSetProperties
5+
from ..experiment_1.simple_data_set import SimpleDataSet
6+
from ..utils import DatasetWriter
7+
from graph_io import QueryParams, CypherQuery
8+
9+
10+
def run(client, data_set_properties: DataSetProperties):
11+
12+
with DatasetWriter(client, data_set_properties.dataset_name, {"is_golden",""}) as writer:
13+
14+
writer.nuke_dataset()
15+
16+
data_set: SimpleDataSet = SimpleDataSet(data_set_properties)
17+
18+
def create_indexes():
19+
client.execute_cypher_write(CypherQuery("CREATE INDEX ON :NODE(id)"), QueryParams())
20+
#client.execute_cypher_write(CypherQuery("CREATE INDEX ON :NODE(id, dataset_name)"), QueryParams())
21+
pass
22+
23+
create_indexes()
24+
25+
for i, product in enumerate(data_set.generate_public_products()):
26+
writer.create_node_if_not_exists(product, {"style"})
27+
28+
for i, person in enumerate(data_set.generate_public_people()):
29+
writer.create_node_if_not_exists(person, {"style_preference"})
30+
31+
for review in data_set.generate_reviews(person):
32+
review.test = random.random() <= 0.1
33+
writer.create_node_if_not_exists(review, {"score", "test"})
34+
writer.create_edge_if_not_exists(PersonWroteReview(review.by_person, review.id, IsGoldenFlag(False)), set())
35+
writer.create_edge_if_not_exists(ReviewOfProduct(review.id, review.of_product, IsGoldenFlag(False)), set())
36+
37+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Extending the type system of python
2+
from .dynamic_enum import DynamicEnum
3+
4+
# Primitives (TODO: do these need to be exposed?)
5+
from .golden_flag import IsGoldenFlag
6+
from .graph_node import GraphNode
7+
from graph_io.classes.dataset_name import DatasetName
8+
from .graph_edge import GraphEdge
9+
10+
# Enum Types within our business logic
11+
from .style import Style
12+
13+
# Node Types within our business logic
14+
from .company import CompanyID, Company
15+
from .product import ProductID, Product, ProductStyle, ProductStyleEnum, ProductStyleVector
16+
from .person import PersonID, Person, PersonMetaProperties, PersonStylePreference, PersonStylePreferenceEnum, PersonStylePreferenceVector
17+
from .review import Review, ReviewScore, ReviewID
18+
19+
# Edge Types within our business logic
20+
from .person_opinion_company import PersonHatesCompany, PersonLikesCompany
21+
from .person_wrote_review import PersonWroteReview, ReviewOfProduct
22+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from uuid import UUID, uuid4
2+
from .graph_node import NodeLabel, GraphNodeIdentifier, GraphNode, IsGoldenFlag
3+
from basic_types import NanoType, NanoID
4+
from .style import Style
5+
from .dynamic_enum import DynamicEnum
6+
7+
8+
class CompanyID(GraphNodeIdentifier):
9+
LABEL = NodeLabel('Company')
10+
11+
def __init__(self, _id: UUID):
12+
super().__init__(self.LABEL, _id)
13+
14+
15+
class Company(GraphNode[CompanyID]):
16+
pass
17+

0 commit comments

Comments
 (0)