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
|
### 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)
|
||||||
- `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`
|
### 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
|
```sql
|
||||||
CREATE TABLE tasks (
|
CREATE TABLE IF NOT EXISTS tasks (
|
||||||
id integer NOT NULL,
|
id integer NOT NULL,
|
||||||
correct_answer boolean,
|
correct_answer character(5),
|
||||||
media_url text,
|
media_url text,
|
||||||
weight smallint
|
weight smallint
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE questions (
|
CREATE TABLE IF NOT EXISTS questions (
|
||||||
task_id integer,
|
task_id integer,
|
||||||
lang character(2),
|
lang character(2),
|
||||||
text text
|
text text
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE tasks_advanced (
|
CREATE TABLE IF NOT EXISTS tasks_advanced (
|
||||||
id integer NOT NULL,
|
id integer NOT NULL,
|
||||||
correct_answer character(1),
|
correct_answer character(1),
|
||||||
media_url text,
|
media_url text,
|
||||||
weight smallint
|
weight smallint
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE questions_advanced (
|
CREATE TABLE IF NOT EXISTS questions_advanced (
|
||||||
task_id integer,
|
task_id integer,
|
||||||
lang character(2),
|
lang character(2),
|
||||||
text text,
|
text text,
|
||||||
|
@ -35,34 +49,89 @@ CREATE TABLE questions_advanced (
|
||||||
answer_c text
|
answer_c text
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE categories (
|
CREATE TABLE IF NOT EXISTS categories (
|
||||||
name text,
|
name text,
|
||||||
task_id integer
|
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
|
```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
|
FROM tasks
|
||||||
LEFT JOIN questions ON tasks.id = questions.task_id
|
LEFT JOIN questions ON tasks.id = questions.task_id
|
||||||
LEFT JOIN categories ON tasks.id = categories.task_id
|
LEFT JOIN categories ON tasks.id = categories.task_id
|
||||||
WHERE
|
WHERE
|
||||||
categories.name = 'B' AND
|
categories.name = 'B' AND
|
||||||
questions.lang = 'PL'
|
questions.lang = 'PL' AND
|
||||||
|
tasks.weight = WEIGHT_OF_QUESTIONS
|
||||||
ORDER BY random()
|
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
|
```sql
|
||||||
SELECT tasks_advanced.correct_answer, tasks_advanced.media_url, tasks_advanced.weight,
|
SELECT
|
||||||
questions_advanced.text, questions_advanced.answer_a, questions_advanced.answer_b, questions_advanced.answer_c
|
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
|
FROM tasks_advanced
|
||||||
LEFT JOIN questions_advanced ON tasks_advanced.id = questions_advanced.task_id
|
LEFT JOIN questions_advanced ON tasks_advanced.id = questions_advanced.task_id
|
||||||
LEFT JOIN categories ON tasks_advanced.id = categories.task_id
|
LEFT JOIN categories ON tasks_advanced.id = categories.task_id
|
||||||
WHERE
|
WHERE
|
||||||
categories.name = 'B' AND
|
categories.name = 'B' AND
|
||||||
questions_advanced.lang = 'PL'
|
questions_advanced.lang = 'PL' AND
|
||||||
|
tasks_advanced.weight = WEIGHT_OF_QUESTIONS
|
||||||
ORDER BY random()
|
ORDER BY random()
|
||||||
LIMIT (20);
|
LIMIT (NO_OF_QUESTIONS);
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
import csv
|
import csv, psycopg2, pwinput
|
||||||
from tqdm import tqdm
|
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 = 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 tasks;')
|
||||||
cur.execute('TRUNCATE TABLE questions;')
|
cur.execute('TRUNCATE TABLE questions;')
|
||||||
cur.execute('TRUNCATE TABLE categories;')
|
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 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':
|
if poprawna_odp == 'Tak':
|
||||||
correct_answer = True
|
correct_answer = 'true'
|
||||||
elif poprawna_odp == 'Nie':
|
elif poprawna_odp == 'Nie':
|
||||||
correct_answer = False
|
correct_answer = 'false'
|
||||||
else:
|
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)',
|
cur.execute('INSERT INTO tasks (id, correct_answer, media_url) VALUES (%s, %s, %s)',
|
||||||
(task_id, correct_answer, media))
|
(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