forked from maciej/prawo-jazdy-resources
Modified code slightly, polished almost everything else
This commit is contained in:
parent
c5d5db72bc
commit
e0e5ae4a37
5 changed files with 111 additions and 27 deletions
111
README.md
111
README.md
|
@ -1,32 +1,46 @@
|
|||
# prawo-jazdy-resources
|
||||
# db-prawo-jazdy
|
||||
|
||||
`db/main.py` is an *extremely* badly-written script that reads files (`pytania.csv` and `punkty.csv`) published by the Ministry of Infrastructure and imports them into a database
|
||||
- `db/pytania.csv` is the `katalog_pytania_egzminacyjne_kandydat__14112024.xlsx` file from [here](https://www.gov.pl/web/infrastruktura/prawo-jazdy), opened in Libreoffice Calc and saved as csv
|
||||
- `db/punkty.csv` isn't published by the Ministry, so you have to send a freedom of information request to acquire it; it is processed the same way as `pytania.csv`
|
||||
### Slightly modified version of [prawo-jazdy-resources](https://git.mandarynki.eu/maciej/prawo-jazdy-resources) by [maciej](https://git.mandarynki.eu/maciej), to suit the needs of [nuxt-prawo-jazdy](https://git.mandarynki.eu/netman/nuxt-prawo-jazdy)
|
||||
|
||||
### Files summary
|
||||
|
||||
`main.py` is an _extremely_ badly-written script that reads files (`pytania.csv` and `punkty.csv`) shared by the Ministry of Infrastructure and imports them into a postgresql database
|
||||
|
||||
- `db/pytania.csv` is the `katalog_pytania_egzminacyjne_kandydat__14112024.xlsx` file from [here](https://www.gov.pl/web/infrastruktura/prawo-jazdy)
|
||||
- `db/punkty.csv` isn't published by the Ministry, so you have to send a public information request to acquire it - we have received an XLSX
|
||||
both of them are converted to CSV
|
||||
|
||||
# Requirements
|
||||
|
||||
- postgres server
|
||||
- python3
|
||||
- packages from requirements.txt (`pip install -r requirements.txt`)
|
||||
- files above (either already CSV'd from this repo or converted by yourself from official, most probably fresher sources)
|
||||
|
||||
### Database structure
|
||||
|
||||
The database structure is as follows:
|
||||
```sql
|
||||
CREATE TABLE tasks (
|
||||
CREATE TABLE IF NOT EXISTS tasks (
|
||||
id integer NOT NULL,
|
||||
correct_answer boolean,
|
||||
correct_answer character(5),
|
||||
media_url text,
|
||||
weight smallint
|
||||
);
|
||||
|
||||
CREATE TABLE questions (
|
||||
CREATE TABLE IF NOT EXISTS questions (
|
||||
task_id integer,
|
||||
lang character(2),
|
||||
text text
|
||||
);
|
||||
|
||||
CREATE TABLE tasks_advanced (
|
||||
CREATE TABLE IF NOT EXISTS tasks_advanced (
|
||||
id integer NOT NULL,
|
||||
correct_answer character(1),
|
||||
media_url text,
|
||||
weight smallint
|
||||
);
|
||||
|
||||
CREATE TABLE questions_advanced (
|
||||
CREATE TABLE IF NOT EXISTS questions_advanced (
|
||||
task_id integer,
|
||||
lang character(2),
|
||||
text text,
|
||||
|
@ -35,34 +49,89 @@ CREATE TABLE questions_advanced (
|
|||
answer_c text
|
||||
);
|
||||
|
||||
CREATE TABLE categories (
|
||||
CREATE TABLE IF NOT EXISTS categories (
|
||||
name text,
|
||||
task_id integer
|
||||
);
|
||||
```
|
||||
|
||||
The basic tasks can be queried like so:
|
||||
## Criteria
|
||||
|
||||
Categories are as such:
|
||||
|
||||
- A
|
||||
- B
|
||||
- C
|
||||
- D
|
||||
- T
|
||||
- AM
|
||||
- A1
|
||||
- A2
|
||||
- B1
|
||||
- C1
|
||||
- D1
|
||||
- PT
|
||||
|
||||
Languages as such:
|
||||
|
||||
- PL
|
||||
- EN
|
||||
- UA
|
||||
- DE
|
||||
|
||||
# Basic tasks query
|
||||
|
||||
According to the Ministry of Infrastructure, in an exam there are (basic):
|
||||
|
||||
- 4 questions for 1 point
|
||||
- 6 questions for 2 points
|
||||
- 10 questions for 3 points
|
||||
so NO_OF_QUESTIONS and WEIGHT_OF_QUESTIONS should be set accordingly to the requirements above (and of course set category & lang to your liking)
|
||||
|
||||
```sql
|
||||
SELECT tasks.correct_answer, tasks.media_url, tasks.weight, questions.text
|
||||
SELECT
|
||||
tasks.id,
|
||||
tasks.correct_answer,
|
||||
tasks.media_url,
|
||||
tasks.weight,
|
||||
questions.text
|
||||
FROM tasks
|
||||
LEFT JOIN questions ON tasks.id = questions.task_id
|
||||
LEFT JOIN categories ON tasks.id = categories.task_id
|
||||
WHERE
|
||||
categories.name = 'B' AND
|
||||
questions.lang = 'PL'
|
||||
questions.lang = 'PL' AND
|
||||
tasks.weight = WEIGHT_OF_QUESTIONS
|
||||
ORDER BY random()
|
||||
LIMIT (20);
|
||||
LIMIT (NO_OF_QUESTIONS);
|
||||
```
|
||||
And the advanced tasks like this:
|
||||
|
||||
# Advanced tasks query
|
||||
|
||||
According to the Ministry of Infrastructure, in an exam there are (advanced):
|
||||
|
||||
- 2 questions for 1 point
|
||||
- 4 questions for 2 points
|
||||
- 6 questions for 3 points
|
||||
so NO_OF_QUESTIONS and WEIGHT_OF_QUESTIONS should be set accordingly to the requirements above (and of course set category & lang to your liking)
|
||||
|
||||
```sql
|
||||
SELECT tasks_advanced.correct_answer, tasks_advanced.media_url, tasks_advanced.weight,
|
||||
questions_advanced.text, questions_advanced.answer_a, questions_advanced.answer_b, questions_advanced.answer_c
|
||||
SELECT
|
||||
tasks_advanced.id,
|
||||
tasks_advanced.correct_answer,
|
||||
tasks_advanced.media_url,
|
||||
tasks_advanced.weight,
|
||||
questions_advanced.text,
|
||||
questions_advanced.answer_a,
|
||||
questions_advanced.answer_b,
|
||||
questions_advanced.answer_c
|
||||
FROM tasks_advanced
|
||||
LEFT JOIN questions_advanced ON tasks_advanced.id = questions_advanced.task_id
|
||||
LEFT JOIN categories ON tasks_advanced.id = categories.task_id
|
||||
WHERE
|
||||
categories.name = 'B' AND
|
||||
questions_advanced.lang = 'PL'
|
||||
questions_advanced.lang = 'PL' AND
|
||||
tasks_advanced.weight = WEIGHT_OF_QUESTIONS
|
||||
ORDER BY random()
|
||||
LIMIT (20);
|
||||
```
|
||||
LIMIT (NO_OF_QUESTIONS);
|
||||
```
|
||||
|
|
|
@ -1,10 +1,21 @@
|
|||
import csv
|
||||
import csv, psycopg2, pwinput
|
||||
from tqdm import tqdm
|
||||
import psycopg2
|
||||
|
||||
conn = psycopg2.connect('host=10.16.32.107 user=maciej password=maciej dbname=egzamin')
|
||||
host = input('host: ')
|
||||
user = input('user: ')
|
||||
password = pwinput.pwinput(prompt='password: ')
|
||||
dbname = input('dbname: ')
|
||||
port = int(input('port: '))
|
||||
|
||||
conn = psycopg2.connect(host=host, user=user, password=password, dbname=dbname, port=port)
|
||||
cur = conn.cursor()
|
||||
|
||||
cur.execute('CREATE TABLE IF NOT EXISTS tasks (id integer NOT NULL, correct_answer character(5), media_url text, weight smallint);')
|
||||
cur.execute('CREATE TABLE IF NOT EXISTS questions (task_id integer, lang character(2), text text);')
|
||||
cur.execute('CREATE TABLE IF NOT EXISTS tasks_advanced (id integer NOT NULL, correct_answer character(1), media_url text, weight smallint);')
|
||||
cur.execute('CREATE TABLE IF NOT EXISTS questions_advanced (task_id integer, lang character(2), text text, answer_a text, answer_b text, answer_c text);')
|
||||
cur.execute('CREATE TABLE IF NOT EXISTS categories (name text, task_id integer);')
|
||||
|
||||
cur.execute('TRUNCATE TABLE tasks;')
|
||||
cur.execute('TRUNCATE TABLE questions;')
|
||||
cur.execute('TRUNCATE TABLE categories;')
|
||||
|
@ -44,11 +55,11 @@ with open('pytania.csv') as file:
|
|||
|
||||
if numer and pytanie_pl and poprawna_odp and kategorie and not odp_a_pl and not odp_b_pl and not odp_c_pl:
|
||||
if poprawna_odp == 'Tak':
|
||||
correct_answer = True
|
||||
correct_answer = 'true'
|
||||
elif poprawna_odp == 'Nie':
|
||||
correct_answer = False
|
||||
correct_answer = 'false'
|
||||
else:
|
||||
raise Exception('zjebało się')
|
||||
raise Exception('Error, an answer to a basic question does not equal "Tak" or "Nie", check the pytania.csv file for anomaly in poprawna_odp section')
|
||||
|
||||
cur.execute('INSERT INTO tasks (id, correct_answer, media_url) VALUES (%s, %s, %s)',
|
||||
(task_id, correct_answer, media))
|
Can't render this file because it is too large.
|
4
requirements.txt
Normal file
4
requirements.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
tqdm
|
||||
psycopg2-binary
|
||||
pwinput
|
||||
csv
|
Loading…
Add table
Reference in a new issue