For sake of simplicity let’s say I have a questionare.
Each answer gains a score.
Some questions are qualitative so user must choose between one of the text answers.
Q: what’s your fav pet?
- cat [1 point]
- dog [2 points]
- caiman [3 points]
Answering dog I get 2 points.
Some questions are quantitative so user inputs a number and gets scoring with linear interpolation:
How much beer liters do you drink in a day?
- 0 [0 points]
- 1 [1 point]
- 3 [5 points]
If I answer 2 liters I get 3 points.
Now I use sqlalchemy and have a table with an answer each row:
questions
id PK
name String
quantitative Bool
answers
id Integer PK
id_question Integer FK
value String
and cast answers.value to float each time I have to deal with it as a number for interpolation and so on.
-
I could change column name
valueto_valueand make getter and setter functions foranswer.valuethat casts each time to floatanswer._valueif question is numeric (answer.question.quantitativeisTrue) -
I could have separate columns in answer for textual and numeric values (like
valueandtext, I will have no millions of records anyway) -
Or…
What is supposed to be more efficient and easy to use?
Please consider SQLAlchemy magic that takes care of a lot of the dirty work, I’d like to keep it that simple.
Edit:
Since beer example could be misleading I integrate with another:
Q: how many money do you give in charity in USD?
- 0 [0 point]
- 10 [1 point]
- 100 [2 points]
Like for pets & beer question I have answer values "0", "10", "100" stored in database as strings in answers.value column so to interpolate values to get score for answer 50 I have all the time to cast answers.value to float.
Here’s where I have mixed content type in the same db column.
For a quick and dirty solution I would suggest at least using two different columns to store different answers. You can also add a CHECK constraint to the database to ensure that exactly one of them is used for any row and the other is NULL. Than do the quick-n-dirty code to calculate total
Testscore.The alternative
The idea is build the proper object model, map it to RDMBS and the question does not need to be asked. Also I expect that when using Single Table Inheritance, the resulting DB schema would be almost identical to the current implementation (you can see the model when you run the script with the option
echo=True):The code below is a complete working script that shows both the object model, its mapping to the database and the usage scenarios. As it is designed, the model is easily extendable with other types of questions/answers without any impact on existing classes. Basically you get less hacky and more flexible code simply because you have an object model which properly reflects your case. The code is below:
I hope that this version of the code answers all the questions asked in the comments.