initial commit

master
Bill Sun 6 months ago
commit ccd4dc6f50

@ -0,0 +1,26 @@
# You can change these variables to use a different base image, but
# you must ensure that your base image inherits from one of ours.
# You can also override these at build time with --build-arg flags
ARG BASE_REPO=gradescope/autograder-base
ARG TAG=latest
FROM ${BASE_REPO}:${TAG}
ADD source /autograder/source
RUN cp /autograder/source/run_autograder /autograder/run_autograder
# Ensure that scripts are Unix-friendly and executable
RUN dos2unix /autograder/run_autograder /autograder/source/setup.sh
RUN chmod +x /autograder/run_autograder
# Do whatever setup was needed in setup.sh, including installing apt packages
# Cleans up the apt cache afterwards in the same step to keep the image small
RUN apt-get update && \
bash /autograder/source/setup.sh && \
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# You can also use RUN commands in the Dockerfile to install things
# instead of using a bash script
# The base image defines the CMD and ENTRYPOINT, so don't redefine those

@ -0,0 +1 @@
{"output": "", "score": 3, "max_score": 8}

@ -0,0 +1,59 @@
import pymongo, json
# dbprep
fsroot = '/autograder/source/'
datasets = ['congress', 'bills']
db = pymongo.MongoClient('mongodb://127.0.0.1')['test']
def evaluate(query : str):
import re
query = re.sub(r'(\$?[\d\w]+)\s*:', r'"\1" :', query)
query = re.sub(r'[\r|\n]|.\s*pretty\s*\(\s*\)', '', query).strip()
return list(eval(query))[0] if query else None
for d in datasets:
with open(fsroot + d + '.json', encoding = 'utf-8') as f:
db[d].insert_many(json.load(f))
from solution import sols
answers = [evaluate(s) for s in sols]
# grading
from os import listdir
from importlib.util import module_from_spec, spec_from_file_location
subroot = '/autograder/submission/'
feedback = ''
submissions = [subroot + f for f in listdir(subroot) if f.strip().lower().endswith('.py')]
grade = 0
n_queries = len(sols)
if submissions:
submission = submissions[0]
for i in range(n_queries):
feedback += f'Query {i + 1}: '
try:
spec = spec_from_file_location('curr', submission)
module = module_from_spec(spec)
spec.loader.exec_module(module)
q = getattr(module, f'query{i + 1}')()
if evaluate(q) == answers[i]:
grade += 1
feedback += 'Correct.\n'
else:
feedback += 'Wrong Answer.\n'
except Exception:
feedback += 'Runtime Error.\n'
else:
feedback += 'No python file in submission.\n'
# output
results = {
'output': feedback,
'score': grade * 100 / n_queries,
'max_score': 100,
}
with open('/autograder/results/results.json', 'w') as res:
json.dump(results, res)

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -0,0 +1,20 @@
#!/usr/bin/env bash
mkdir -p /autograder/results/
cd /data
mongod > /dev/null 2>&1 &
cd -
python3 /autograder/source/autograder.py
# files_submitted=$(ls /autograder/submission)
# num_files_submitted=$(ls /autograder/submission/ | wc -l)
# cat > /autograder/results/results.json <<EOF
# {
# "output": "Good job, you passed! Submitted ${num_files_submitted} files: ${files_submitted}",
# "score": 10,
# "max_score": 10
# }
# EOF

@ -0,0 +1,10 @@
apt install -y curl python3 python3-pip
curl -fsSL https://pgp.mongodb.com/server-7.0.asc | gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
export OS_VER=`cat /etc/os-release | grep VERSION_CODENAME` &&\
export OS_VER=${OS_VER#*=} &&\
printf "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu "${OS_VER}"/mongodb-org/7.0 multiverse\n">/etc/apt/sources.list.d/mongodb.list
apt update
apt install -y mongodb-org
mkdir -p /data/db
cd /data
python3 -m pip install pymongo

@ -0,0 +1,47 @@
sols = ['db.bills.find({sponsor_name:"Marco Rubio"}, {_id:0, title: 1, sponsor_name:1, sponsor_state:1})',
'db.bills.find({cosponsors:{$gte:3, $lte:5}}, {_id:0, title:1, sponsor_name:1, cosponsors:1})',
'db.bills.find({$or:[{cosponsors:{$gte:3, $lte:5}}, {sponsor_name:"Marco Rubio"}]}, {_id:0, title:1, sponsor_name:1, cosponsors:1})',
'''db.congress.aggregate([
{ $match: {"state": "IN"} },
{ $group: {_id: "$role_type", count_of_this_role: {$sum:1} } },
{ $sort: {count_of_this_role: -1} },
{ $project: {_id: 1, count_of_this_role: 1} }
])''',
'''db.bills.aggregate([
{ $lookup: {
from: "congress",
localField: "sponsor_id",
foreignField: "person.bioguideid",
as:"congressMember"} },
{ $unwind: "$congressMember" },
{ $project: {_id: 0, title:1, sponsor_name: 1, "description": "$congressMember.description", "DOB": "$congressMember.person.birthday"} }
])''',
'''db.bills.aggregate([
{ $unwind: "$committee_codes" },
{ $project: {committee_codes: 1} },
{ $group: {_id: "$committee_codes", countOfCommittee: {$sum:1} } },
{ $sort: {countOfCommittee: -1} },
])''',
'''db.bills.aggregate([
{ $project: {_id: 1, title:1, sponsor_name: 1, sponsor_state:1}},
{ $lookup: {
from: "bills",
localField: "sponsor_state",
foreignField: "sponsor_state",
as:"otherBills"} },
{ $unwind: "$otherBills" },
{ $project: {title: 1, sponsor_name: 1, sponsor_state: 1, otherbill_id: "$otherBills._id", otherbill_title: "$otherBills.title", otherbill_sponser_name: "$otherBills.sponsor_name", otherbill_sponsor_state: "$otherBills.sponsor_state"}},
{ $match: {$expr: {$lt: ["$_id", "$otherbill_id"]}}}
])''',
'''db.congress.aggregate([
{ $project: {_id: 1, firstname: "$person.firstname", lastname: "$person.lastname", state: 1}},
{ $lookup: {
from: "congress",
localField: "lastname",
foreignField: "person.lastname",
as:"otherPersons"} },
{ $unwind: "$otherPersons" },
{ $match: {$expr: {$lt: ["$_id", "$otherPersons._id"]}}},
{ $project: {_id:1, firstname: 1, lastname: 1, state:1, otherPerson_id: "$otherPersons._id", otherPerson_firstname: "$otherPersons.person.firstname", otherPerson_lastname: "$otherPersons.person.lastname", otherPerson_state: "$otherPersons.state"}},
{ $match: {$expr: {$eq: ["$state", "$otherPerson_state"]}}},
])''']

@ -0,0 +1,26 @@
# You can change these variables to use a different base image, but
# you must ensure that your base image inherits from one of ours.
# You can also override these at build time with --build-arg flags
ARG BASE_REPO=gradescope/autograder-base
ARG TAG=latest
FROM ${BASE_REPO}:${TAG}
ADD source /autograder/source
RUN cp /autograder/source/run_autograder /autograder/run_autograder
# Ensure that scripts are Unix-friendly and executable
RUN dos2unix /autograder/run_autograder /autograder/source/setup.sh
RUN chmod +x /autograder/run_autograder
# Do whatever setup was needed in setup.sh, including installing apt packages
# Cleans up the apt cache afterwards in the same step to keep the image small
RUN apt-get update && \
bash /autograder/source/setup.sh && \
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# You can also use RUN commands in the Dockerfile to install things
# instead of using a bash script
# The base image defines the CMD and ENTRYPOINT, so don't redefine those

@ -0,0 +1 @@
docker build -t sunyinqi0508/neo4j_autograder . && docker push sunyinqi0508/neo4j_autograder

@ -0,0 +1,47 @@
CREATE
(gorman:Author {name:"Gorman, Michael"}),
(toner:Author {name:"Toner, Patrick"}),
(koslicki:Author {name:"Koslicki, Kathrin"}),
(fine:Author {name:"Fine, Kit"}),
(roger:Author {name:"Roger, Cat"}),
(beth:Author {name:"Beth, Dog"}),
(art1:Article {doi:"10.5840/ipq20064626", title:"Independence and Substance"}),
(art2:Article {doi:"10.1007/s11098-010-9521-4", title:"Independence Accounts of Substance and Substantial Parts"}),
(art3:Article {doi:"10.1007/s11098-011-9708-3", title:"On Substantial Independence: a Reply to Patrick Toner"}),
(art4:Article {doi:"10.1080/05568640609485174", title:"Substance and Identity-Dependence"}),
(art5:Article {doi:"10.2307/4545221", title:"Ontological Dependence"}),
(art6:Article {doi:"10.2307/4519752", title:"Yet Another Title"}),
(art7:Article {doi:"10.2308/4547590", title:"Seventh Title"}),
(chp1:Chapter {no:9, title:"Substance, Independence, and Unity"}),
(chp2:Chapter {no:10, title:"Chapter on Making Chapters"}),
(ipq:Journal {title:"International Philosophical Quarterly", ISSN:"0019-0365", onlineISSN:"2153-8077"}),
(ps:Journal {title:"Philosophical Studies", ISSN:"0031-8116", onlineISSN:"1573-0883"}),
(pp:Journal {title:"Philosophical Papers", ISSN:"0556-8641", onlineISSN:"1996-8523"}),
(pas:Journal {title:"Proceedings of the Aristotelian Society", ISSN:"0066-7374", onlineISSN:"1467-9264"}),
(hitm:Journal {title:"History in the making", ISSN:"0084-7649", onlineISSN:"1235-7549"}),
(ssj:Journal {title:"Something Something Journal", ISSN:"0420-6729", onlineISSN:"5964-3248"}),
(gorman)-[:WRITES]->(art1)-[:IN {pp:[147,159]} ]->(:Issue {volume:46, issue:2, year:2006, month:6})-[:OF]->(ipq),
(toner)-[:WRITES]->(art2)-[:IN {pp:[37,43]} ]->(:Issue {volume:155, issue:1, year:2011, month:8})-[:OF]->(ps),
(gorman)-[:WRITES]->(art3)-[:IN {pp:[239,297]} ]->(:Issue {volume:159, issue:2, year:2012, month:6})-[:OF]->(ps),
(gorman)-[:WRITES]->(art4)-[:IN {pp:[103,118]} ]->(:Issue {volume:35, issue:1, year:2006, month:3})-[:OF]->(pp),
(fine)-[:WRITES]->(art5)-[:IN {pp:[269,290]} ]->(:Issue {volume:95, year:1995})-[:OF]->(pas),
(roger)-[:WRITES]->(art6)-[:IN {pp:[206,300]} ]->(:Issue {volume:24, year:1996})-[:OF]->(hitm),
(beth)-[:WRITES]->(art7)-[:IN {pp:[0,5]} ]->(:Issue {volume:32, year:1903})-[:OF]->(ssj),
(koslicki)-[:WRITES]->(chp1)-[:IN {pp:[169,195]} ]->(book:Book {title:"Aristotle on Method and Metaphysics", `ISBN-10`:"0230360912", `ISBN-13`:"978-0230360914", year:2013, month:7})<-[:EDITS]-(feser:Author {name:"Feser, Edward"}),
(beth)-[:WRITES]->(chp2)-[:IN {pp:[104,109]} ]->(book2:Book {title:"Book Name is Two", `ISBN-10`:"023546382", `ISBN-13`:"978-0230346584", year:2003, month:9})<-[:EDITS]-(tim:Author {name:"Tim, Bob"}),
(book)<-[:PUBLISHED_BY]-(pub:Publisher {location:"London", name:"Palgrave Macmillan"}),
(book2)<-[:PUBLISHED_BY]-(pub2:Publisher {location:"Madagascar", name:"Alex Lion"}),
(art1)-[:CITES]->(art5),
(art2)-[:CITES]->(art1),
(art2)-[:CITES]->(art4),
(art3)-[:CITES]->(art2),
(art3)-[:CITES]->(art4),
(art5)-[:CITES]->(art6),
(art7)-[:CITES]->(art3),
(art6)-[:CITES]->(art1),
(chp1)-[:CITES]->(art1),
(chp1)-[:CITES]->(art2),
(chp2)-[:CITES]->(art3),
(chp1)-[:CITES]->(art6),
(chp2)-[:CITES]->(art7),
(chp1)-[:CITES]->(art3)

@ -0,0 +1,70 @@
import neo4j, json
# dbprep
fsroot = '/autograder/source/'
datasets = ['Neo4J_dataset']
db = neo4j.GraphDatabase.driver('bolt://localhost:7687', auth = ('neo4j', '4Sfz541Lm')).session()
def evaluate(query : str):
query = query.strip()
return db.run(query).data() if query else None
while True:
try:
db.run('RETURN 0')
break
except:
continue
for d in datasets:
with open(fsroot + d + '.txt', encoding = 'utf-8') as f:
db.run(f.read())
from solution import sols
answers = [evaluate(s) if type(s) is str else tuple(evaluate(k) for k in s) for s in sols ]
# grading
from os import listdir
from importlib.util import module_from_spec, spec_from_file_location
subroot = '/autograder/submission/'
feedback = ''
submissions = [subroot + f for f in listdir(subroot) if f.strip().lower().endswith('.py')]
grade = 0
n_queries = len(sols)
if submissions:
submission = submissions[0]
for i in range(n_queries):
feedback += f'Query {i + 1}: '
try:
spec = spec_from_file_location('curr', submission)
module = module_from_spec(spec)
spec.loader.exec_module(module)
q = getattr(module, f'query{i + 1}')()
def eq(a: list, b):
if a is None: return False
if type(b) is tuple:
return any(eq(a, bb) for bb in b)
if len(a) != len(b): return False
return all(aa == bb for aa, bb in zip(a, b))
if eq(evaluate(q), answers[i]):
grade += 1
feedback += 'Correct.\n'
else:
feedback += 'Wrong Answer.\n'
except Exception:
feedback += 'Runtime Error.\n'
else:
feedback += 'No python file in submission.\n'
# output
results = {
'output': feedback,
'score': round(grade * 100 / n_queries, 1),
'max_score': 100,
}
with open('/autograder/results/results.json', 'w') as res:
json.dump(results, res)

@ -0,0 +1,18 @@
#!/usr/bin/env bash
mkdir -p /autograder/results/
service neo4j start
python3 /autograder/source/autograder.py
# files_submitted=$(ls /autograder/submission)
# num_files_submitted=$(ls /autograder/submission/ | wc -l)
# cat > /autograder/results/results.json <<EOF
# {
# "output": "Good job, you passed! Submitted ${num_files_submitted} files: ${files_submitted}",
# "score": 10,
# "max_score": 10
# }
# EOF

@ -0,0 +1,10 @@
apt install -y curl python3 python3-pip
curl -fsSL https://debian.neo4j.com/neotechnology.gpg.key | gpg --dearmor -o /usr/share/keyrings/neo4j.gpg
echo "deb [signed-by=/usr/share/keyrings/neo4j.gpg] https://debian.neo4j.com stable latest" > /etc/apt/sources.list.d/neo4j.list
apt update
apt install -y neo4j
sed -i '1s/^/server.default_listen_address=0.0.0.0\n/' /etc/neo4j/neo4j.conf
systemctl enable --now neo4j
neo4j-admin dbms set-initial-password 4Sfz541Lm --require-password-change=false
python3 -m pip install neo4j

@ -0,0 +1,73 @@
sols = [
'''
MATCH (author:Author)-[:WRITES]->(article:Article)
RETURN author.name, article.title
''',
('''
match (author:Author)-[:WRITES]->(paper_or_chapter)
return author.name, paper_or_chapter.title, labels(paper_or_chapter)
''',
'''
MATCH (author:Author)-[:WRITES]->(paper_or_chapter)
WITH author, paper_or_chapter, labels(paper_or_chapter) as publicationType
WHERE publicationType=["Article"] or publicationType=["Chapter"]
RETURN author.name, paper_or_chapter.title, publicationType
'''),
('''
match (author:Author)-[:WRITES|EDITS]->(publication)
return author.name, publication.title, labels(publication)
''',
'''
MATCH (author:Author)-[]->(publication)
WHERE publication:Article or publication:Chapter or publication:Book
RETURN author.name, publication.title, labels(publication)
'''),
('''
match (author:Author)-[:WRITES|EDITS]->(publication)
return author.name, count(publication) as publication_count
''',
'''
MATCH (author:Author)-[]->(publication)
WHERE publication:Article OR publication:Chapter or publication:Book
RETURN author.name, count(publication) as publication_count
'''),
('''
match(a:Article)-[in:IN]->(:Issue)
where (in.pp[1] - in.pp[0]) <= 10
return a.title, (in.pp[1] - in.pp[0] + 1) as NumberOfPages
''',
'''
MATCH (a:Article)-[e:IN]->(:Issue)
WITH a, e.pp[1]-e.pp[0]+1 as NumberOfPages
WHERE NumberOfPages <=10
RETURN a.title, NumberOfPages
'''),
'''
MATCH (p2:Article)<-[]-(a1:Author)-[]->(p1:Article),(p1)-[:CITES]->(p2)
RETURN a1.name, p1.title, p2.title
''',
'''
MATCH (publication)<-[:CITES]-()
WITH publication, count(*) as publication_count
WHERE (publication:Article or publication:Chapter) and publication_count >= 2
RETURN publication.title, publication_count
''',
('''
match (journal:Journal)<-[:OF]-(issue:Issue)<-[:IN]-(article:Article)<-[:CITES]-(someOtherPublication)
with journal, article, count(someOtherPublication) as citations_count
where citations_count > 1
match (article)<-[:WRITES]-(author:Author)
return journal.title, article.title, citations_count, author.name
''',
'''
MATCH (author:Author)-[:WRITES]->(article:Article)-[:IN]->()-[]->(journal:Journal), ()-[e:CITES]->(article:Article)
WITH journal, article, author, count(e) as citation_count
WHERE citation_count >= 2
RETURN journal.title, article.title, citation_count, author.name
'''),
'''
MATCH (a1:Article)-[:IN]->(i1:Issue)-[]->(:Journal)<-[]-(i2:Issue)<-[]-(a2:Article)
WHERE (a1)-[:CITES]->(a2)
RETURN a1.title, i1.issue, a2.title, i2.issue
'''
]
Loading…
Cancel
Save