Reza-galaxy21 commited on
Commit
fb48623
·
verified ·
1 Parent(s): 98b30a9

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +184 -0
app.py ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import json
4
+ import os
5
+ import re
6
+ from typing import Dict, List, Optional
7
+
8
+ # تنظیمات
9
+ DB_PATH = "material_db.json"
10
+ os.makedirs("uploads", exist_ok=True)
11
+
12
+ class ProjectEstimator:
13
+ def __init__(self):
14
+ self.db = self._load_db()
15
+
16
+ def _load_db(self) -> Dict:
17
+ try:
18
+ with open(DB_PATH, 'r', encoding='utf-8') as f:
19
+ return json.load(f)
20
+ except (FileNotFoundError, json.JSONDecodeError):
21
+ return {"projects": {}, "rules": {}}
22
+
23
+ def _save_db(self):
24
+ with open(DB_PATH, 'w', encoding='utf-8') as f:
25
+ json.dump(self.db, f, ensure_ascii=False, indent=2)
26
+
27
+ def add_entry(self, description: str, excel_file: Optional[str] = None) -> str:
28
+ entry_id = f"entry_{len(self.db['projects']) + 1}"
29
+
30
+ # پردازش متن
31
+ features = self._parse_description(description)
32
+
33
+ # پردازش اکسل (اگر وجود دارد)
34
+ materials = []
35
+ if excel_file:
36
+ try:
37
+ df = pd.read_excel(excel_file)
38
+ materials = self._parse_excel(df)
39
+ except Exception as e:
40
+ return f"❌ خطا در پردازش فایل اکسل: {str(e)}"
41
+
42
+ # ذخیره در دیتابیس
43
+ self.db['projects'][entry_id] = {
44
+ "description": description,
45
+ "features": features,
46
+ "materials": materials
47
+ }
48
+ self._save_db()
49
+ return f"✅ ورودی با شناسه {entry_id} ثبت شد"
50
+
51
+ def _parse_description(self, text: str) -> Dict:
52
+ """استخراج ویژگی‌ها از متن توصیفی"""
53
+ features = {
54
+ "height": self._extract_value(text, r'ارتفاع\s*(\d+)'),
55
+ "capacity": self._extract_value(text, r'توان\s*(\d+)'),
56
+ "conductor": self._extract_conductor(text),
57
+ "formulas": self._extract_formulas(text)
58
+ }
59
+ return {k: v for k, v in features.items() if v}
60
+
61
+ def _parse_excel(self, df: pd.DataFrame) -> List[Dict]:
62
+ """پردازش فایل اکسل برآورد"""
63
+ materials = []
64
+ for _, row in df.iterrows():
65
+ item = {
66
+ "code": str(row.get('کد', '')),
67
+ "title": str(row.get('عنوان', '')),
68
+ "unit": str(row.get('واحد', '')),
69
+ "conditions": {
70
+ "height": row.get('ارتفاع پایه'),
71
+ "capacity": row.get('توان پایه'),
72
+ "conductor": row.get('نوع هادی')
73
+ },
74
+ "quantity": str(row.get('تعداد', ''))
75
+ }
76
+ materials.append(item)
77
+ return materials
78
+
79
+ def estimate(self, description: str) -> Dict:
80
+ """محاسبه برآورد براساس توضیحات"""
81
+ features = self._parse_description(description)
82
+ results = []
83
+
84
+ for project_id, project in self.db['projects'].items():
85
+ if self._match_project(project, features):
86
+ for item in project['materials']:
87
+ if self._match_material(item, features):
88
+ results.append({
89
+ "project": project_id,
90
+ "code": item['code'],
91
+ "title": item['title'],
92
+ "quantity": self._calc_quantity(item, features),
93
+ "unit": item['unit']
94
+ })
95
+
96
+ return {
97
+ "features": features,
98
+ "estimates": results
99
+ }
100
+
101
+ def _match_project(self, project: Dict, features: Dict) -> bool:
102
+ """بررسی تطابق پروژه با ویژگی‌های درخواستی"""
103
+ # می‌توانید منطق پیشرفته‌تری اینجا پیاده‌سازی کنید
104
+ return True
105
+
106
+ def _match_material(self, material: Dict, features: Dict) -> bool:
107
+ """بررسی شرایط هر قلم کالا"""
108
+ cond = material.get('conditions', {})
109
+ return (
110
+ (cond.get('height') is None or cond['height'] == features.get('height')) and
111
+ (cond.get('capacity') is None or cond['capacity'] == features.get('capacity')) and
112
+ (cond.get('conductor') is None or cond['conductor'] == features.get('conductor'))
113
+ )
114
+
115
+ def _calc_quantity(self, material: Dict, features: Dict) -> float:
116
+ """محاسبه مقدار نهایی"""
117
+ try:
118
+ if str(material['quantity']).startswith('='):
119
+ return eval(str(material['quantity'])[1:], {}, features)
120
+ return float(material['quantity'])
121
+ except:
122
+ return 1.0
123
+
124
+ # متدهای کمکی
125
+ def _extract_value(self, text: str, pattern: str) -> Optional[float]:
126
+ match = re.search(pattern, text)
127
+ return float(match.group(1)) if match else None
128
+
129
+ def _extract_conductor(self, text: str) -> Optional[str]:
130
+ conductors = ["مینک", "هاینا", "فاکس"]
131
+ for cond in conductors:
132
+ if cond in text:
133
+ return cond
134
+ return None
135
+
136
+ def _extract_formulas(self, text: str) -> Dict:
137
+ formulas = {}
138
+ # استخراج فرمول‌ها از متن
139
+ return formulas
140
+
141
+ # ایجاد نمونه
142
+ estimator = ProjectEstimator()
143
+
144
+ # رابط کاربری
145
+ with gr.Blocks(title="سیستم برآورد هوشمند") as demo:
146
+ with gr.Tab("📥 ثبت قوانین/پروژه"):
147
+ desc_input = gr.TextArea(label="توضیحات کامل پروژه یا قوانین")
148
+ file_input = gr.File(label="فایل اکسل (اختیاری)", file_types=[".xlsx"])
149
+ submit_btn = gr.Button("ثبت در دیتابیس")
150
+ output_status = gr.Textbox(label="وضعیت ثبت")
151
+
152
+ submit_btn.click(
153
+ estimator.add_entry,
154
+ inputs=[desc_input, file_input],
155
+ outputs=output_status
156
+ )
157
+
158
+ with gr.Tab("📊 دریافت برآورد"):
159
+ request_input = gr.TextArea(label="توضیحات پروژه مورد نظر")
160
+ estimate_btn = gr.Button("محاسبه برآورد")
161
+
162
+ with gr.Row():
163
+ features_output = gr.JSON(label="ویژگی‌های استخراج شده")
164
+ results_output = gr.Dataframe(
165
+ headers=["پروژه مرجع", "کد", "عنوان", "مقدار", "واحد"],
166
+ datatype=["str", "str", "str", "number", "str"]
167
+ )
168
+
169
+ estimate_btn.click(
170
+ estimator.estimate,
171
+ inputs=request_input,
172
+ outputs=[features_output, results_output]
173
+ )
174
+
175
+ with gr.Tab("🗃️ مشاهده دیتابیس"):
176
+ db_viewer = gr.JSON(label="محتوای دیتابیس")
177
+ refresh_btn = gr.Button("بروزرسانی نمایش")
178
+ refresh_btn.click(
179
+ lambda: estimator.db,
180
+ outputs=db_viewer
181
+ )
182
+
183
+ if __name__ == "__main__":
184
+ demo.launch()