add functionality

This commit is contained in:
AntonWirsing 2025-08-18 13:22:25 +02:00
parent 804d11d3cc
commit 1455466044
4 changed files with 874 additions and 23 deletions

File diff suppressed because one or more lines are too long

316
durationEstimate.ipynb Normal file

File diff suppressed because one or more lines are too long

145
main.py Normal file
View File

@ -0,0 +1,145 @@
import pandas as pd
from client import askGPT
systempromptWindow = """Du bist ein Assistent zur Kostenschätzung von Reinigungsaufträgen.
Antworte nur im gewünschten JSON-Schema.
Preisliste (EUR):
- normale_fenster: 15
- balkon_terrassentuer: 15
- altbau_doppelfenster: 25 (teurer, da üblicherweise unterteilt in 4 Scheiben)
- aussenjalousien: 15
- schaufenster_pro_m2: 3.6
Aufgaben:
1. Prüfe genau, ob die Beschreibung vollständig und klar ist:
- Sind alle Leistungen eindeutig und verständlich beschrieben?
- Sind Mengen klar spezifiziert? Falls nur Scheiben angegeben sind: Berechne daraus unbedingt, wie viele komplette Fenster gemeint sind.
- Kläre, ob Zahlen sich auf Scheiben, Fenster oder Quadratmeter beziehen.
2. Identifiziere explizit mögliche Missverständnisse in der Beschreibung und erläutere sie kurz.
3. Führe eine schrittweise Kalkulation durch:
- Wandle Scheibenanzahl ggf. zuerst in Fenster um.
- Fasse alle eindeutigen Leistungen zusammen (mit genauen Mengenangaben).
4. Kalkuliere den Gesamtpreis und erkläre den Rechenweg klar.
5. Gib den minimalen Gesamtpreis (nur vollständig angegebene Leistungen).
6. Gib den maximalen Gesamtpreis (unter Berücksichtigung angedeuteter/unvollständiger Angaben).
7. Schätze konservativ die Klarheit und Vollständigkeit der Beschreibung (zwischen 0 und 1).
8. Gibt es zuzätzliche Informationen die du vom Kunden anfordern möchtest? Lass das feld leer, wenn nicht.
Response Schema:
{"totalPrice": "integer", "totalPriceLow": "integer", "totalPriceHigh": "integer","ZusatzInfo": "string", "complete": "boolean", "confidence": "float","missverständliche Aspekte": "string","Zu erbringende Leistungen:": "string", "Rechenweg": "string", "Kommentare": "string"}
Berechne anhand der Auftragsbeschreibung, welche Leistungen wie oft vorhanden sind. Summiere diese zu einem Gesamtpreis!
"""
systempromptUmzug = """Du bist ein Assistent zur Kostenschätzung von Reinigungsaufträgen zur Endreinigung nachdem der Bewohner ausgezogen ist.
Antworte nur im gewünschten JSON-Schema.
Beispiele (Minuten):
- normale_fenster: 20
- balkon_terrassentuer: 20
- altbau_doppelfenster: 30 (aufwendiger, da üblicherweise unterteilt in 4 Scheiben)
- aussenjalousien: 20
- schaufenster_pro_m2: 5
Aufgaben:
1. Prüfe genau, ob die Beschreibung vollständig und klar ist:
- Sind alle Leistungen eindeutig und verständlich beschrieben?
- Sind Mengen klar spezifiziert? Falls nur Scheiben angegeben sind: Berechne daraus unbedingt, wie viele komplette Fenster gemeint sind.
- Kläre, ob Zahlen sich auf Scheiben, Fenster oder Quadratmeter Fensterfläche oder Quadratmeter Bodenfläche beziehen.
2. Identifiziere explizit mögliche Missverständnisse in der Beschreibung und erläutere sie kurz.
3. Führe eine schrittweise Kalkulation durch:
- Wandle Scheibenanzahl ggf. zuerst in Fenster um.
- Fasse alle eindeutigen Leistungen zusammen (mit genauen Mengenangaben).
4. Kalkuliere den Gesamtaufwand und erkläre den Rechenweg klar.
5. Schätze konservativ die Klarheit und Vollständigkeit der Beschreibung (zwischen 0 und 1).
6. Gibt es zuzätzliche Informationen die du vom Kunden anfordern möchtest? Lass das feld leer, wenn nicht.
Response Schema:
{"duration": "quoted integer","ZusatzInfo": "quoted string", "complete": "quoted number 1 or 0", "confidence": "quoted float between 0 and 1","missverständliche Aspekte": "quoted string","Zu erbringende Leistungen:": "quoted string", "Rechenweg": "quoted string", "Kommentare": "quoted string"}
Berechne anhand der Auftragsbeschreibung, welche Leistungen wie oft vorhanden sind. Summiere diese zu einem Gesamtaufwand!
"""
systempromptIntensiv = """Du bist ein Assistent zur Kostenschätzung von Reinigungsaufträgen zur besonders gründlichen Reinigung.
Antworte nur im gewünschten JSON-Schema.
Beispiele (Minuten):
- normale_fenster: 30
- balkon_terrassentuer: 30
- altbau_doppelfenster: 45 (aufwendiger, da üblicherweise unterteilt in 4 Scheiben)
- aussenjalousien: 30
- schaufenster_pro_m2: 7.5
Aufgaben:
1. Prüfe genau, ob die Beschreibung vollständig und klar ist:
- Sind alle Leistungen eindeutig und verständlich beschrieben?
- Sind Mengen klar spezifiziert? Falls nur Scheiben angegeben sind: Berechne daraus unbedingt, wie viele komplette Fenster gemeint sind.
- Kläre, ob Zahlen sich auf Scheiben, Fenster oder Quadratmeter Fensterfläche oder Quadratmeter Bodenfläche beziehen.
2. Identifiziere explizit mögliche Missverständnisse in der Beschreibung und erläutere sie kurz.
3. Führe eine schrittweise Kalkulation durch:
- Wandle Scheibenanzahl ggf. zuerst in Fenster um.
- Fasse alle eindeutigen Leistungen zusammen (mit genauen Mengenangaben).
4. Kalkuliere den Gesamtaufwand und erkläre den Rechenweg klar.
5. Schätze konservativ die Klarheit und Vollständigkeit der Beschreibung (zwischen 0 und 1).
6. Gibt es zuzätzliche Informationen die du vom Kunden anfordern möchtest? Lass das feld leer, wenn nicht.
Response Schema:
{"duration": "quoted integer","ZusatzInfo": "quoted string", "complete": "quoted number 1 or 0", "confidence": "quoted float between 0 and 1","missverständliche Aspekte": "quoted string","Zu erbringende Leistungen:": "quoted string", "Rechenweg": "quoted string", "Kommentare": "quoted string"}
Berechne anhand der Auftragsbeschreibung, welche Leistungen wie oft vorhanden sind. Summiere diese zu einem Gesamtaufwand!
"""
data = pd.read_csv("./intensivQuotationsSample.csv", on_bad_lines='skip',sep=";")
data["response"]=""
index = data.index
for i in index:
print(f"\n\n\n\n\n\niteration {i} in {index}\n")
quotation = data.iloc[i,]
print(quotation["requirements_textual"])
response = askGPT(systempromptIntensiv,quotation["requirements_textual"])
data.at[i,"response"] = response
print(quotation["duration"])
data.to_csv("./intensivQuotationsSampleWithResponse.csv", index=False,sep=";")
data = pd.read_csv("./umzugQuotationsSample.csv", on_bad_lines='skip',sep=";")
data["response"]=""
index = data.index
for i in index:
print(f"\n\n\n\n\n\niteration {i} in {index}\n")
quotation = data.iloc[i,]
print(quotation["requirements_textual"])
response = askGPT(systempromptUmzug,quotation["requirements_textual"])
data.at[i,"response"] = response
print(quotation["duration"])
data.to_csv("./umzugQuotationsSampleWithResponse.csv", index=False,sep=";")
#print(data)
#print(systemprompt)

97
plot.py Normal file
View File

@ -0,0 +1,97 @@
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
def plotVariables(x,y):
# scatter plot (matplotlib, single plot, no explicit colors)
#plt.ylim(0, 1)
plt.figure()
plt.scatter(x, y)
plt.axhline(0, linestyle="--") # reference line
plt.xlabel(x.name)
plt.ylabel(y.name)
plt.title("diff_price vs. confidence")
plt.grid(True)
plt.show()
def plotPriceConfidence(condensed):
# pick the right confidence column
conf_col = "confidence" if "confidence" in condensed.columns else (
"resp_confidence" if "resp_confidence" in condensed.columns else None
)
if conf_col is None:
raise KeyError("No 'confidence' or 'resp_confidence' column found in condensed.")
# keep only the needed columns and coerce to numeric
dfp = condensed[[conf_col, "diff_price"]].copy()
dfp[conf_col] = pd.to_numeric(dfp[conf_col], errors="coerce")
dfp["diff_price"] = pd.to_numeric(dfp["diff_price"], errors="coerce")
dfp = dfp.dropna(subset=[conf_col, "diff_price"])
# scatter plot (matplotlib, single plot, no explicit colors)
#plt.ylim(0, 1)
plt.figure()
plt.scatter(dfp[conf_col], dfp["diff_price"])
plt.axhline(0, linestyle="--") # reference line
plt.xlabel(conf_col)
plt.ylabel("diff_price")
plt.title("diff_price vs. confidence")
plt.grid(True)
plt.show()
def histPriceDiff(condensed):
conf_col = (
"confidence" if "confidence" in condensed.columns
else "resp_confidence" if "resp_confidence" in condensed.columns
else None
)
if conf_col is None:
raise KeyError("No 'confidence' or 'resp_confidence' column in condensed.")
# --- prepare data ---
df = condensed[[conf_col, "diff_price"]].copy()
df[conf_col] = pd.to_numeric(df[conf_col], errors="coerce")
df["diff_price"] = pd.to_numeric(df["diff_price"], errors="coerce")
df = df.dropna(subset=[conf_col, "diff_price"])
# scale confidence to 0100 if it looks like 01
if df[conf_col].max() <= 1.01:
df[conf_col] = df[conf_col] * 100
# --- define bands ---
bands = [
("confidence == 100", df[ df[conf_col] == 100 ]),
("100 > confidence ≥ 90", df[(df[conf_col] < 100) & (df[conf_col] >= 90)]),
("90 > confidence ≥ 80", df[(df[conf_col] < 90) & (df[conf_col] >= 80)]),
("80 > confidence ≥ 50", df[(df[conf_col] < 80) & (df[conf_col] >= 50)]),
("50 > confidence", df[ df[conf_col] < 50 ]),
]
# --- common bins across all groups for fair comparison ---
all_vals = df["diff_price"].values
if all_vals.size == 0:
raise ValueError("No numeric diff_price values to plot.")
xmin, xmax = np.nanmin(all_vals), np.nanmax(all_vals)
if xmin == xmax:
# degenerate case: make a tiny range around the single value
xmin, xmax = xmin - 0.5, xmax + 0.5
bins = np.linspace(xmin, xmax, 31) # 30 bins
# --- plot each histogram in its own figure (no subplots, no explicit colors) ---
for title, d in bands:
if d.empty:
print(f"[skip] {title}: no rows")
continue
plt.figure()
plt.hist(d["diff_price"].values, bins=bins)
plt.title(f"diff_price for {title}")
plt.xlabel("diff_price")
plt.ylabel("count")
plt.grid(True)
plt.show()
# (optional) quick counts per band
for title, d in bands:
print(f"{title}: {len(d)} rows")