Skip to content

Commit baf74a6

Browse files
committed
cp to tests
1 parent 20c5039 commit baf74a6

File tree

2 files changed

+264
-0
lines changed

2 files changed

+264
-0
lines changed

tests/schema_university.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import datajoint as dj
2+
3+
schema = dj.Schema()
4+
5+
6+
@schema
7+
class Student(dj.Manual):
8+
definition = """
9+
student_id : int unsigned # university-wide ID number
10+
---
11+
first_name : varchar(40)
12+
last_name : varchar(40)
13+
sex : enum('F', 'M', 'U')
14+
date_of_birth : date
15+
home_address : varchar(120) # mailing street address
16+
home_city : varchar(60) # mailing address
17+
home_state : char(2) # US state acronym: e.g. OH
18+
home_zip : char(10) # zipcode e.g. 93979-4979
19+
home_phone : varchar(20) # e.g. 414.657.6883x0881
20+
"""
21+
22+
23+
@schema
24+
class Department(dj.Manual):
25+
definition = """
26+
dept : varchar(6) # abbreviated department name, e.g. BIOL
27+
---
28+
dept_name : varchar(200) # full department name
29+
dept_address : varchar(200) # mailing address
30+
dept_phone : varchar(20)
31+
"""
32+
33+
34+
@schema
35+
class StudentMajor(dj.Manual):
36+
definition = """
37+
-> Student
38+
---
39+
-> Department
40+
declare_date : date # when student declared her major
41+
"""
42+
43+
44+
@schema
45+
class Course(dj.Manual):
46+
definition = """
47+
-> Department
48+
course : int unsigned # course number, e.g. 1010
49+
---
50+
course_name : varchar(200) # e.g. "Neurobiology of Sensation and Movement."
51+
credits : decimal(3,1) # number of credits earned by completing the course
52+
"""
53+
54+
55+
@schema
56+
class Term(dj.Manual):
57+
definition = """
58+
term_year : year
59+
term : enum('Spring', 'Summer', 'Fall')
60+
"""
61+
62+
63+
@schema
64+
class Section(dj.Manual):
65+
definition = """
66+
-> Course
67+
-> Term
68+
section : char(1)
69+
---
70+
auditorium : varchar(12)
71+
"""
72+
73+
74+
@schema
75+
class CurrentTerm(dj.Manual):
76+
definition = """
77+
omega=0 : tinyint
78+
---
79+
-> Term
80+
"""
81+
82+
83+
@schema
84+
class Enroll(dj.Manual):
85+
definition = """
86+
-> Student
87+
-> Section
88+
"""
89+
90+
91+
@schema
92+
class LetterGrade(dj.Lookup):
93+
definition = """
94+
grade : char(2)
95+
---
96+
points : decimal(3,2)
97+
"""
98+
contents = [
99+
["A", 4.00],
100+
["A-", 3.67],
101+
["B+", 3.33],
102+
["B", 3.00],
103+
["B-", 2.67],
104+
["C+", 2.33],
105+
["C", 2.00],
106+
["C-", 1.67],
107+
["D+", 1.33],
108+
["D", 1.00],
109+
["F", 0.00],
110+
]
111+
112+
113+
@schema
114+
class Grade(dj.Manual):
115+
definition = """
116+
-> Enroll
117+
---
118+
-> LetterGrade
119+
"""

tests/test_university.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
from nose.tools import assert_true, assert_list_equal, assert_false, raises
2+
import hashlib
3+
from datajoint import DataJointError
4+
from .schema_university import *
5+
from . import PREFIX, CONN_INFO
6+
7+
8+
def _hash4(table):
9+
"""hash of table contents"""
10+
data = table.fetch(order_by="KEY", as_dict=True)
11+
blob = dj.blob.pack(data, compress=False)
12+
return hashlib.md5(blob).digest().hex()[:4]
13+
14+
15+
@raises(DataJointError)
16+
def test_activate_unauthorized():
17+
schema.activate("unauthorized", connection=dj.conn(**CONN_INFO))
18+
19+
20+
def test_activate():
21+
schema.activate(
22+
PREFIX + "_university", connection=dj.conn(**CONN_INFO)
23+
) # deferred activation
24+
# --------------- Fill University -------------------
25+
for table in (
26+
Student,
27+
Department,
28+
StudentMajor,
29+
Course,
30+
Term,
31+
CurrentTerm,
32+
Section,
33+
Enroll,
34+
Grade,
35+
):
36+
from pathlib import Path
37+
38+
table().insert(Path("./data/" + table.__name__ + ".csv"))
39+
40+
41+
def test_fill():
42+
"""check that the randomized tables are consistently defined"""
43+
# check randomized tables
44+
assert_true(len(Student()) == 300 and _hash4(Student) == "1e1a")
45+
assert_true(len(StudentMajor()) == 226 and _hash4(StudentMajor) == "3129")
46+
assert_true(len(Section()) == 756 and _hash4(Section) == "dc7e")
47+
assert_true(len(Enroll()) == 3364 and _hash4(Enroll) == "177d")
48+
assert_true(len(Grade()) == 3027 and _hash4(Grade) == "4a9d")
49+
50+
51+
def test_restrict():
52+
"""
53+
test diverse restrictions from the university database.
54+
This test relies on a specific instantiation of the database.
55+
"""
56+
utahns1 = Student & {"home_state": "UT"}
57+
utahns2 = Student & 'home_state="UT"'
58+
assert_true(len(utahns1) == len(utahns2.fetch("KEY")) == 7)
59+
60+
# male nonutahns
61+
sex1, state1 = ((Student & 'sex="M"') - {"home_state": "UT"}).fetch(
62+
"sex", "home_state", order_by="student_id"
63+
)
64+
sex2, state2 = ((Student & 'sex="M"') - {"home_state": "UT"}).fetch(
65+
"sex", "home_state", order_by="student_id"
66+
)
67+
assert_true(len(set(state1)) == len(set(state2)) == 44)
68+
assert_true(set(sex1).pop() == set(sex2).pop() == "M")
69+
70+
# students from OK, NM, TX
71+
s1 = (Student & [{"home_state": s} for s in ("OK", "NM", "TX")]).fetch(
72+
"KEY", order_by="student_id"
73+
)
74+
s2 = (Student & 'home_state in ("OK", "NM", "TX")').fetch(
75+
"KEY", order_by="student_id"
76+
)
77+
assert_true(len(s1) == 11)
78+
assert_list_equal(s1, s2)
79+
80+
millennials = Student & 'date_of_birth between "1981-01-01" and "1996-12-31"'
81+
assert_true(len(millennials) == 170)
82+
millennials_no_math = millennials - (Enroll & 'dept="MATH"')
83+
assert_true(len(millennials_no_math) == 53)
84+
85+
inactive_students = Student - (Enroll & CurrentTerm)
86+
assert_true(len(inactive_students) == 204)
87+
88+
# Females who are active or major in non-math
89+
special = Student & [Enroll, StudentMajor - {"dept": "MATH"}] & {"sex": "F"}
90+
assert_true(len(special) == 158)
91+
92+
93+
def test_advanced_join():
94+
"""test advanced joins"""
95+
# Students with ungraded courses in current term
96+
ungraded = Enroll * CurrentTerm - Grade
97+
assert_true(len(ungraded) == 34)
98+
99+
# add major
100+
major = StudentMajor.proj(..., major="dept")
101+
assert_true(len(ungraded.join(major, left=True)) == len(ungraded) == 34)
102+
assert_true(len(ungraded.join(major)) == len(ungraded & major) == 31)
103+
104+
105+
def test_union():
106+
# effective left join Enroll with Major
107+
q1 = (Enroll & "student_id=101") + (Enroll & "student_id=102")
108+
q2 = Enroll & "student_id in (101, 102)"
109+
assert_true(len(q1) == len(q2) == 41)
110+
111+
112+
def test_aggr():
113+
avg_grade_per_course = Course.aggr(
114+
Grade * LetterGrade, avg_grade="round(avg(points), 2)"
115+
)
116+
assert_true(len(avg_grade_per_course) == 45)
117+
118+
# GPA
119+
student_gpa = Student.aggr(
120+
Course * Grade * LetterGrade, gpa="round(sum(points*credits)/sum(credits), 2)"
121+
)
122+
gpa = student_gpa.fetch("gpa")
123+
assert_true(len(gpa) == 261)
124+
assert_true(2 < gpa.mean() < 3)
125+
126+
# Sections in biology department with zero students in them
127+
section = (Section & {"dept": "BIOL"}).aggr(
128+
Enroll, n="count(student_id)", keep_all_rows=True
129+
) & "n=0"
130+
assert_true(len(set(section.fetch("dept"))) == 1)
131+
assert_true(len(section) == 17)
132+
assert_true(bool(section))
133+
134+
# Test correct use of ellipses in a similar query
135+
section = (Section & {"dept": "BIOL"}).aggr(
136+
Grade, ..., n="count(student_id)", keep_all_rows=True
137+
) & "n>1"
138+
assert_false(
139+
any(
140+
name in section.heading.names for name in Grade.heading.secondary_attributes
141+
)
142+
)
143+
assert_true(len(set(section.fetch("dept"))) == 1)
144+
assert_true(len(section) == 168)
145+
assert_true(bool(section))

0 commit comments

Comments
 (0)