Python koha testi
Tässä on koodi kirjastoaikani python3-koodille, joka hakee varauslistasta generoidusta excel-tiedostosta, haettavat varaukset ja käsittelee näiden dataa alla olevien koodien perusteella. Lopulta matplotlib sitten tekee frekvenssi-kuvaajat, joka näytetään Flask palvelimella.
import numpy as np
from io import BytesIO
from matplotlib.figure import Figure
import base64
from collections import Counter
# Luodaan erilaisia kuvaajia ja dataa ladatuista varaustiedoista.
# Datat:
# Nideluokka (kirja, cd, paikka (aikuiset nuoret), varauspaikka
def create_bar_chart(data, title, xlabel, ylabel):
fig = Figure(figsize=(6,3))
ax = fig.subplots()
items = list(data.items())
labels, values = zip(*items)
ax.bar(labels, values, width=0.4)
ax.set_title(title)
ax.set_xlabel(xlabel)
ax.set_ylabel(ylabel)
ax.tick_params(axis='x', rotation=45)
fig.tight_layout()
buffer = BytesIO()
with BytesIO() as buffer:
fig.savefig(buffer, format="png", dpi=600)
buffer.seek(0)
img_base64 = base64.b64encode(buffer.read()).decode("utf-8")
return img_base64
def calc_unique_count(excel_data):
reservations_total = len(excel_data)
# Counter on kätevä - laskee jokaisen uniikin arvon määrän mitä siihen tungetaan!
reservations_by_lib = Counter(row["res"] for row in excel_data)
reservations_by_type = Counter(row["type"] for row in excel_data)
reservations_by_loc = Counter(row["loc"] for row in excel_data)
reservations_by_signum = Counter(str(row["signum"]) for row in excel_data)
graphs = {
"reservations_by_lib": create_bar_chart(dict(reservations_by_lib),"Varaukset kirjastoittain", "Kirjasto", "Määrä"),
"reservations_by_type": create_bar_chart(dict(reservations_by_type), "Varaukset nideluokittain", "Nideluokka", "Määrä"),
"reservations_by_loc": create_bar_chart(dict(reservations_by_loc), "Varaukset sijainnittain", "Sijainti", "Määrä"),
"reservations_by_signum": create_bar_chart(dict(reservations_by_signum), "Varaukset signumeittain", "Signum", "Määrä")
}
return {
"total": reservations_total,
"reservations_by_lib": dict(reservations_by_lib),
"reservations_by_type": dict(reservations_by_type),
"reservations_by_loc": dict(reservations_by_loc),
"reservations_by_signum": dict(reservations_by_signum),
"graphs": graphs
}
Lataa calc.py
Yllä oleva calc.py koodi laskeskelee tarvittavat arvot. Seuraavaksi koodi joka käsittelee Excel-tiedoston sisältämän datan Pandas-kirjaston avulla:
import conf # config-tiedosto
import pandas as pd
filters = conf.filters
home = conf.settings["HOME"]
signum_id = conf.settings["signum_id"]
available_index = conf.settings["available_index"]
reservation_index = conf.settings["reservation_index"]
signum_index = conf.settings["signum_index"]
name_index = conf.settings["name_index"]
type_index = conf.settings["type_index"]
loc_index = conf.settings["loc_index"]
class ConfigurationError(Exception):
def __init__(self, message):
super().__init__(message)
def parse_signum(parsable_data: str):
#if conf.settings["parse_signum"].lower() == "true":
# return parsable_data
print(parsable_data)
indexes = []
temp = []
pairs = []
track = False
if parsable_data[-1] != " ":
parsable_data = parsable_data + " "
if parsable_data[0] != " ":
parsable_data = " " + parsable_data
for i, char in enumerate(parsable_data):
if char == " ":
indexes.append(i)
for i in range(0,len(indexes)-1):
element = parsable_data[indexes[i]:indexes[i+1]]
temp.append(element.replace(" ", ""))
for k in range(0, len(temp)-1):
if temp[k] == signum_id or temp[k+1] == signum_id:
if temp[k].isnumeric():
return temp[k]
else: return temp[k+1]
return parsable_data # Jos paria ei löydy, tulostetaan kaikki.
def process_excel(file_path: str):
pickup_rows = []
df = pd.read_excel(file_path, keep_default_na=False, na_values=['jokuarvo123'])
# pandas-kirjasto luulee että luokka NA (nuoret aikuiset) on nan-datatyyppi.
for index, row in df.iterrows():
delete = None
available = row.iloc[available_index]
reservation = row.iloc[reservation_index]
if reservation == home:
delete = False
elif reservation in available:
delete = False
else:
if reservation in filters and len(filters[reservation]) > 0:
for k in filters[reservation]:
if k in available:
delete = True
break
if not delete:
pickup_rows.append({
"res": reservation,
"signum": parse_signum(row.iloc[signum_index]),
"type": row.iloc[type_index],
"name": row.iloc[name_index],
"loc": row.iloc[loc_index]
})
return pickup_rows
Lataa excel.py
Ja vielä conf.py tiedoston lähdekoodi:
import json, os
filters_path = os.path.join(os.path.dirname(__file__), 'settings', 'filters.json')
settings_path = os.path.join(os.path.dirname(__file__), 'settings', 'settings.json')
filters = None
settings = None
# Haetaan tiedot tiedostoista yms.
with open(filters_path, "r", encoding="utf-8") as file:
filters = json.load(file)
with open(settings_path, "r", encoding="utf-8") as file:
settings = json.load(file)
# Poistaa oman filtterin
filters.pop(settings["HOME"])
Lataa conf.py
conf.py hakee settings kansiosta tarvittavat filtterit, joita käyttämällä Excel-tiedosto pystytään käsittelemään ja haettua noudettavat varaukset yms.
Tällä sivulla annettuja koodipätkiä saa hyödyntää :)