I'm making a program where people, by giving their info (education, field of study, higher degree achieved etc.) are given a score. I'm using sqlite3 and Python 2.7
To do so, I have a DB in which each city and province is listed with the percentage of people education's highest degree. I have made one table for each province:
DB:
table: province_1
cities| no certificate| high school diploma| Apprenticeship| bachelor| etc..
city1 : 5 | 15 | 8 | 20 | ...
city2 : 15 | 12 | 35 | 10 | ...
city3 : 1 | 35 | 3 | 8 | ...
And then I have my function. In it, what I'd like to do is calculate the percentage of people with a lower and equal education / people with higher education.
Example: if user1 is from city2 and has an apprenticeship degree it would result as 62 / 38 = 1.63
This is what I have got until now, but as you can see, it is a massive flop:
def edu_score(education, fos, province, city):
edu_lvl = ['No_certificate', 'high_school_diploma', 'Apprenticeship', 'CEGEP', 'Bachelor Diploma', 'Master Diploma', 'Doctorate']
score = 0
crsr.execute("SELECT (SUM([edu_lvl.index(ed):: -1]) / (SUM ([edu_lvl.index(ed)::])) FROM province_1 WHERE cities = city")
score = crsr.fetchone()
print score
How do I calculate it? and how do I do so that the user's input is not taken as a string, which returns that same string value in the db?
Thank you so much, and I hope I was clear enough.
First you should merge your tables into one, and add a column called provinces. There is a strong reason for that. You do not want any user input field being called as a table name since you can't easily tokenize it (avoid sql injection).
Second you are merging python code with a SQL statement, so that will never work.
What you need is something like this:
def edu_score(education, fos, province, city):
score = 0
crsr.execute('SELECT (SUM("no certificate"+"high school diploma"+"Apprenticeship") / (SUM ("Bachelor Diploma"+"Master Diploma"+"Doctorate")) FROM provinces WHERE cities = ? AND province = ?', city, province)
score = crsr.fetchone()
return score
UPDATED: To handle the scoring you should do it in python, not SQL.
def edu_score(education, fos, province, city):
eds = ['No_certificate', 'high_school_diploma', 'Apprenticeship', 'CEGEP', 'Bachelor Diploma', 'Master Diploma', 'Doctorate']
ed_index = eds.index(education)
crsr.execute('SELECT SUM("no certificate"), SUM("high school diploma"), SUM("Apprenticeship"), SUM ("Bachelor Diploma"), SUM("Master Diploma"), SUM("Doctorate") FROM provinces WHERE cities = ? AND province = ?',
city, province)
scores = crsr.fetchone()
score = sum(scores[:ed_index])/sum(scores[ed_index:])
return score
[MY ANSWER]
So the first problem I had was that I was adding another string into the SELECT statement through edu_score(education), which only returned the string found in the DB. The other problem was that it wasn't summing just the necessary rows, depending on the user's highest level of education.
The answer was this: segment the SELECT string and do not use the SUM, as it is summing column and not rows. You just need to make a string that encompasses all the data you want to add ie : SELECT (A + B + C) FROM table WHERE ?, [city,] .
phrase = ''
I made this variable because within the function it would return 'None'
def city_result(base):
global phrase
edu_lvl = ['No_certificate', 'high_school_diploma', 'Apprenticeship', 'CEGEP', 'Bachelor', 'Master', 'Doctorate']
for i in edu_lvl[edu_lvl.index(base):: -1] :
if edu_lvl.index(i) == 0:
phrase = phrase + i
else:
phrase = i + " + " + phrase
city_result is what will be put in the SELECT statement to be counted
def edu_score(education, fos, province, city):
global phrase
score = 0
city_result(education)
crsr.execute("SELECT (" + phrase + ") FROM ? WHERE cities = ?", [province, city,])
score = crsr.fetchone()
score = score / (100 - score)
The only thing to remember is that SUM is for column, so if you just want certain row, just put the data you want to add within the SELECT statement, and be careful with putting string in the SELECT string (because it returns that same string).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.