Skip to content

Instantly share code, notes, and snippets.

@Hamleyburger
Last active January 4, 2021 17:44
Show Gist options
  • Save Hamleyburger/8491dd8f8b3e826491310f64f422f10b to your computer and use it in GitHub Desktop.
Save Hamleyburger/8491dd8f8b3e826491310f64f422f10b to your computer and use it in GitHub Desktop.
Solution for pset7 houses, CS50 2020
import sqlite3
import csv
import sys
def main():
# checking argv (that there's one and it's a csv)
if (len(sys.argv) != 2):
sys.exit("Usage: import.py file.csv")
filename = sys.argv[1]
if not (filename.endswith(".csv")):
sys.exit("You must provide a *.csv")
# Connect with the .db file and make a cursor
sqlite_file = "students.db"
con = sqlite3.connect(sqlite_file)
cur = con.cursor()
# Open the csv file to import from
with open(filename, "r") as characters:
# Make a dictionary reader that iterates through rows
reader = csv.DictReader(characters)
for row in reader:
names = []
for part in row["name"].split(" "):
names.append(part)
names.append(row["house"])
names.append(row["birth"])
if (len(names) == 5):
cur.execute("INSERT INTO students (first, middle, last, house, birth) VALUES(?, ?, ?, ?, ?)", names[:5])
if (len(names) == 4):
cur.execute("INSERT INTO students (first, last, house, birth) VALUES(?, ?, ?, ?)", names[:4])
con.commit()
con.close()
if __name__ == "__main__":
main()
import sqlite3
import csv
import sys
def main():
# checking argv (needs to be one, house name)
if (len(sys.argv) != 2):
sys.exit("Usage: roster.py house_name")
# Make house name lower to avoid cap sensitivity
housename = sys.argv[1].lower()
# Check if argument is indeed a house at Hogwarts
houses = ["slytherin", "gryffindor", "ravenclaw", "hufflepuff"]
if housename.lower() not in houses:
sys.exit("provide house name: Gryffindor, Hufflepuff, Slytherin or Ravenclaw.")
# Connect with the .db file and make a cursor
sqlite_file = "students.db"
con = sqlite3.connect(sqlite_file)
cur = con.cursor()
cur.execute('SELECT first, middle, last, birth FROM students WHERE lower(house) = "{}" ORDER BY last, first;'.format(housename))
# Fetchall gives us all the rows of the table as a list of tuples with strings.
houseroster = cur.fetchall()
# Do stuff with each row in table
for row in houseroster:
if not row[1]:
print("{} {}, born {}".format(row[0], row[2], row[3]))
else:
print("{} {} {}, born {}".format(row[0], row[1], row[2], row[3]))
con.close()
if __name__ == "__main__":
main()
@mrstoastedsnowman
Copy link

No problem - I spent hours agonising over this problem, so I feel your pain!

Yes, absolutely, the input file that you will have as part of the Pset is characters.csv, so when you test the code yourself, that's the filename you'll need to use in import.py.

Then, just before you submit it via check50, change the input filename in import.py to students.csv, and it should pass check50.

Messy, but in the absence of being able to use the second command line argument as the input file (which I just couldn't get to work), it works.

Does that help?

@lamzyyabdulk
Copy link

lamzyyabdulk commented Dec 19, 2020 via email

@mrstoastedsnowman
Copy link

Not sure if we're allowed to post code, but I can tell you what I did:

with open("students.csv", "r") as data:

Then used csv.DictReader to read the data into a dictionary

Then iterated over each row in the dictionary, assigning the values from the dictionary to variables for name, house and year of birth (I used a function called split to separate the first, last and middle names into 3 separate values in a list)

Lastly, I wrote an if/else conditional that checked whether the length of the the names list was 2 or 3, and used an appropriate INSERT statement in either case to insert a new row into the table, referencing the variables listed above, but inserting None if the student has no middle name.

@ShyaamCR
Copy link

Pretty neat coding btw 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment