Skip to content
Snippets Groups Projects
Commit 60be469f authored by Majid Rouhani's avatar Majid Rouhani
Browse files

fikset grafer

parent 83147805
Branches v1.4
No related tags found
No related merge requests found
Showing
with 1222 additions and 5 deletions
...@@ -54,6 +54,18 @@ ...@@ -54,6 +54,18 @@
<option value="E501" /> <option value="E501" />
<option value="W29" /> <option value="W29" />
<option value="E501" /> <option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
</list> </list>
</option> </option>
</inspection_tool> </inspection_tool>
......
No preview for this file type
No preview for this file type
No preview for this file type
from tkinter import * from tkinter import *
from prosjekt.prosjektoppgave.archive_db import * from prosjekt.prosjektoppgave.archive_db import *
import datetime from datetime import *
import sys import sys
from tkinter import messagebox from tkinter import messagebox
...@@ -24,7 +24,7 @@ Endret dato, endret av, versjon ...@@ -24,7 +24,7 @@ Endret dato, endret av, versjon
def valider_dato(dato): def valider_dato(dato):
date_format = '%d.%m.%Y' # dd.mm.yyyy, 25/8/2019 date_format = '%d.%m.%Y' # dd.mm.yyyy, 25/8/2019
try: try:
date_obj = datetime.datetime.strptime(dato, date_format) date_obj = datetime.strptime(dato, date_format).date()
return dato return dato
except ValueError: except ValueError:
messagebox.showerror("Error", "Dato skal være på formen: DD.MM.YYYY") messagebox.showerror("Error", "Dato skal være på formen: DD.MM.YYYY")
......
...@@ -56,8 +56,9 @@ def view_materiale_statistics(): ...@@ -56,8 +56,9 @@ def view_materiale_statistics():
Kaller funksjonen archive_db.get_materialet_counts som returnerer liste med gjenstander grupper etter materialet og antall Kaller funksjonen archive_db.get_materialet_counts som returnerer liste med gjenstander grupper etter materialet og antall
Deretter kalles funkasjonen archive_statistics.show_bar_chart for å tegne grafen. Deretter kalles funkasjonen archive_statistics.show_bar_chart for å tegne grafen.
""" """
counts, materiale = archive_db.get_materialet_counts() materiale,counts = archive_db.get_materialet_counts()
archive_statistics.show_bar_chart(materiale,counts,"Antall","Materialet" )
archive_statistics.show_histogram(counts,materiale,"Antall","Materialet" )
# Definerer aksjon for dobbeltklikk på en gjenstand i lista # Definerer aksjon for dobbeltklikk på en gjenstand i lista
def edit_gjenstand(event): def edit_gjenstand(event):
......
...@@ -14,11 +14,20 @@ def show_bar_chart(counts, labels, ylabel, xlabel): ...@@ -14,11 +14,20 @@ def show_bar_chart(counts, labels, ylabel, xlabel):
m.show() m.show()
# Lag et histogram hvor gitte verdier telles opp og puttes i bøtter (bins) basert på min, max og antall # Lag et histogram hvor gitte verdier telles opp og puttes i bøtter (bins) basert på min, max og antall
def show_histogram(values, min, max, num_bins, ylabel, xlabel): def show_histogram_tall(values, min, max, num_bins, ylabel, xlabel):
bins = np.linspace(min, max, num_bins) bins = np.linspace(min, max, num_bins)
plt.hist(values, bins) plt.hist(values, bins)
plt.show() plt.show()
def show_histogram(materialet, counts, ylabel, xlabel):
plt.bar(materialet, height=materialet)
plt.xticks(materialet, counts)
plt.ylim(0,max(counts))
plt.show()
# Test-funksjoner # Test-funksjoner
#show_bar_chart([2, 16, 3, 1, 4.5], ["a", "b", "c", "d", "e"], "Antall", "Kategori") #show_bar_chart([2, 16, 3, 1, 4.5], ["a", "b", "c", "d", "e"], "Antall", "Kategori")
#show_histogram([10,41,72,45,51,52,51,54,56,81,43,42], 0, 100, 10, "Antall", "Alder") #show_histogram([10,41,72,45,51,52,51,54,56,81,43,42], 0, 100, 10, "Antall", "Alder")
File added
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoredErrors">
<list>
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
<option value="W29" />
<option value="E501" />
</list>
</option>
</inspection_tool>
</profile>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (LBAS2002_Prosjektoppgave_Mal_v1.0)" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/simple-python-gui-app-master.iml" filepath="$PROJECT_DIR$/.idea/simple-python-gui-app-master.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.7 (LBAS2002_Prosjektoppgave_Mal_v1.0)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="9b9e68dd-cd4c-4c67-9408-4fb32e0bb4da" name="Default Changelist" comment="" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FUSProjectUsageTrigger">
<session id="-117992187">
<usages-collector id="statistics.lifecycle.project">
<counts>
<entry key="project.closed" value="2" />
<entry key="project.open.time.0" value="2" />
<entry key="project.opened" value="2" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.extensions.open">
<counts>
<entry key="py" value="1" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.types.open">
<counts>
<entry key="Python" value="1" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.extensions.edit">
<counts>
<entry key="py" value="6" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.types.edit">
<counts>
<entry key="Python" value="6" />
</counts>
</usages-collector>
</session>
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/archive_db.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="153">
<caret line="9" selection-start-line="9" selection-end-line="9" />
<folding>
<element signature="e#0#14#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/archive_db.py" />
</list>
</option>
</component>
<component name="ProjectFrameBounds">
<option name="x" value="621" />
<option name="y" value="169" />
<option name="width" value="1530" />
<option name="height" value="1217" />
</component>
<component name="ProjectId" id="1SBkrPm8synUK4zFblNJjfBUBgg" />
<component name="ProjectView">
<navigator proportions="" version="1">
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="Course" />
<pane id="ProjectPane">
<subPane>
<expand>
<path>
<item name="LBAS2002_Prosjektoppgave_Mal_v1.1" type="b2602c69:ProjectViewProjectNode" />
<item name="LBAS2002_Prosjektoppgave_Mal_v1.1" type="462c0819:PsiDirectoryNode" />
</path>
</expand>
<select />
</subPane>
</pane>
</panes>
</component>
<component name="PropertiesComponent">
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager" selected="Python.archive_db">
<configuration name="archive_db" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="simple-python-gui-app-master" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/archive_db.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="archive_main" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="simple-python-gui-app-master" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/archive_main.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<list>
<item itemvalue="Python.archive_main" />
<item itemvalue="Python.archive_db" />
</list>
<recent_temporary>
<list>
<item itemvalue="Python.archive_db" />
<item itemvalue="Python.archive_main" />
</list>
</recent_temporary>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="ToolWindowManager">
<frame x="621" y="169" width="1530" height="1217" extended-state="0" />
<editor active="true" />
<layout>
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.25" />
<window_info id="Structure" order="1" weight="0.25" />
<window_info anchor="bottom" id="Message" order="0" />
<window_info anchor="bottom" id="Find" order="1" />
<window_info anchor="bottom" id="Run" order="2" weight="0.32933578" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
<window_info anchor="bottom" id="TODO" order="6" />
<window_info anchor="bottom" id="Version Control" order="7" show_stripe_button="false" />
<window_info anchor="bottom" id="Python Console" order="8" />
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
</layout>
</component>
<component name="VcsContentAnnotationSettings">
<option name="myLimit" value="2678400000" />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/archive_db.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="153">
<caret line="9" selection-start-line="9" selection-end-line="9" />
<folding>
<element signature="e#0#14#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</component>
</project>
\ No newline at end of file
File added
File added
File added
import pymysql
from tkinter import messagebox
import sys
"""
Skrevet av: Majid Rouhani
Opprettet: 11.09.2018
Oppdatert: 15.10.2019
Versjon: 1.2
Beskrivesle:
Denne modulen leser data fra databasen eller registrerer/oppdaterer gjenstander.
NB! Oppdater variablene user/password slik at de inneholder rett database tilgang.
-----------------------------------------------------------------------------------------------------------
Endret dato, endret av, versjon
<dato>, <navn>, <versjon>
-----------------------------------------------------------------------------------------------------------
"""
host = "mysql.stud.iie.ntnu.no"
user = "" # Skriv inn brukernavnet ditt her
password = "" # Skriv inn passordet ditt her
def get_db_connection():
if user=="":
messagebox.showerror("Error", "User/password for database kobling er ikke satt. Sjekk filen archive_db")
return False
else:
return pymysql.connect(host, user, password, user)
# Søk på gjenstander, gitt navn og/eller registreringsnummer
def search(name, regnr):
"""
:param name: navn på gjenstand. Denne kan være tom, dvs "" eller være hele/deler av navnet. Case-sensitive!
:param regnr: registreringsnummer på gjenstand. Denne kan være tom, dvs "" eller være hele/deler av registreringsnummeret. Case-sensitive!
:return: returnerer en 2-dimensjonal liste med søkeresultater
"""
db = get_db_connection()
if not db:
sys.exit(0)
cursor = db.cursor()
# Logger inputdata til konsollet
print("search: name=" + name + ", regnr=" + regnr)
sql = "SELECT regnr,navn,regdato,regav FROM gjenstand WHERE navn LIKE '%"+name+"%' AND regnr LIKE '%"+regnr+"%'"
print(sql)
cursor.execute(sql)
result = []
for row in cursor:
gjenstand = []
#******************************************
# Oppgave 4.2
# Fullfør denne funksjonen slik at en 2-dimensjonal liste (result) returneres
#******************************************
db.close()
# Logger antall rader funnet til konsollet
print("search: rowcount=" + str(len(result)))
return result
#Slett gjenstand
def delete_gjenstand(regnr):
"""
:param regnr: Registreriongsnr på gjenstand som skal slettes
:return: ingen returverdi.
Funksjonen skal finne gjenstanden og slette denne.
1. Finn kategori_id for denne gjenstanden (fra gjenstand-tabell) for det gitte registreringsnummeret
2. Slett fra egenskaper-tabellen for det gitte registreringsnummeret
3. Slett fra proveniens-tabellen for det gitte registreringsnummeret
4. Slett fra kategori-tabellen for det gitte registreringsnummeret
5. Slett fra gjentand-tabellen for det gitte registreringsnummeret
Dersom sletting går bra, skriv en melding til skjermen.
"""
#******************************************
# Oppgave 4.3
# Fullfør denne funksjonen
#******************************************
print("delete_gjenstand: "+regnr)
# Hent alle materialet og antall av hver som to lister
def get_materialet_counts():
"""
Les antall gjenstander fra databasen gruppert på 'materialet'
Legg resultatet i to lister: materialet og counts
:return: counts (liste med tall), materialet (liste med gjenstands materialet)
"""
db = get_db_connection()
if not db:
sys.exit(0)
cursor = db.cursor()
cursor.execute("SELECT count(regnr),materiale FROM egenskaper group by materiale")
materiale = []
counts = []
for row in cursor:
materiale.append(row[0])
counts.append(row[1])
db.close()
# Logger antall rader funnet til konsollet
print("get_materialet_counts: rowcount=" + str(len(materiale)))
return counts, materiale
# Hent all informasjon om en gjenstand basert på regnr
def hent_gjenstand(regnr):
"""
Henter all informasjon om en gjebstand for en gitt registreringsnr
:param regnr: Regnr er av typen string
:return: Returnerer resultatet i en 2-dimensjonal tabell.
Tabellen vil alltid inneholde en gjenstand da vi søker etter eksakt treff og regnr er primær-nøkkel
"""
db = get_db_connection()
if not db:
sys.exit(0)
cursor = db.cursor()
cursor.execute("""
SELECT giver,inndato,kommentar,mottattav,navn,plassering,regav,regdato,g.regnr,katnavn,fys_egenskap,maal,materiale,tilstand,produsent,prod_aar,siste_eier,tidl_eiere
FROM gjenstand g,
egenskaper e,
kategori k,
proveniens p
WHERE g.regnr = e.regnr
AND g.kategori_id = k.kategori_id
AND g.regnr = p.regnr
AND g.regnr = %s """, regnr)
result = []
for row in cursor:
print(row)
gjenstand = []
for r in range(len(row)):
gjenstand.append(row[r])
result.append(gjenstand)
db.close()
# Logger antall rader funnet til konsollet
print("search: rowcount=" + str(len(result)))
return result
#Get next kategori_id
def get_next_category_id():
"""
Finn neste kategori_id for registrering av ny gjenstand.
:return: hente siste kategori_id fra basen og øk tallet med 1. Returner dette
"""
db = get_db_connection()
if not db:
sys.exit(0)
cursor = db.cursor()
cursor.execute("SELECT max(kategori_id) as kategori_id FROM kategori")
kategoti_id = ""
for row in cursor:
kategoti_id= str(row[0])
db.close()
# Logger antall rader funnet til konsollet
print("kategoti_id: " + kategoti_id)
if int(kategoti_id)==0:
next_kategoti_id=1
else:
next_kategoti_id = int(kategoti_id)+1
return next_kategoti_id
#Get next kategori_id
def get_category_id(katnavn):
"""
:return: hente siste kategori_id fra basen. Returner dette
"""
db = get_db_connection()
if not db:
sys.exit(0)
cursor = db.cursor()
cursor.execute("SELECT kategori_id FROM kategori WHERE katnavn='" + katnavn+"'")
kategoti_id = ""
for row in cursor:
kategoti_id= str(row[0])
db.close()
# Logger antall rader funnet til konsollet
print("kategoti_id: " + kategoti_id)
return kategoti_id
def get_kategori():
"""
Hent alle kategoriene formatert som dictionary
:return: kategori liste
"""
kategori_dic = {}
db = get_db_connection()
if not db:
sys.exit(0)
cursor = db.cursor()
cursor.execute("SELECT kategori_id, katnavn FROM kategori")
kategoti_id = ""
for row in cursor:
kategori_dic.update({row[1]: row[0]})
db.close()
return kategori_dic
#Sjekk om regnr existerer i databasen
def regnr_exist(regnr,tabellnavn):
"""
Sjekk om regnnr existerer allerede i basen
:param regnr: type string
:return: boolean
"""
db = get_db_connection()
if not db:
sys.exit(0)
cursor = db.cursor()
sql = "SELECT count(regnr) as regnr_count FROM {0} WHERE regnr='{1}'".format(tabellnavn,regnr)
cursor.execute(sql)
regnr_count = 0
for row in cursor:
regnr_count= row[0]
db.close()
# Logger antall rader funnet til konsollet
print("regnr_count: " + str(regnr_count))
if regnr_count==0:
return False
else:
return True
#Sjekk om kategori_id existerer i basen
def kategori_exist(kategori_id):
"""
Sjekk om kategori_id existerer i databasen
:param kategori_id: int
:return: boolean
"""
db = get_db_connection()
if not db:
sys.exit(0)
cursor = db.cursor()
cursor.execute("SELECT count(kategori_id) as kategori_id_count FROM kategori WHERE kategori_id=%s",kategori_id)
kategori_id_count = 0
for row in cursor:
kategori_id_count= row[0]
db.close()
# Logger antall rader funnet til konsollet
print("kategori_id_count: " + str(kategori_id_count))
if kategori_id_count==0:
return False
else:
return True
#Lagre kategori info i basen
def save_cateogri_db(kategori_id, kategori):
"""
Lagre kategori info i databasen.
Dersom den finnes allerede, blir kategori oppdatert
Dersom den ikke finnes, blir den opprettet.
:param kategori_id: int
:param kategori: string
:return:
"""
#****************************************
# Oppgave 4.1
# Fullfør innholdet i denne funksjonen!
#****************************************
# Logger resultatet til konsollet
print("save_cateogri_db: rowcount=" + str(cursor.rowcount))
#Lagrer gjenstand i basen
def save_gjenstand_db(giver_val,
innlemmet_dato_val,
kategori_id,
kommentar_val,
mottatt_av_val,
navn_val,
plassering_val,
registrert_av_val,
registrerings_dato_val,
regnr):
"""
Lagre gjenstand info i databasen.
Dersom den finnes allerede, blir gjenstand oppdatert
Dersom den ikke finnes, blir den opprettet.
:param giver_val: string
:param innlemmet_dato_val: string
:param kategori_id: int
:param kommentar_val: string
:param mottatt_av_val: string
:param navn_val: string
:param plassering_val: string
:param registrert_av_val: string
:param registrerings_dato_val: string
:param regnr: string
:return:
"""
#****************************************
# Oppgave 4.1
# Fullfør innholdet i denne funksjonen!
#****************************************
# Logger resultatet til konsollet
print("save_gjenstand_db: rowcount=" + str(cursor.rowcount))
#Lagre egenskaper til gjenstand
def save_egenskaper_db(fysiske_egenskaper_val,
maal_val,
materiale_val,
regnr,
tilstand_val):
"""
Lagre egenskaper til gjenstand i 'egenskper' tabellen
:param fysiske_egenskaper_val: string
:param maal_val: string
:param materiale_val: string
:param regnr: string
:param tilstand_val: string
:return:
"""
db = get_db_connection()
if not db:
sys.exit(0)
db.autocommit(True)
cursor = db.cursor()
if regnr_exist(regnr,'egenskaper'):
cursor.execute("UPDATE egenskaper SET fys_egenskap=%s,maal=%s,materiale=%s,tilstand=%s WHERE regnr=%s",
(fysiske_egenskaper_val,maal_val,materiale_val,tilstand_val,regnr))
else:
cursor.execute("INSERT INTO egenskaper (fys_egenskap,maal,materiale,regnr,tilstand) VALUES(%s,%s,%s,%s,%s)",
(fysiske_egenskaper_val,maal_val,materiale_val,regnr,tilstand_val))
db.close()
# Logger resultatet til konsollet
print("save_egenskaper_db: rowcount=" + str(cursor.rowcount))
#Lagre proveniens til 'proveniens' tabellen
def save_proveniens_db(produsent_val,produksjonsaar_val,regnr,giver_siste_eier_val,tidligere_eiere_val):
"""
Lagre proveniens i 'proveniens' tabellen i databasen
:param produsent_val: string
:param produksjonsaar_val: string
:param regnr: string
:param giver_siste_eier_val: string
:param tidligere_eiere_val: string
:return:
"""
db = get_db_connection()
if not db:
sys.exit(0)
db.autocommit(True)
cursor = db.cursor()
if regnr_exist(regnr,'proveniens'):
cursor.execute("UPDATE proveniens SET produsent=%s,prod_aar=%s,siste_eier=%s,tidl_eiere=%s WHERE regnr=%s",
(produsent_val,produksjonsaar_val,giver_siste_eier_val,tidligere_eiere_val,regnr))
else:
cursor.execute("INSERT INTO proveniens (produsent,prod_aar,regnr,siste_eier,tidl_eiere) VALUES(%s,%s,%s,%s,%s)",
(produsent_val,produksjonsaar_val,regnr,giver_siste_eier_val,tidligere_eiere_val))
db.close()
# Logger resultatet til konsollet
print("save_proveniens_db: rowcount=" + str(cursor.rowcount))
from tkinter import *
from prosjekt.prosjektoppgave_v13.archive_db import *
"""
Skrevet av: Majid Rouhani
Opprettet: 11.09.2018
Oppdatert: 05.10.2019
Versjon: 1.1
Beskrivesle:
Denne modulen håndterer registrering/oppdatering av data.
Samler data fra skjermen og bruker db-funksjoner fra modulen archive_db for videre håndtering
-----------------------------------------------------------------------------------------------------------
Endret dato, endret av, versjon
<dato>, <navn>, <versjon>
-----------------------------------------------------------------------------------------------------------
"""
# Åpner eget vindu for å editere person
def open_edit(root, search, gjenstand_data=None):
"""
Åpner vindu for registrering av ny gjenstand eller oppdatering av eksisterende gjenstand.
:param root: referanse til hovedvinduet
:param search: søke kriteriet (string)
:param gjenstand_data: dersom data skal oppdateres (liste)
:return:
"""
# Definerer aksjon for lagring
def save_egenskaper():
"""
Lokal funksjon innhenting av egenskap data fra skjerm.
Videresender dataene til save_egenskaper_db for lagring
:return:
"""
registreringsnr_val = registreringsnr.get()
fysiske_egenskaper_val = fysiske_egenskaper.get()
maal_val = maal.get()
materiale_val = materiale.get()
tilstand_val = tilstand.get()
save_egenskaper_db(fysiske_egenskaper_val,
maal_val,
materiale_val,
registreringsnr_val,
tilstand_val)
def save_proveniens():
"""
Lokal funksjon innhenting av proveniens data fra skjerm.
Videresender dataene til save_proveniens_db for lagring
:return:
"""
registreringsnr_val = registreringsnr.get()
produsent_val = produsent.get()
produksjonsaar_val = produksjonsaar.get()
giver_siste_eier_val = giver_siste_eier.get()
tidligere_eiere_val = tidligere_eiere.get()
save_proveniens_db(produsent_val,
produksjonsaar_val,
registreringsnr_val,
giver_siste_eier_val,
tidligere_eiere_val)
def save_gjenstand(kategori_id):
"""
Lokal funksjon innhenting av gjenstand data fra skjerm.
Videresender dataene til save_gjenstand_db for lagring
:param kategori_id: int
:return:
"""
registreringsnr_val=registreringsnr.get()
giver_val = giver.get()
innlemmet_dato_val = innlemmet_dato.get()
kommentar_val = ""
mottatt_av_val = mottatt_av.get()
plassering_val = plassering.get()
registrert_av_val = registrert_av.get()
registrerings_dato_val = registrerings_dato.get()
navn_val=betegnelse.get()
save_gjenstand_db(giver_val,
innlemmet_dato_val,
kategori_id,
kommentar_val,
mottatt_av_val,
navn_val,
plassering_val,
registrert_av_val,
registrerings_dato_val,
registreringsnr_val)
#Ikke i bruk
def save_category():
"""
Lokal funksjon innhenting av kategori data fra skjerm.
Videresender dataene til save_cateogri_db for lagring
:return: int
"""
kategori_id=get_next_category_id()
kategori_val = kategori.get()
save_cateogri_db(kategori_id,
kategori_val)
return kategori_id
#Lage all data
def save_data():
"""
Hovedfunksjon for lagring av archive data.
Kalles videre save_category, save_gjenstand, save_egenskaper og save_proveniens
:return:
"""
#kategori_id = save_category()
kategori_id = get_category_id(kategori.get())
if registrerings_dato.get() == "":
messagebox.showerror("Error", "Registreringsnummer må oppgis")
exit(0)
save_gjenstand(kategori_id)
save_egenskaper()
save_proveniens()
messagebox.showinfo("Registrering", "Registrering av ny gjenstand er fullført!")
window.destroy()
# Definerer aksjon for sletting
def delete():
print("delete " + registreringsnr.get()) # Kun logg
if messagebox.askokcancel("Slett", "Er du sikker på at du vil slette gjenstanden?", parent=window):
delete_gjenstand(registreringsnr.get())
window.destroy() # Lukk dette vinduet
search() # Oppdater data i hovedvinduet på nytt siden vi har oppdatert innhold
# Oppretter et nytt vindu for å editere personinfo
window = Toplevel(root)
window.geometry("600x550")
# Add a title
window.title("Tussudal Bygdemuseum - Archieve")
window.columnconfigure(0, weight=1)
window.columnconfigure(1, weight=2)
window.columnconfigure(2, weight=2)
# Logger inndata
print("open_edit: data=" + str(gjenstand_data))
registreringsnr = StringVar()
registrerings_dato = StringVar()
registrert_av = StringVar()
innlemmet_dato = StringVar()
betegnelse = StringVar()
kategori = StringVar()
mottatt_av = StringVar()
giver = StringVar()
plassering = StringVar()
materiale = StringVar()
maal = StringVar()
tilstand = StringVar()
fysiske_egenskaper = StringVar()
produsent = StringVar()
produksjonsaar = StringVar()
giver_siste_eier = StringVar()
tidligere_eiere = StringVar()
# Hvis vi dobbeltklikket på listen fyller vi ut data'ene vi allerede har
if gjenstand_data:
print("Reading : "+str(gjenstand_data))
gjenstand = hent_gjenstand(gjenstand_data[0])
if len(gjenstand)>0:
giver.set(gjenstand[0][0])
innlemmet_dato.set(gjenstand[0][1])
mottatt_av.set(gjenstand[0][3])
betegnelse.set(gjenstand[0][4])
plassering.set(gjenstand[0][5])
registrert_av.set(gjenstand[0][6])
registrerings_dato.set(gjenstand[0][7])
registreringsnr.set(gjenstand[0][8])
kategori.set(gjenstand[0][9])
fysiske_egenskaper.set(gjenstand[0][10])
maal.set(gjenstand[0][11])
materiale.set(gjenstand[0][12])
tilstand.set(gjenstand[0][13])
produsent.set(gjenstand[0][14])
produksjonsaar.set(gjenstand[0][15])
giver_siste_eier.set(gjenstand[0][16])
tidligere_eiere.set(gjenstand[0][17])
# Oppretter widgets og plasserer dem i grid'en
l1=Label(window, text="Tussudal Bygdemuseum")
l1.grid(row=0,columnspan=2)
l1.config(font=("Courier", 22))
r=1
generelt_group = LabelFrame(window, text="Generelt", padx=5, pady=5, borderwidth=2)
generelt_group.grid(row=r,column=1,sticky=W)
#Show an image
#logo = PhotoImage(file="./bilder/tuddal_bygdemuseum.gif",width=200,height=200)
#w1 = Label(can1, image=logo).grid(row=0,column=1)
#Registrerings dato
Label(generelt_group,text="Registreringsdato:",width=25).grid(row=r,column=0,sticky=W)
Entry(generelt_group,textvariable=registrerings_dato,width=35).grid(row=r,column=1)
#Registrert av
r+=1
Label(generelt_group,text="Registrert av:",width=25).grid(row=r,column=0,sticky=W)
Entry(generelt_group,textvariable=registrert_av,width=35).grid(row=r,column=1)
#Innlemmet dato
r+=1
Label(generelt_group,text="Innlemmet dato:",width=25).grid(row=r,column=0,sticky=W)
Entry(generelt_group,textvariable=innlemmet_dato,width=35).grid(row=r,column=1)
identifikasjon_group = LabelFrame(window, text="Identifikasjon", padx=5, pady=5)
identifikasjon_group.grid(row=r,column=1,sticky=W)
#Identifikasjon
#r+=1
#Label(win,text="Identifikasjon").grid(row=r,column=0,sticky=W)
#Registreringsnr
r+=1
Label(identifikasjon_group,text="Registreringsnummer:",width=25).grid(row=r,column=0,sticky=W)
Entry(identifikasjon_group,textvariable=registreringsnr,width=35).grid(row=r,column=1)
#Betegnelse
r+=1
Label(identifikasjon_group,text="Betegnelse:",width=25).grid(row=r,column=0,sticky=W)
Entry(identifikasjon_group,textvariable=betegnelse,width=35).grid(row=r,column=1)
#Kategori
r+=1
choices = get_kategori()
kategori.set(next(iter(choices.keys())))
Label(identifikasjon_group,text="Velg kategori:",width=25).grid(row=r,column=0,sticky=W)
#Entry(identifikasjon_group,textvariable=kategori,width=35).grid(row=r,column=1)
OptionMenu(identifikasjon_group, kategori, *choices).grid(row=r,column=1)
#Mottatt av
r+=1
Label(identifikasjon_group,text="Mottatt av:",width=25).grid(row=r,column=0,sticky=W)
Entry(identifikasjon_group,textvariable=mottatt_av,width=35).grid(row=r,column=1)
#Giver
r+=1
Label(identifikasjon_group,text="Giver:",width=25).grid(row=r,column=0,sticky=W)
Entry(identifikasjon_group,textvariable=giver,width=35).grid(row=r,column=1)
#Plassering
r+=1
Label(identifikasjon_group,text="Plassering:",width=25).grid(row=r,column=0,sticky=W)
Entry(identifikasjon_group,textvariable=plassering,width=35).grid(row=r,column=1)
fysiske_egenskaper_group = LabelFrame(window, text="Fysiske egenskaper", padx=5, pady=5)
fysiske_egenskaper_group.grid(row=r,column=1,sticky=W)
#Fysiske egenskaper
#r+=1
#Label(fysiske_egenskaper_group,text="Fysiske egenskaper").grid(row=r,column=0,sticky=W)
#Materiale
r+=1
Label(fysiske_egenskaper_group,text="Materiale:",width=25).grid(row=r,column=0,sticky=W)
Entry(fysiske_egenskaper_group,textvariable=materiale,width=35).grid(row=r,column=1)
#Mål
r+=1
Label(fysiske_egenskaper_group,text="Mål:",width=25).grid(row=r,column=0,sticky=W)
Entry(fysiske_egenskaper_group,textvariable=maal,width=35).grid(row=r,column=1)
#Tilstand
r+=1
Label(fysiske_egenskaper_group,text="Tilstand:",width=25).grid(row=r,column=0,sticky=W)
Entry(fysiske_egenskaper_group,textvariable=tilstand,width=35).grid(row=r,column=1)
#Fysiske egenskaper
r+=1
Label(fysiske_egenskaper_group,text="Fysiske egenskaper:",width=25).grid(row=r,column=0,sticky=W)
Entry(fysiske_egenskaper_group,textvariable=fysiske_egenskaper,width=35).grid(row=r,column=1)
proveniens_group = LabelFrame(window, text="Proveniens", padx=5, pady=5)
proveniens_group.grid(row=r,column=1,sticky=W)
#Proveniens
#r+=1
#Label(win,text="Proveniens").grid(row=r,column=0,sticky=W)
#Produsent
r+=1
Label(proveniens_group,text="Materiale:",width=25).grid(row=r,column=0,sticky=W)
Entry(proveniens_group,textvariable=produsent,width=35).grid(row=r,column=1)
#Produksjonsår
r+=1
Label(proveniens_group,text="Produksjonsår:",width=25).grid(row=r,column=0,sticky=W)
Entry(proveniens_group,textvariable=produksjonsaar,width=35).grid(row=r,column=1)
#Tidligere eiere
r+=1
Label(proveniens_group,text="Tidligere eiere:",width=25).grid(row=r,column=0,sticky=W)
Entry(proveniens_group,textvariable=tidligere_eiere,width=35).grid(row=r,column=1)
#Fysiske Giver/Siste eier
r+=1
Label(proveniens_group,text="Giver/Siste eier:",width=25).grid(row=r,column=0,sticky=W)
Entry(proveniens_group,textvariable=giver_siste_eier,width=35).grid(row=r,column=1)
#Lagre data
r+=1
button = Button(window, text='Lagre', width=25,command=save_data)
button.grid(row=r,column=1)
# Legger til slette-knapp KUN hvis gjenstand data allerede eksisterer
if gjenstand_data:
delete_button = Button(window, text="Slett", command=delete)
delete_button.grid(row=r,column=0)
from tkinter import *
import prosjekt.prosjektoppgave_v13.archive_edit as archive_edit
import prosjekt.prosjektoppgave_v13.archive_db as archive_db
import prosjekt.prosjektoppgave_v13.archive_statistics as archive_statistics
"""
Skrevet av: Majid Rouhani
Opprettet: 11.09.2018
Oppdatert: 05.10.2019
Versjon: 1.1
Beskrivesle:
Dette er forslag til en minimumsløsning for prosjektet i fag LBAS2002 Informatikk (2018 HØST).
Programmet består av følgende moduler:
1) archive_main: Programmet startes ved å kjøre denne filen.
2) archive_db: Kommunikasjon mot databasen
3) archive_edit: Registrering/Redigering av data
For å kunne kjøre programmet, må du oppdatere archive_db modulen med påloggingsinformasjon (user/password).
-----------------------------------------------------------------------------------------------------------
Endret dato, endret av, versjon
<dato>, <navn>, <versjon>
-----------------------------------------------------------------------------------------------------------
"""
# Global liste for søkeresultatet
result = []
# Definerer aksjon for arkivsøket
def search():
"""
Søk i archive databasen
Funksjonen kaller archive_edit.search metoden som returnerer en 2-dimensjonal liste med søkeresultater.
(regnr,navn,regdato,regav)
Fyller deretter listen "result_listbox" med resultatet.
"""
result_listbox.delete(0, END)
result.clear()
db_result = archive_edit.search(name.get(), regnr.get())
for element in db_result:
result.append(element)
result_listbox.insert(END, element[0]+", "+element[1]+", "+element[2]+", "+element[3])
# Definerer aksjon for menyvalget "Registrer Ny"
def new_archive():
""""
Kaller funksjonen archive_edit.open_edit som åpner et vindu for å registrere ny gjenstand
"""
archive_edit.open_edit(root, search)
# Definerer aksjon for menyvalget "Vis aldersdistribusjon"
def view_materiale_statistics():
"""
Kaller funksjonen archive_db.get_materialet_counts som returnerer liste med gjenstander grupper etter materialet og antall
Deretter kalles funkasjonen archive_statistics.show_bar_chart for å tegne grafen.
"""
counts, materiale = archive_db.get_materialet_counts()
archive_statistics.show_histogram(materiale,counts,10,100,"Antall","Materialet" )
# Definerer aksjon for dobbeltklikk på en gjenstand i lista
def edit_gjenstand(event):
"""
Når bruker dobbel-klikker på en gjenstand i listen (søke-resultatet), sendes første kolonnen (regnr) i litsen som
parameter til funksjonen archive_edit.open_edit
Denne funksjonen slår opp i databasen og henter all data relatert til denne gjenstaden.
"""
archive_edit.open_edit(root, search, result[result_listbox.curselection()[0]])
"""
****************************Hoved program****************************
"""
# Opprett hovedvindu
root = Tk()
# Oppretter en ledetekster
name_label = Label(root, text="Navn:")
regnr_label = Label(root, text="Regnr:")
# Oppretter tekstfelter brukeren kan søke fra
name = StringVar() # Definerer en tekstvariabel for tekstfeltet
name_entry = Entry(root, textvariable=name)
regnr = StringVar() # Definerer en tekstvariabel for tekstfeltet
regnr_entry = Entry(root, textvariable=regnr)
# Oppretter en knapp med teksten "Søk", som kaller funksjonen search() ved trykk
search_button = Button(root, text="Søk", command=search)
# Oppretter listeboks med scrollbar for søkeresultat
scrollbar = Scrollbar(root, orient=VERTICAL)
result_listbox = Listbox(root, yscrollcommand=scrollbar.set)
scrollbar.config(command=result_listbox.yview)
result_listbox.bind('<Double-Button-1>', edit_gjenstand)
# Plasserer widget'ene i vinduet i et rutenett (grid)
name_label.grid(column=0, row=0, padx=2, pady=2)
name_entry.grid(column=1, row=0, padx=2, pady=2)
regnr_label.grid(column=2, row=0, padx=2, pady=2)
regnr_entry.grid(column=3, row=0, padx=2, pady=2)
search_button.grid(column=4, row=0, columnspan=2, padx=2, pady=2)
result_listbox.grid(column=0, row=1, columnspan=5, rowspan=10, sticky=EW)
scrollbar.grid(column=5, row=1, rowspan=10, sticky=NS)
# Lag meny
menubar = Menu(root)
gjenstandMenu = Menu(menubar, tearoff=0)
gjenstandMenu.add_command(label="Registrer ny", command=new_archive)
statisticsMenu = Menu(menubar, tearoff=0)
statisticsMenu.add_command(label="Se materiale distriobusjon", command=view_materiale_statistics)
menubar.add_cascade(label="Gjenstand", menu=gjenstandMenu)
menubar.add_cascade(label="Statistikk", menu=statisticsMenu)
root.config(menu=menubar)
# Starter GUI'et
root.mainloop()
import matplotlib.pyplot as plt
#plt.use('TkAgg') # Fiks for Mac
import numpy as np
def show_histogram_tall(values, min, max, num_bins, ylabel, xlabel):
bins = np.linspace(min, max, num_bins)
plt.hist(values, bins)
plt.show()
def show_histogram1(materialet, counts, ylabel, xlabel):
plt.bar(materialet, height=materialet)
plt.xticks(materialet, counts)
plt.show()
def show_histogram2(materialet, counts, xlabel, ylabel, title):
#y_pos = np.arange(len(materialet))
y_pos = range(0,len(materialet))
plt.bar(y_pos, height=counts)
plt.title(title)
plt.xlabel(xlabel)
plt.ylabel(ylabel)
plt.ylim(0,max(counts)+5)
plt.xticks(y_pos, materialet)
plt.show()
#Test
show_histogram2(['Tre','Jern','Plast','Glass','Ukategorisert'],[10,5,20,7,50],'Materialet','Antall','Kategori distribusjon')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment