Skip to content

Commit 9286e29

Browse files
shwehtom89bmcutler
authored andcommitted
[Feature:Autograding] Adds autograding example for database query gradeables (#26)
* added example database assignment * fixed gradeable structure * fixed gradeable structure * makes requested changes * update config
1 parent 61c880c commit 9286e29

File tree

10 files changed

+313
-0
lines changed

10 files changed

+313
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"resource_limits": {
3+
"RLIMIT_CPU": 180
4+
},
5+
"autograding_method": "docker",
6+
"container_options": {
7+
"use_router": false
8+
},
9+
"autograding": {
10+
"submission_to_runner": ["**/*.py", "**/*.txt","**/*.sql"],
11+
"work_to_details": ["**/*.txt"]
12+
},
13+
"testcases": [
14+
{
15+
"title": "Queries",
16+
"points": 15,
17+
"validation": [
18+
{
19+
"method": "diff",
20+
"description": "One",
21+
"deduction": 0.33,
22+
"actual_file": "main/1-result.txt",
23+
"expected_file": "1-expected.txt"
24+
},
25+
{
26+
"method": "diff",
27+
"description": "Two",
28+
"deduction": 0.33,
29+
"actual_file": "main/2-result.txt",
30+
"expected_file": "2-expected.txt"
31+
},
32+
{
33+
"method": "diff",
34+
"description": "Three",
35+
"deduction": 0.33,
36+
"actual_file": "main/3-result.txt",
37+
"expected_file": "3-expected.txt"
38+
}
39+
],
40+
"containers": [
41+
{
42+
"server": true,
43+
"container_name": "db_example_postgres",
44+
"container_image": "submitty/tutorial:tutorial_18"
45+
},
46+
{
47+
"container_name": "main",
48+
"container_image" : "submitty/tutorial:database_client",
49+
"commands": ["python3 sql_runner.py"]
50+
}
51+
]
52+
}
53+
]
54+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import psycopg2
2+
import psycopg2.extras
3+
import csv
4+
import sys
5+
import time
6+
import re
7+
from timeit import default_timer as timer
8+
9+
conn_string = "host='db_example_postgres' dbname='contributors' user='contributors_reader' password='contributors_reader'"
10+
11+
def err(message):
12+
print(message, file=sys.stderr)
13+
14+
def log_error(message):
15+
with open('connection_errors.txt', 'a') as log_file:
16+
log_file.write(message)
17+
log_file.write('\n')
18+
19+
def log_query_metrics(message):
20+
with open('query_metrics.txt', 'a') as log_file:
21+
log_file.write(message + '\n')
22+
23+
def get_connection():
24+
count = 0
25+
conn = None
26+
t = timer()
27+
while not conn and count < 120:
28+
count += 1
29+
try:
30+
conn = psycopg2.connect(conn_string)
31+
except psycopg2.OperationalError as op_error:
32+
time.sleep(0.25)
33+
34+
if conn:
35+
elapsed = timer() - t
36+
log_query_metrics(f"Connection established after {elapsed:.3f} seconds")
37+
else:
38+
err("Could not establish connection")
39+
return conn
40+
41+
def get_cursor(conn):
42+
t = timer()
43+
cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
44+
log_query_metrics(f"Cursor get in {(timer() - t):.3f} seconds")
45+
return cursor
46+
47+
48+
def run_query(cursor, query):
49+
cursor.execute(query)
50+
records = cursor.fetchall()
51+
return records
52+
53+
def run_cost(cursor, query):
54+
cost_query = "EXPLAIN ANALYZE " + query
55+
cursor.execute(cost_query)
56+
records = cursor.fetchone()
57+
if len(records) == 0:
58+
return 0
59+
cost = re.search('(cost=)([0-9]+.\d\d)', records[0])
60+
time = re.search('(time=)([0-9]+.\d\d\d)', records[0])
61+
return float(cost[2]), float(time[2])
62+
63+
64+
def load_query(path):
65+
with open(path, 'r') as query_file:
66+
contents = query_file.readlines()
67+
lines = map(lambda bytes: str(bytes), contents)
68+
no_comments = filter(lambda line: not line.lstrip().startswith('--'), lines)
69+
no_bom = list(map(lambda line: line.replace('\xef\xbb\xbf', ''), no_comments))
70+
joined = ''.join(no_bom)
71+
split = joined.split(';')
72+
return split[0]
73+
74+
def main():
75+
conn = get_connection()
76+
if conn == None:
77+
err('Connection failed')
78+
return
79+
curr = get_cursor(conn)
80+
for num in range(1, 4):
81+
try:
82+
input_file = str(num) + ".sql"
83+
output_file = str(num) + "-result.txt"
84+
85+
query = load_query(input_file)
86+
result = run_query(curr, query)
87+
cost, time = run_cost(curr, query)
88+
log_query_metrics(f"Query {num:d} run in {time:.3f} sec with cost {cost:.2f}")
89+
90+
with open(output_file, 'w', newline='', encoding='utf-8') as result_file:
91+
writer = csv.writer(result_file, lineterminator='\n')
92+
writer.writerow([attr for attr in result[0].keys()])
93+
for t in result:
94+
writer.writerow(t)
95+
except:
96+
err("Solution for %d raised exception %s" % (num, sys.exc_info()))
97+
98+
99+
if __name__ == '__main__':
100+
main()
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
firstname,lastname,startyear
2+
Evan,Maicus,2016
3+
Ana,Milanova,2016
4+
Jeramey,Tyler,2016
5+
Garrett,Chang,2016
6+
Robert,Patterson,2016
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
count
2+
36
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
contributor,tenure
2+
Samuel Breese,4
3+
Brandon Drumheller,4
4+
Timothy Cyrus,2
5+
Elizabeth Dinella,2
6+
Justin LaPre,2
7+
Gagan Kumar,1
8+
Rylan O'Connell,1
9+
John (Jack) Hulton,1
10+
Alex Belsten,1
11+
Richard Collins,1
12+
Jared Okun,1
13+
Salles Viana Gomes de Magalhaes,1
14+
Victor Nazzaro,1
15+
Joanna Ng,1
16+
Nick Roper,1
17+
Tushar Gurjar,1
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
FROM postgres:12
2+
3+
COPY ./setup-contrib.sql /docker-entrypoint-initdb.d/1-setup.sql
4+
COPY ./contributors.sql /docker-entrypoint-initdb.d/2-data.sql
5+
COPY ./setup-users.sql /docker-entrypoint-initdb.d/3-users.sql
6+
7+
RUN apt-get update \
8+
&& apt-get -y --no-install-recommends install \
9+
grep \
10+
libseccomp-dev \
11+
libseccomp2 \
12+
procps \
13+
&& rm -rf /var/lib/apt/lists/*
14+
15+
RUN apt-get update \
16+
&& apt-get install -y --no-install-recommends wget gnupg \
17+
&& echo "deb http://apt.llvm.org/buster/ llvm-toolchain-buster-7 main" >> /etc/apt/sources.list \
18+
&& echo "deb-src http://apt.llvm.org/buster/ llvm-toolchain-buster-7 main" >> /etc/apt/sources.list \
19+
&& wget -O - http://apt.llvm.org/llvm-snapshot.gpg.key|apt-key add - \
20+
&& apt-get update \
21+
&& apt-get -y --no-install-recommends install \
22+
clang-7 \
23+
&& apt-get purge -y --auto-remove wget gnupg \
24+
&& rm -rf /var/lib/apt/lists/* \
25+
&& ln -s /usr/bin/clang-7 /usr/bin/clang \
26+
&& ln -s /usr/bin/clang++-7 /usr/bin/clang++
27+
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
-- CREATE DATABASE contributors WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8';
2+
3+
4+
ALTER DATABASE contributors OWNER TO contributors;
5+
6+
\connect contributors
7+
8+
9+
CREATE TABLE contributors(
10+
userid bigint,
11+
firstname character varying(255),
12+
lastname character varying(255),
13+
startyear bigint,
14+
endyear bigint,
15+
role character varying(255),
16+
PRIMARY KEY(firstname, lastname)
17+
);
18+
19+
ALTER TABLE contributors OWNER TO contributors;
20+
21+
INSERT INTO contributors (userid, firstname, lastname, startyear, endyear, role)
22+
VALUES
23+
(1, 'Barbara', 'Cutler', 2014, NULL, 'Project Manager'),
24+
(2, 'Matthew', 'Peveler', 2014, NULL, 'Project Manager'),
25+
(3, 'Evan', 'Maicus', 2016, NULL, 'Project Manager'),
26+
(4, 'Eli', 'Schiff', 2019, NULL, 'Developer'),
27+
(5, 'Ben', 'Kelly', 2019, NULL, 'Developer'),
28+
(6, 'Saketh', 'Dargula', 2019, NULL, 'Developer'),
29+
(7, 'Kevin', 'McKinney', 2019, NULL, 'Developer'),
30+
(8, 'Jacob', 'McKnight', 2019, NULL, 'Developer'),
31+
(9, 'Alexa', 'Orosz', 2019, NULL, 'Developer'),
32+
(10, 'Maya', 'Tung', 2019, NULL, 'Developer'),
33+
(11, 'Xiao', 'Han,', 2019, NULL, 'Developer'),
34+
(12, 'Fon', 'Noel,', 2019, NULL, 'Developer'),
35+
(13, 'Drumil', 'Patil,', 2019, NULL, 'Developer'),
36+
(14, 'Anubhav', 'Singh,', 2019, NULL, 'Developer'),
37+
(15, 'Preston', 'Carman', 2019, NULL, 'Developer'),
38+
(16, 'Matthew', 'Garber', 2019, NULL, 'Developer'),
39+
(17, 'Matthew', 'Raneri', 2019, NULL, 'Developer'),
40+
(18, 'Thomas', 'Shweh', 2019, NULL, 'Developer'),
41+
(19, 'Kasra', 'Sheik', 2018, 2019, 'Developer'),
42+
(20, 'Ryan', 'Waddell', 2018, 2019, 'Developer'),
43+
(21, 'Victor', 'Li', 2018, 2019, 'Developer'),
44+
(22, 'Eric', 'Tran', 2018, NULL, 'Developer'),
45+
(23, 'Kevin', 'Mackenzie', 2018, NULL, 'Developer'),
46+
(24, 'Glenn', 'Smith', 2018, NULL, 'Developer'),
47+
(25, 'Andrew', 'Aikens', 2017, NULL, 'Developer'),
48+
(26, 'Shail', 'Patel', 2018, NULL, 'Developer'),
49+
(27, 'Leon', 'Montealegre', 2017, NULL, 'Developer'),
50+
(28, 'Buster', 'Holzbauer', 2017, NULL, 'Developer'),
51+
(29, 'Ana', 'Milanova', 2016, NULL, 'Developer'),
52+
(30, 'Steven', 'Lindsey', 2014, NULL, 'Developer'),
53+
(31, 'Peter', 'Bailie', 2014, NULL, 'Developer'),
54+
(32, 'David', 'Goldschmidt', 2014, NULL, 'Developer'),
55+
(33, 'Konstantin', 'Kuzmin', 2018, NULL, 'Developer'),
56+
(34, 'John (Jack)', 'Hulton', 2018, 2018, 'Developer'),
57+
(35, 'Victor', 'Nazzaro', 2018, 2018, 'Developer'),
58+
(36, 'Joanna', 'Ng', 2018, 2018, 'Developer'),
59+
(37, 'Nick', 'Roper', 2018, 2018, 'Developer'),
60+
(38, 'Tushar', 'Gurjar', 2018, 2018, 'Developer'),
61+
(39, 'Gagan', 'Kumar', 2018, 2018, 'Developer'),
62+
(40, 'Timothy', 'Cyrus', 2017, 2018, 'Developer'),
63+
(41, 'Rylan', 'O''Connell', 2018, 2018, 'Developer'),
64+
(42, 'Salles', 'Viana Gomes de Magalhaes', 2018, 2018, 'Developer'),
65+
(43, 'Alex', 'Belsten', 2018, 2018, 'Developer'),
66+
(44, 'Richard', 'Collins', 2018, 2018, 'Developer'),
67+
(45, 'Jared', 'Okun', 2018, 2018, 'Developer'),
68+
(46, 'Elizabeth', 'Dinella', 2017, 2018, 'Developer'),
69+
(47, 'Justin', 'LaPre', 2017, 2018, 'Developer'),
70+
(48, 'Samuel', 'Breese', 2015, 2018, 'Developer'),
71+
(49, 'Brandon', 'Drumheller', 2015, 2018, 'Developer'),
72+
(50, 'Marisa', 'Lee', 2017, 2017, 'Developer'),
73+
(51, 'Jessica', 'Wang', 2017, 2017, 'Developer'),
74+
(52, 'James', 'Anderson', 2017, 2017, 'Developer'),
75+
(53, 'Joshua', 'Barthlemess', 2017, 2017, 'Developer'),
76+
(54, 'Andrew', 'Ma', 2017, 2017, 'Developer'),
77+
(55, 'Jason', 'Parham', 2014, 2017, 'Developer'),
78+
(56, 'Jeramey', 'Tyler', 2016, 2017, 'Developer'),
79+
(57, 'Zishan', 'Huang', 2015, 2016, 'Developer'),
80+
(58, 'Garrett', 'Chang', 2016, 2016, 'Developer'),
81+
(59, 'Robert', 'Patterson', 2016, 2016, 'Developer'),
82+
(60, 'Andrea', 'Wong', 2015, 2016, 'Developer'),
83+
(61, 'Melissa', 'Lindquist', 2015, 2016, 'Developer'),
84+
(62, 'Beverly', 'Sihsobhon', 2015, 2016, 'Developer'),
85+
(63, 'Marina', 'Espinoza', 2015, 2015, 'Developer'),
86+
(64, 'Chris', 'Berger', 2014, 2014, 'Developer'),
87+
(65, 'Seema', 'Bhaskar', 2014, 2014, 'Developer'),
88+
(66, 'Stanley', 'Cheung', 2014, 2014, 'Developer'),
89+
(67, 'Jesse', 'Freitas', 2014, 2014, 'Developer'),
90+
(68, 'Severin', 'Ibarluzea', 2014, 2014, 'Developer'),
91+
(69, 'Kiana', 'McNellis', 2014, 2014, 'Developer'),
92+
(70, 'Kienan', 'Knight-Boehm', 2014, 2014, 'Developer'),
93+
(71, 'Tyler', 'Shepard', 2014, 2014, 'Developer'),
94+
(72, 'Sam', 'Seng', 2014, 2014, 'Developer'),
95+
(73, 'Victor', 'Zhu', 2014, 2014, 'Developer'),
96+
(74, 'Andrew', 'Fasano', NULL, NULL, 'Security'),
97+
(75, 'Markus', 'Gaasedelen', NULL, NULL, 'Security'),
98+
(76, 'Amy', 'Burnett', NULL, NULL, 'Security'),
99+
(77, 'Aidan', 'Noll', NULL, NULL, 'Security'),
100+
(78, 'Toshi', 'Piazza', NULL, NULL, 'Security'),
101+
(79, 'Zachary', 'Wimer', NULL, NULL, 'Security');
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CREATE USER contributors WITH PASSWORD 'contributors';
2+
CREATE DATABASE contributors;
3+
GRANT ALL PRIVILEGES ON DATABASE contributors TO contributors;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CREATE USER contributors_reader WITH PASSWORD 'contributors_reader';
2+
\connect contributors
3+
GRANT SELECT ON ALL TABLES IN SCHEMA public TO contributors_reader;
Binary file not shown.

0 commit comments

Comments
 (0)