Spaces:
Running
Running
Delete Operational_Instructions/DM_API_usage_example.ipynb
Browse files
Operational_Instructions/DM_API_usage_example.ipynb
DELETED
@@ -1,502 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "markdown",
|
5 |
-
"metadata": {},
|
6 |
-
"source": [
|
7 |
-
"**DataMorgana** is a powerful tool for generating synthetic question-answering data, useful for both evaluating and training question-answering systems.\n",
|
8 |
-
"\n",
|
9 |
-
"If you're using DataMorgana for the first time, it's recommended to start with the [DataMorgana Sandbox](https://platform.ai71.ai/playground). The Sandbox provides an intuitive UI for generating individual question-answer pairs interactively.\n",
|
10 |
-
"\n",
|
11 |
-
"In this notebook, we'll explore how to use the DataMorgana API to generate large-scale synthetic question-answering data on FineWeb.\n",
|
12 |
-
"\n",
|
13 |
-
"For the full API documentation, refer to [this link](https://api.ai71.ai/redoc#tag/Synthetic-Conversations)."
|
14 |
-
]
|
15 |
-
},
|
16 |
-
{
|
17 |
-
"cell_type": "code",
|
18 |
-
"execution_count": 11,
|
19 |
-
"metadata": {},
|
20 |
-
"outputs": [],
|
21 |
-
"source": [
|
22 |
-
"import json\n",
|
23 |
-
"import time\n",
|
24 |
-
"from typing import Dict, List\n",
|
25 |
-
"\n",
|
26 |
-
"import requests\n",
|
27 |
-
"\n",
|
28 |
-
"BASE_URL = \"https://api.ai71.ai/v1/\""
|
29 |
-
]
|
30 |
-
},
|
31 |
-
{
|
32 |
-
"cell_type": "markdown",
|
33 |
-
"metadata": {},
|
34 |
-
"source": [
|
35 |
-
"First, ensure that you have an API key for the AI71 platform."
|
36 |
-
]
|
37 |
-
},
|
38 |
-
{
|
39 |
-
"cell_type": "code",
|
40 |
-
"execution_count": 12,
|
41 |
-
"metadata": {},
|
42 |
-
"outputs": [],
|
43 |
-
"source": [
|
44 |
-
"API_KEY = # Your API key"
|
45 |
-
]
|
46 |
-
},
|
47 |
-
{
|
48 |
-
"cell_type": "markdown",
|
49 |
-
"metadata": {},
|
50 |
-
"source": [
|
51 |
-
"The generation of the data is done using LLMs, which is costly. Therefore, you will have a limited amount of credits - each credit corresponds to a single generated question. \n",
|
52 |
-
"\n",
|
53 |
-
"You can use the `check_budget` endpoint to see the remaining credits for your organization."
|
54 |
-
]
|
55 |
-
},
|
56 |
-
{
|
57 |
-
"cell_type": "code",
|
58 |
-
"execution_count": 13,
|
59 |
-
"metadata": {},
|
60 |
-
"outputs": [],
|
61 |
-
"source": [
|
62 |
-
"def check_budget():\n",
|
63 |
-
" resp = requests.get(\n",
|
64 |
-
" f\"{BASE_URL}check_budget\",\n",
|
65 |
-
" headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n",
|
66 |
-
" )\n",
|
67 |
-
" resp.raise_for_status()\n",
|
68 |
-
" print(json.dumps(resp.json(), indent=4))"
|
69 |
-
]
|
70 |
-
},
|
71 |
-
{
|
72 |
-
"cell_type": "code",
|
73 |
-
"execution_count": 14,
|
74 |
-
"metadata": {},
|
75 |
-
"outputs": [
|
76 |
-
{
|
77 |
-
"name": "stdout",
|
78 |
-
"output_type": "stream",
|
79 |
-
"text": [
|
80 |
-
"{\n",
|
81 |
-
" \"remaining_budget\": 9987\n",
|
82 |
-
"}\n"
|
83 |
-
]
|
84 |
-
}
|
85 |
-
],
|
86 |
-
"source": [
|
87 |
-
"check_budget()"
|
88 |
-
]
|
89 |
-
},
|
90 |
-
{
|
91 |
-
"cell_type": "markdown",
|
92 |
-
"metadata": {},
|
93 |
-
"source": [
|
94 |
-
"Now, let's see how to generate questions using the `bulk_generation` endpoint.\n",
|
95 |
-
"\n",
|
96 |
-
"This endpoint accepts three arguments: `n_questions`, `question_categorizations`, and `user_categorizations`.\n",
|
97 |
-
"\n",
|
98 |
-
"Since the endpoint is **asynchronous**, it returns only a `request_id`. To retrieve the generated questions once they are ready, we need to use the `fetch_generation_results` endpoint with the corresponding `request_id`."
|
99 |
-
]
|
100 |
-
},
|
101 |
-
{
|
102 |
-
"cell_type": "code",
|
103 |
-
"execution_count": 31,
|
104 |
-
"metadata": {},
|
105 |
-
"outputs": [],
|
106 |
-
"source": [
|
107 |
-
"def bulk_generate(n_questions: int, question_categorizations: List[Dict], user_categorizations: List[Dict]):\n",
|
108 |
-
" resp = requests.post(\n",
|
109 |
-
" f\"{BASE_URL}bulk_generation\",\n",
|
110 |
-
" headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n",
|
111 |
-
" json={\n",
|
112 |
-
" \"n_questions\": n_questions,\n",
|
113 |
-
" \"question_categorizations\": question_categorizations,\n",
|
114 |
-
" \"user_categorizations\": user_categorizations\n",
|
115 |
-
" }\n",
|
116 |
-
" )\n",
|
117 |
-
" resp.raise_for_status()\n",
|
118 |
-
" request_id = resp.json()[\"request_id\"]\n",
|
119 |
-
" print(json.dumps(resp.json(), indent=4))\n",
|
120 |
-
"\n",
|
121 |
-
" result = wait_for_generation_to_finish(request_id)\n",
|
122 |
-
" return result\n",
|
123 |
-
"\n",
|
124 |
-
"\n",
|
125 |
-
"def wait_for_generation_to_finish(request_id: str):\n",
|
126 |
-
" while True:\n",
|
127 |
-
" resp = requests.get(\n",
|
128 |
-
" f\"{BASE_URL}fetch_generation_results\",\n",
|
129 |
-
" headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n",
|
130 |
-
" params={\"request_id\": request_id},\n",
|
131 |
-
" )\n",
|
132 |
-
" resp.raise_for_status()\n",
|
133 |
-
" if resp.json()[\"status\"] == \"completed\":\n",
|
134 |
-
" print(json.dumps(resp.json(), indent=4))\n",
|
135 |
-
" return resp.json()\n",
|
136 |
-
" else:\n",
|
137 |
-
" print(\"Waiting for generation to finish...\")\n",
|
138 |
-
" time.sleep(5)"
|
139 |
-
]
|
140 |
-
},
|
141 |
-
{
|
142 |
-
"cell_type": "markdown",
|
143 |
-
"metadata": {},
|
144 |
-
"source": [
|
145 |
-
"Let's call the `bulk_generation` endpoint. In this example, we will define two question categorizations and one user categorization. \n",
|
146 |
-
"\n",
|
147 |
-
"When defining categorizations, keep in mind: \n",
|
148 |
-
"\n",
|
149 |
-
"- You can create your own categorizations—these are just examples. \n",
|
150 |
-
"- Each categorization can include as many categories as you like, as long as their probabilities sum to 1. \n",
|
151 |
-
"- The **descriptions** of the categories are injected into the LLM prompt during question generation. To ensure high-quality outputs, it’s important to write them clearly and thoughtfully. We encourage you to first try your configurations in the Sandbox before using them to generate a large bulk of questions, to ensure you get the expected results.\n",
|
152 |
-
"\n",
|
153 |
-
"For the competition, you’ll want to evaluate and train your system on a diverse set of questions, since you won’t know in advance what types of questions will appear in the test. Keep in mind that the categorizations used in this notebook are just examples and will not correspond to those used to generate the actual test set."
|
154 |
-
]
|
155 |
-
},
|
156 |
-
{
|
157 |
-
"cell_type": "code",
|
158 |
-
"execution_count": 28,
|
159 |
-
"metadata": {},
|
160 |
-
"outputs": [],
|
161 |
-
"source": [
|
162 |
-
"question_length_categorization = {\n",
|
163 |
-
" \"categorization_name\": \"question_length\",\n",
|
164 |
-
" \"categories\": [\n",
|
165 |
-
" {\n",
|
166 |
-
" \"name\": \"short\",\n",
|
167 |
-
" \"description\": \"a short question with no more than 6 words.\",\n",
|
168 |
-
" \"probability\": 0.4\n",
|
169 |
-
" },\n",
|
170 |
-
" {\n",
|
171 |
-
" \"name\": \"long\",\n",
|
172 |
-
" \"description\": \"a long question with at least 7 words.\",\n",
|
173 |
-
" \"probability\": 0.6\n",
|
174 |
-
" }\n",
|
175 |
-
" ]\n",
|
176 |
-
"}\n",
|
177 |
-
"\n",
|
178 |
-
"question_formulation_categorization = {\n",
|
179 |
-
" \"categorization_name\": \"question_formulation\",\n",
|
180 |
-
" \"categories\": [\n",
|
181 |
-
" {\n",
|
182 |
-
" \"name\": \"natural\",\n",
|
183 |
-
" \"description\": \"phrased in the way people typically speak, reflecting everyday language use, without formal or artificial structure.\",\n",
|
184 |
-
" \"probability\": 0.8\n",
|
185 |
-
" },\n",
|
186 |
-
" {\n",
|
187 |
-
" \"name\": \"search query\",\n",
|
188 |
-
" \"description\": \"phrased as a typed web query for search engines (only keywords, without punctuation and without a natural-sounding structure).\",\n",
|
189 |
-
" \"probability\": 0.2\n",
|
190 |
-
" }\n",
|
191 |
-
" ]\n",
|
192 |
-
"}\n",
|
193 |
-
"\n",
|
194 |
-
"user_expertise_categorization = {\n",
|
195 |
-
" \"categorization_name\": \"user_expertise\",\n",
|
196 |
-
" \"categories\": [\n",
|
197 |
-
" {\n",
|
198 |
-
" \"name\": \"expert\",\n",
|
199 |
-
" \"description\": \"an expert of the subject discussed in the document, therefore he asks complex questions.\",\n",
|
200 |
-
" \"probability\": 0.8\n",
|
201 |
-
" },\n",
|
202 |
-
" {\n",
|
203 |
-
" \"name\": \"common person\",\n",
|
204 |
-
" \"description\": \"a common person who is not expert of the subject discussed in the document, therefore he asks basic questions.\",\n",
|
205 |
-
" \"probability\": 0.2\n",
|
206 |
-
" }\n",
|
207 |
-
" ]\n",
|
208 |
-
"}"
|
209 |
-
]
|
210 |
-
},
|
211 |
-
{
|
212 |
-
"cell_type": "markdown",
|
213 |
-
"metadata": {},
|
214 |
-
"source": [
|
215 |
-
"For example, let's use these categorizations to generate 5 questions."
|
216 |
-
]
|
217 |
-
},
|
218 |
-
{
|
219 |
-
"cell_type": "code",
|
220 |
-
"execution_count": 37,
|
221 |
-
"metadata": {},
|
222 |
-
"outputs": [
|
223 |
-
{
|
224 |
-
"name": "stdout",
|
225 |
-
"output_type": "stream",
|
226 |
-
"text": [
|
227 |
-
"{\n",
|
228 |
-
" \"request_id\": \"5d5f6002-2395-4ff9-95a2-83c37947f9ee\",\n",
|
229 |
-
" \"type\": \"async\"\n",
|
230 |
-
"}\n",
|
231 |
-
"Waiting for generation to finish...\n",
|
232 |
-
"Waiting for generation to finish...\n",
|
233 |
-
"Waiting for generation to finish...\n",
|
234 |
-
"Waiting for generation to finish...\n",
|
235 |
-
"Waiting for generation to finish...\n",
|
236 |
-
"Waiting for generation to finish...\n",
|
237 |
-
"Waiting for generation to finish...\n",
|
238 |
-
"Waiting for generation to finish...\n",
|
239 |
-
"{\n",
|
240 |
-
" \"status\": \"completed\",\n",
|
241 |
-
" \"file\": \"https://s3.amazonaws.com/data.aiir/data_morgana/web_api/results_id_d01f3d5e-9cef-4be8-a311-8b07d3a22c6f_user_id_ded43e4d-7723-49d3-ad51-6636cf5aefd2.jsonl?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIA2UC3AHBFWKQ2GES5%2F20250204%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250204T091912Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEA4aCXVzLWVhc3QtMSJIMEYCIQDtXc99Td%2BZFZ5JRPTjV9GHEB7zKrsxhjodL5WmngqN7AIhAM7Cp7PiP%2FvHEfZ0LYKeps6T7nTAKmBZJqy2wNJmbfW%2FKrsFCCcQABoMNzMwMzM1Mjk1NTYzIgy2SkG3NP09ZldZskwqmAVLZLbPkvHnGbkiGqacmLPE5%2FpMud8ZCJUcKedwpv4uu0R5FhbxEhWGWg2pXp%2Fsgz5mYqQkowG%2BdId0PcrhDwW%2FLD0SCVmd0P6Bp3ha5FCNp4ssvl4q6Mozbfq7U%2FBeOAvrDJQg1Z3ofOp%2FxVS%2BgVkRleRwhS36cOWaTeDaAMyIYJNmEnYkkBQ%2FzRTwWkaw0uID2sCVgHRELPE1k9U99PaQ0xWizWX3HnoLjBIsILRSnDYhqm%2B8Klttf4keD093tqLl3U6Clcd0nCEsLpHlpK8ScytwM8RrMbMdiydDtXcM2FsgLQtUA5Ks28qjBxO47C7s8CR4Oop3TS%2BcpWacHDlYEjCX6pTyyu5hhcTTzpl4SkCZ%2FxmQSIKoPy0GRjudzpeAficf9dSmdoCWH3kkeLPa1j6rWpGzTtqldm3lHfWZKOj191blFSF4r2hy95y64hu8EomFf2r3vkQAXC2ZN4DtbFA5MgTRo37tr0nlu%2Bnfxer72dJA9V8SAInQYP9nnFZdJilgTNUdD2E4jdhVz7oZGtWpJhiuYOTDD7%2B4UezNf3idDgBdYZ8bbt2ENCcMKgvpq89TezsPr3BOPux2sh4Y9JvN0rqsvoYu28eVfrGJC6JNL14s9SUy7FnTAY8lCIvHTGjXlVG0nQsSiEJwRG56C4TY77zO4HsReMe9%2B6Rl7s3siB%2B8atqhPhwZrdypOUbmltv8uWjtxHDwuDnaM5yJLTbFKoOK6CpKv8EC16TjszENlAYTAkUlUdvVlseZx80cAVSa7mtQvEEclR9namYo3Wkv6UlKXSYK5ir%2BWavTIE1tnyNBtKp37aTZJr9nmQNund1L6G4bj855NzeFvga0RA58UEQ7dFw0gRysOP7mgU1zsPP%2FZFJzMKHThr0GOrABQuCeKIWKait%2F0Q1YIjaq1jmibSqUI7pLveuxH3Nl3VXeQorntgj3Ucq7GBnZ9Y5rGCrOkDVsepOWAP9piZEBIiwGo7Gp%2BZfmUg%2B0qf9lVGsKVeJtbvpJTFyhHLrPdGMllIg7aq4fqjnXUyyHHlplwphe3ezKYYHTcAbJINGt95Ed5K3zBSe0DqNdiY9bpVrveIbcWU829IJXp4r939aH6pNuwZ3jlFXMAw2%2FY4BDk6g%3D&X-Amz-Signature=6e135cdd7cf2751d2e9231d04ad9a049ef9f1ac8c4fc23a83c42043eca8f870b\",\n",
|
242 |
-
" \"credits\": 5\n",
|
243 |
-
"}\n"
|
244 |
-
]
|
245 |
-
}
|
246 |
-
],
|
247 |
-
"source": [
|
248 |
-
"results = bulk_generate(n_questions=5,\n",
|
249 |
-
" question_categorizations=[question_length_categorization, question_formulation_categorization],\n",
|
250 |
-
" user_categorizations=[user_expertise_categorization]\n",
|
251 |
-
" )"
|
252 |
-
]
|
253 |
-
},
|
254 |
-
{
|
255 |
-
"cell_type": "markdown",
|
256 |
-
"metadata": {},
|
257 |
-
"source": [
|
258 |
-
"The API response includes a link to the file where the generated results are stored. \n",
|
259 |
-
"This link is valid for 12 hours. If you need to access the file after that time, you can call `fetch_generation_results` again with the original `request_id` to receive a new link.\n",
|
260 |
-
"\n",
|
261 |
-
"Let's retrieve the data from the file and print the results."
|
262 |
-
]
|
263 |
-
},
|
264 |
-
{
|
265 |
-
"cell_type": "code",
|
266 |
-
"execution_count": 39,
|
267 |
-
"metadata": {},
|
268 |
-
"outputs": [],
|
269 |
-
"source": [
|
270 |
-
"response = requests.get(results[\"file\"])\n",
|
271 |
-
"qas = [json.loads(line) for line in response.text.splitlines()]"
|
272 |
-
]
|
273 |
-
},
|
274 |
-
{
|
275 |
-
"cell_type": "code",
|
276 |
-
"execution_count": 41,
|
277 |
-
"metadata": {},
|
278 |
-
"outputs": [
|
279 |
-
{
|
280 |
-
"data": {
|
281 |
-
"text/plain": [
|
282 |
-
"{'question': 'How does ADMS handle network faults?',\n",
|
283 |
-
" 'answer': 'The system assists grid operators by suggesting remedial actions and restoration processes to isolate and restore affected network sections quickly after a fault. It also uses smart meter data for outage prediction, fault detection and clearance.',\n",
|
284 |
-
" 'context': [\"Siemens Smart Grid has introduced a comprehensive distribution management system specifically developed for enhancing and expanding smarter grids. Spectrum Power™ ADMS (Advanced Distribution Management System) combines SCADA (Supervisory Control and Data Acquisition), outage management, and fault and network analysis functions for the first time on a software platform within a consolidated user environment, the first of its kind in North America. This simplifies workflows and facilitates efficient data management. The system also allows network operators to not only control and monitor their distribution network more reliably, but also track and restore outages and carry out maintenance and repair work more efficiently.\\n“Siemens has developed its ADMS solution for North America to specifically address these challenges and achieve wide-spread build out of the smart grid. Utilities will now be able to make data more actionable, increasing operational efficiency for the utility itself and improving power reliability for end users.”\\nBy suggesting remedial actions and restoration processes, the system assists grid operators in isolating and restoring the affected network sections as quickly as possible after a fault. The system also leverages the intelligent use of smart meter data for outage prediction, fault detection and clearance, and for managing distributed energy sources making Spectrum Power ADMS a key component for enhancing and expanding smart grids.\\n“Energy systems worldwide are facing a growing range of challenges, especially in power distribution management,” said Dr. Jan Mrosik, CEO of Siemens’ Smart Grid Division. “Siemens has developed its ADMS solution for North America to specifically address these challenges and achieve wide-spread build out of the smart grid. Utilities will now be able to make data more actionable, increasing operational efficiency for the utility itself and improving power reliability for end users.”\\nSince it was developed for integration in a service-oriented architecture (SOA), the system can make use of services and data from other IT systems, such as network data from geographic information systems or load profiles from meter data management systems. In the same way, other IT systems can access services and data in the distribution network management system, like information for customer information systems about downtime in case of a malfunction, or work orders or switching jobs for the workforce management system. The SOA focused design concept allows Spectrum Power ADMS to be integrated efficiently in the user's IT environment, promoting business process optimization and work process automation.\\nThe system provides the grid operator with the right tools to comply with the requirements of international reliability standards such as NERC CIP (North American Electric Reliability Corporation – Critical Infrastructure Protection) or those of the US federal agency NIST (National Institute of Standards and Technology). Interoperability standards such as IEC 61970 (CIM, Common Information Model) and IEC 61968 (system interfaces for distribution networks) have also been taken into account in the development of Spectrum Power ADMS in order to facilitate the IT integration of the system in an existing infrastructure.\\nThe introduction of Siemens Spectrum Power™ ADMS solution is the culmination of many successfully deployed distribution management solutions as well as Siemens ability to integrate these solutions with the utility’s existing infrastructure. The fully integrated operational environment available from Siemens enables improved monitoring, control and maintenance for a reliable and efficient distribution network.\"],\n",
|
285 |
-
" 'question_categories': [{'categorization_name': 'question_length',\n",
|
286 |
-
" 'category_name': 'short'},\n",
|
287 |
-
" {'categorization_name': 'question_formulation', 'category_name': 'natural'}],\n",
|
288 |
-
" 'user_categories': [{'categorization_name': 'user_expertise',\n",
|
289 |
-
" 'category_name': 'expert'}],\n",
|
290 |
-
" 'document_ids': ['<urn:uuid:db2e6b90-78a6-418b-9c12-f19144174c74>']}"
|
291 |
-
]
|
292 |
-
},
|
293 |
-
"execution_count": 41,
|
294 |
-
"metadata": {},
|
295 |
-
"output_type": "execute_result"
|
296 |
-
}
|
297 |
-
],
|
298 |
-
"source": [
|
299 |
-
"qas[0]"
|
300 |
-
]
|
301 |
-
},
|
302 |
-
{
|
303 |
-
"cell_type": "markdown",
|
304 |
-
"metadata": {},
|
305 |
-
"source": [
|
306 |
-
"Each generated result includes: \n",
|
307 |
-
"\n",
|
308 |
-
"- The generated **question** \n",
|
309 |
-
"- The generated **answer** \n",
|
310 |
-
"- The **context** (FineWeb documents) the question is based on \n",
|
311 |
-
"- The **IDs** of those documents \n",
|
312 |
-
"- The **question categories** used during generation \n",
|
313 |
-
"- The **user categories** used during generation "
|
314 |
-
]
|
315 |
-
},
|
316 |
-
{
|
317 |
-
"cell_type": "markdown",
|
318 |
-
"metadata": {},
|
319 |
-
"source": [
|
320 |
-
"You can retrieve all information about your requests (such as request id, status, configuration, etc.) using the `get_all_requests` endpoint."
|
321 |
-
]
|
322 |
-
},
|
323 |
-
{
|
324 |
-
"cell_type": "code",
|
325 |
-
"execution_count": 42,
|
326 |
-
"metadata": {},
|
327 |
-
"outputs": [],
|
328 |
-
"source": [
|
329 |
-
"def get_all_requests():\n",
|
330 |
-
" resp = requests.get(\n",
|
331 |
-
" f\"{BASE_URL}get_all_requests\",\n",
|
332 |
-
" headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n",
|
333 |
-
" )\n",
|
334 |
-
" resp.raise_for_status()\n",
|
335 |
-
" print(json.dumps(resp.json(), indent=4))"
|
336 |
-
]
|
337 |
-
},
|
338 |
-
{
|
339 |
-
"cell_type": "code",
|
340 |
-
"execution_count": null,
|
341 |
-
"metadata": {},
|
342 |
-
"outputs": [],
|
343 |
-
"source": [
|
344 |
-
"get_all_requests()"
|
345 |
-
]
|
346 |
-
},
|
347 |
-
{
|
348 |
-
"cell_type": "markdown",
|
349 |
-
"metadata": {},
|
350 |
-
"source": [
|
351 |
-
"#### Generating questions from **document pairs**\n",
|
352 |
-
"DataMorgana supports generating multi-doc questions: questions where the information required to answer them is split across two documents.\n",
|
353 |
-
"\n",
|
354 |
-
"In DataMorgana, the **multi-doc** concept is associated with the **question category** concept. A question category can be designated as a multi-doc category by setting the `is_multi_doc` field to be `true` (its default value is `false` when not specified).\n",
|
355 |
-
"\n",
|
356 |
-
"Note that the `is_multi_doc` field applies only to question categories, and not to user categories.\n",
|
357 |
-
"\n",
|
358 |
-
"When writing the description for a multi-doc question category, it is important to clearly specify how the two documents are used to create the question.\n",
|
359 |
-
"\n",
|
360 |
-
"Below is an illustrative example of a categorization with two multi-doc question categories, each with a well-written description:"
|
361 |
-
]
|
362 |
-
},
|
363 |
-
{
|
364 |
-
"cell_type": "code",
|
365 |
-
"execution_count": 32,
|
366 |
-
"metadata": {},
|
367 |
-
"outputs": [],
|
368 |
-
"source": [
|
369 |
-
"multi_doc_categorization = {\n",
|
370 |
-
" \"categorization_name\": \"multi-doc\",\n",
|
371 |
-
" \"categories\": [\n",
|
372 |
-
" {\n",
|
373 |
-
" \"name\": \"comparison\",\n",
|
374 |
-
" \"description\": \"a comparison question that requires comparing two related concepts or entities. The comparison must be natural and reasonable, i.e., comparing two entities by a common attribute which is meaningful and relevant to both entities. For example: 'Who is older, Glenn Hughes or Ross Lynch?', 'Are Pizhou and Jiujiang in the same province?', 'Pyotr Ilyich Tchaikovsky and Giuseppe Verdi have this profession in common'. The information required to answer the question needs to come from two documents, specifically, the first document must provide information about the first entity/concept, while the second must provide information about the second entity/concept.\",\n",
|
375 |
-
" \"probability\": 0.5,\n",
|
376 |
-
" \"is_multi_doc\": True\n",
|
377 |
-
" },\n",
|
378 |
-
" {\n",
|
379 |
-
" \"name\": \"multi-aspect\",\n",
|
380 |
-
" \"description\": \"A question about two different aspects of the same entity/concept. For example: 'What are the advantages of AI-powered diagnostics, and what are the associated risks of bias in medical decision-making?', 'How do cryptocurrencies enable financial inclusion, and what are the security risks associated with them?'. The information required to answer the question needs to come from two documents, specifically, the first document must provide information about the first aspect, while the second must provide information about the second aspect.\",\n",
|
381 |
-
" \"probability\": 0.5,\n",
|
382 |
-
" \"is_multi_doc\": True\n",
|
383 |
-
" }\n",
|
384 |
-
" ]\n",
|
385 |
-
"}"
|
386 |
-
]
|
387 |
-
},
|
388 |
-
{
|
389 |
-
"cell_type": "markdown",
|
390 |
-
"metadata": {},
|
391 |
-
"source": [
|
392 |
-
"Let's use it jointly with `question_length_categorization` to generate some questions:"
|
393 |
-
]
|
394 |
-
},
|
395 |
-
{
|
396 |
-
"cell_type": "code",
|
397 |
-
"execution_count": 10,
|
398 |
-
"metadata": {},
|
399 |
-
"outputs": [
|
400 |
-
{
|
401 |
-
"name": "stdout",
|
402 |
-
"output_type": "stream",
|
403 |
-
"text": [
|
404 |
-
"{\n",
|
405 |
-
" \"request_id\": \"ed2988c1-2417-4a89-8ad9-62824869ed99\",\n",
|
406 |
-
" \"type\": \"async\"\n",
|
407 |
-
"}\n",
|
408 |
-
"Waiting for generation to finish...\n",
|
409 |
-
"Waiting for generation to finish...\n",
|
410 |
-
"Waiting for generation to finish...\n",
|
411 |
-
"Waiting for generation to finish...\n",
|
412 |
-
"Waiting for generation to finish...\n",
|
413 |
-
"Waiting for generation to finish...\n",
|
414 |
-
"Waiting for generation to finish...\n",
|
415 |
-
"{\n",
|
416 |
-
" \"status\": \"completed\",\n",
|
417 |
-
" \"file\": \"https://s3.amazonaws.com/data.aiir/data_morgana/web_api/results_id_ec7348c4-536e-4b7c-a863-7a26dbc22a79_user_id_ded43e4d-7723-49d3-ad51-6636cf5aefd2.jsonl?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIA2UC3AHBFYKGKCUUJ%2F20250401%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250401T131852Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEFEaCXVzLWVhc3QtMSJHMEUCIBv7O22KjiLt6HRIWy%2Fcen14boV1UkGk5U7oW5cMN7RXAiEA2i8jPR3Ljo88cFlN7Kki6aC568p4O30Fc1biw%2BEQSvIqxAUIuv%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FARAAGgw3MzAzMzUyOTU1NjMiDN6fHSMk8pnM%2BVgIPCqYBWVPpbEkCqk%2Fu44P8QVXy7Ol7mGs63gze5DISEbXcVmhHrvL6iK9w%2FVFT2JF%2F3U5q4zRnqcwwXa5O8ghh8bN55SOKMCeEelFhSFkJRKZmjTq1K0U1Gaz3yFSDeBtEP9A7ZY3kSCNb4VwDm2JNlZ0TEXBGT8pE12tlK8rFOGSozI%2Bw%2BYOWqGG4eh5I6%2FFDIScdAL99UECe92tMgtspHHCa%2F35fLDrBRC2%2FWo3U%2Fob0hsgKcJlSSJFxJbF2ENUqfG58v8RbMbq5Wv6PPGsplx86aHFGBvi0YoyAKhr%2BYMIAtyVgU5lJw7LYj3St2142dbtR7tnhp1SpfoPXFEicvWQu9KHevAh2gofv29zh%2ByC8EWvepyvh6aoCKcGZzpxh3xRebEM9bAcW6WgX9Q%2BkocwxfiX7A9HOmgFIMC2RtJphkGRVb3a8dD42U4cgp3V%2FyKd%2BgEAhYyNHxJkajNd7xBOIJ74bxrni99NWui0wluueE6HtB9VDosxY3fUzg5GODmgWRYxT0VKaPxVxu6zbQUm5ZTwWw6tQfbEqOUWoAGZcP9SrYKH%2Fs846oxgy%2Bdi2sekcxP7whCblR0ps4bmwr5n%2FALF02B%2BiXcMG2mjkLgS%2FV8Qbui8msTru164%2FsOvciCgIm%2FHBFld0%2BDBuIwVAeb9FTnwAytM4r%2Ftw4gt%2FNYoQzl6FvydEdqldods9Ao3ZBcLgUjkCW1onqgZDH5yZgBPncupqLmKQTxTKoorfNhX%2BbzL%2BW3RT9yS0IEDQUePdJV1O4yls%2BIuOa7GFRj4nDQgPr5O1P1ufNNfYMHzGUmcEXkKgUE6Vrgi%2BS%2FsdJz2jt0YmsDwbUMQ4ni6IkuThBcPGzTPYWs6GaCN%2FUOrksSZlVCz%2FJ59okrLWtkwzsauvwY6sQG3JPLhlxjQG%2BkFqY8304abwSjnAOrRMrSX6RhU0rE7jFpf2VvB17eMCKZatq47EzxOSsuQ%2BNPejljYpEPCNuzF%2BuVbOcsuQWNeY29IrTHdmMI3YVthoyDmFchb4z9Nm5aYndriMQLlkHi1LuqOrBvikPYTspCZmdKsASk%2FK%2FHMv2cgPAydWR4DuABs1XZ%2FNJ82kJXNm5Y3v1fFhB6OaZBnw2zvQocoLC%2Bd%2BityXu1Cf7I%3D&X-Amz-Signature=8949b86cf717844e7533d57b32fc00e61a90da6510c781c90704fcac6e4846a6\",\n",
|
418 |
-
" \"credits\": 5\n",
|
419 |
-
"}\n"
|
420 |
-
]
|
421 |
-
}
|
422 |
-
],
|
423 |
-
"source": [
|
424 |
-
"results = bulk_generate(n_questions=5,\n",
|
425 |
-
" question_categorizations=[question_length_categorization, multi_doc_categorization],\n",
|
426 |
-
" user_categorizations=[]\n",
|
427 |
-
" )"
|
428 |
-
]
|
429 |
-
},
|
430 |
-
{
|
431 |
-
"cell_type": "code",
|
432 |
-
"execution_count": 25,
|
433 |
-
"metadata": {},
|
434 |
-
"outputs": [],
|
435 |
-
"source": [
|
436 |
-
"response = requests.get(results[\"file\"])\n",
|
437 |
-
"qas = [json.loads(line) for line in response.text.splitlines()]"
|
438 |
-
]
|
439 |
-
},
|
440 |
-
{
|
441 |
-
"cell_type": "markdown",
|
442 |
-
"metadata": {},
|
443 |
-
"source": [
|
444 |
-
"Each generated question has two supporting documents:"
|
445 |
-
]
|
446 |
-
},
|
447 |
-
{
|
448 |
-
"cell_type": "code",
|
449 |
-
"execution_count": 26,
|
450 |
-
"metadata": {},
|
451 |
-
"outputs": [
|
452 |
-
{
|
453 |
-
"name": "stdout",
|
454 |
-
"output_type": "stream",
|
455 |
-
"text": [
|
456 |
-
"Categories: [{'categorization_name': 'question_length', 'category_name': 'long'}, {'categorization_name': 'multi-doc', 'category_name': 'comparison'}]\n",
|
457 |
-
"Question: Who published their most influential work earlier: John von Neumann with his game theory book or Alessandro Alessandroni with his iconic western whistle performance?\n",
|
458 |
-
"Answer: John von Neumann published his influential game theory book 'Theory of Games and Economic Behavior' in 1944, while Alessandro Alessandroni's iconic whistle performance appeared in 'For a Few Dollars More' in 1965, making von Neumann's publication about 21 years earlier.\n",
|
459 |
-
"Supporting documents:\n",
|
460 |
-
"1)\n",
|
461 |
-
"doc_id='<urn:uuid:644a202a-556f-4fd8-aa0f-54e7265aea6a>'\n",
|
462 |
-
"content='In 1944, the economist, physicist, mathematician and computer scientist John von Neumann published a book that became a sensation, at least among mathematicians – Theory of Games and Economic Behavior. Written with a colleague, Oskar Morgenstern, this volume of nearly biblical proportions is so dense and littered with mathematics that only a game-theory specialist could understand it – and some of them struggled.\\nEven so, game theory has spread far beyond the boundaries of mathematics to become a valuable tool for explaining human behaviour. It’s used by diplomats, biologists, psychologists, economists and many others in business, research and global politics.\\nGame theory can also be a useful tool for parents. Children can be tough negotiators, as parents know. And the stakes are high: the outcome of negotiations between parents and their children can affect a family’s happiness and the children’s futures.\\nDespite its sometimes complicated mathematics, game theory is simple to explain: it’s the science of strategic thinking. Game theory does not cover all games, but only those in which an opponent’s or negotiator’s strategy affects your next move. It has nothing to do with solitaire, in which your ‘opponent’ – a deck of cards – has no strategy. Chess, on the other hand, is a beautiful example of a game-theory game, where two crafty strategists are continually trying to anticipate and block the other’s likely moves.\\nEncouraging cooperation between children is a wonderful game-theory example. Some years ago, Robert Axelrod, a game theorist at the University of Michigan, asked the following question: when should a person cooperate, and when should a person be selfish, in an ongoing interaction with another? He set up a computer competition among game theorists, and he was astonished at what he found. The most sophisticated solutions failed to beat something called tit-for-tat, in which each player responds by doing what the other did. If the first cooperates, so does the second. And so on and so forth. If the first does not cooperate, neither does the second.\\nAuctions are yet another subject of game-theory research, and useful for parents. Suppose your children all want to control the TV remote. Set up what’s known as a sealed-bid, second-price auction. Each secretly writes down what he or she is willing to pay. When the papers are opened, the highest bidder wins the right to buy the remote at $1 plus the second-highest bid. It’s far superior to a coin flip because the person who most wanted the remote got it.\\nGame-theory deals depend upon fairness and, often, so do dealings between parents and children. Children are consumed with the idea of fairness. If a candy bar meant to be shared by two isn’t broken exactly in half, the one who gets the smaller piece will howl. Game theory offers parents a way around this.\\nSuppose you break the candy bar into two pieces that are almost the same size, but not quite. And your children can see that they are different. You could do something that seems eminently fair: toss a coin. Your children can recognise the fairness in tossing a coin; nobody controls the outcome. What could be simpler? You toss the coin into the air. The winner gets the slightly bigger piece of candy; the loser gets the other. But something changes when the coin hits the floor. The winner now believes the decision was completely fair; the loser demands that he get a do-over. To him, it doesn’t seem fair at all.\\nThe problem here turns on the meaning of fairness. The coin toss is fair, as we usually understand that. So what is the problem? In game-theory terms, the outcome was not envy-free. The loser desperately envies the winner. It’s not a very satisfactory solution for you or for one of your two children.\\nHere’s a way to get a much better outcome. Suppose you have the remains of a birthday cake you want to divide between your two children. You have the same problem as you did with the candy: it’s difficult to cut two equal pieces. So you turn to the technique we call ‘I Cut, You Pick’: your daughter cuts the cake, and your son picks the half he wants.\\nYour daughter will be as careful as possible to cut the cake into identical halves, because if she doesn’t, she will get the smaller one. Because it might not be possible to cut the cake into two exact halves, you designate your son to make the cut the next time you have cake. And you continue to take turns. This is fair, and game theory shows that people will recognise it to be fair. It’s far superior to the brutal coin toss.\\nNow let’s make it a bit more difficult. The cake is half chocolate and half vanilla. Your son loves chocolate; your daughter prefers vanilla. If your daughter cuts the cake in a way that gives each of them half of the chocolate and half of the vanilla, the cut is fair. Each piece is the same size. But neither child is entirely happy, because each got some cake they didn’t want. Turn the cut the other way – and divide it into a chocolate half for your son and a vanilla half for your daughter, and both are far happier. Both cuts were fair, but the cut into chocolate and vanilla halves demonstrated what’s called Pareto optimality. Each was not only fairly treated, but also got the best possible outcome.\\nGame theory can also be used to help the family to decide where to go on vacation, what to have for dinner, how siblings can learn to cooperate without mum or dad’s intervention – and many other problems that routinely turn up in the family.\\nGame theory is a gift of evolution, which sculpted us to behave according to precise and illuminating mathematical rules. We use it all the time. Game-theory parenting is a way to help parents explicitly understand the rules and reflect on what the rules say about raising healthy and successful children. An understanding of game theory helps us become the parents we were meant to be. Parents and children might not be able to make their way through von Neumann’s often opaque book, but they don’t have to. They are all game theorists already. All they need are a few good rules. And that’s what game theory provides.'\n",
|
463 |
-
"\n",
|
464 |
-
"2)\n",
|
465 |
-
"doc_id='<urn:uuid:1a728149-280f-4449-aa0c-f52566e200f4>'\n",
|
466 |
-
"content='Goodbye to Alessandro Alessandroni, the western world\\'s most famous ‘whistle’\\nThe composer, conductor and arranger Alessandro Alessandroni died in Rome. He had just turned 92 years-old. Celebrated for his \\'whistle\\' which made many great soundtracks of the spaghetti western genre. \\'For a Few Dollars More\\' is its \\'booed\\' most iconic.\\nLa Repubblica ·\\nBy Valeria Rusconi and Ernesto Assante\\nMarch 27, 2017\\n\"It\\'s very simple. I phoned Ennio Morricone and he told me: \\'Sandro, come down here for a moment, in the room, we need you to whistle. Well, it was really a whistle, nothing more, but think about what happened next ... When we saw the film, I have to admit that no one thought it would make a penny\". And instead. Instead the \\'whistling\\' really did change everything. Alessandro Alessandroni, the master - it is right to call him that - says the opening words of the most famous of his career and the most iconic of Western movies song that for a Fistful of Dollars, made up by Morricone, which made the film music of Sergio Leone - and practically made all the best western movies - even bigger. \"It was a great professional partnership, we had a wonderful collaboration,\" he told La Repubblica. Morricone, \"knew very well I could play the guitar and was the director of the choir and this was superb. And he knew very well that I could whistle. He had worked on A Fistful of Dollars and on other occasions. Why I chose him to whistle? by chance, I needed a whistle, I asked the musicians working with me who was able to whistle well and others I liked less. He had the courage to try\".\\nThe composer, conductor and arranger Alessandro Alessandroni died in Rome, in the city that gave him birth on March 18, 1925, on March 26th. He had just turned 92 years of age. The announcement came on the official Facebook page of the composer: \"It is with great sorrow that I inform you of the death yesterday of the master Alessandro Alessandroni born in Rome on March 18, 1925, composer, multi-instrumentalist, arranger and choir director. There will be a memorial service at his home in Namibia with music and musicians directed by his son Alex Jr. Alessandroni\".\\nAlessandroni approached music when he was still a boy. At the time he lived in the country of his mother, in the province of Viterbo. He was 11 years old and listened insistently, whenever he could to classical music. He began playing the guitar with assistance from a friend. The place is one of those details. He told in an interview to the blog Planet Hexacord: \"I started in the barber shop, because in small countries it is a reference point: there were the instruments, the guitar, the mandolin. They worked a little, but it sounded a lot. .. \". While he was attending the last year of high school he formed his first band, with whom he performed for local dance halls. Quick to learn, in a short time he become proficient on several instruments, which he alternates during his performances: as a teenager he already is able to play the guitar, the piano, the accordion, sax, flute, mandolin and sitar, one of the first Italians to try their hand on this complex stringed instrument. He obtained his diploma at the Conservatory in Rome, and found a job in the film production company Fonolux There he meets the great Nino Rota, his senior by 14 years, who wants him in his orchestra. Then came the whistle. It was almost by accident. Alessandroni, at some point, when Rota asked for a volunteer to whistle. Whistling become his new tool to play with and one of the moments that characterized the soundtracks of the Spaghetti Westerns. Music in effect: \"My whistle parts are on the staff,\" explained Alessandroni, \"and woe to miss the pitch, to make mistakes.\" That thought also by Federico Fellini, author of his soprannonme: Alessandroni for him was simply \"The Whistler\".\\nIn 1962 he founded the octet I Cantori Moderni, a formation that takes the place of his previous group, the Caravels Quartet. With him, the band is formed by soprano Edda Dell\\'Orso, Augustus Garden, Franco Cossacks, Nino Dei, Enzo Gioieni, Gianna Spagnuolo and, not the least, his wife Julia De Mutiis.\\nThe most important co-operation, long-lived and linked by a sincere esteem Alessandroni remains to this day one with Ennio Morricone: besides the famous whistle of For a Fistful of Dollars he also worked on For a Few Dollars More and The Good, the Bad and the Ugly. Alessandroni was used by all the most important Italian composers of the time, in the 1960s, such as Piero Umiliani, for which he sang along with his wife Giulia in great song Mah-na Mah-na, extracted from the soundtrack of Svezia inferno e paradiso by Louis Scattini (1968) and the master Armando Trovajoli. With the arrival of the seventies, for ARC of the RCA label which was dedicated to the ‘young Italian music’, between beats and \\'world exotico\\', a public-disc collection of twelve songs in the race to the edition of 1969 of Canzonissima. Are recorded, of course, the tune and work on the Hammond organ solo is credited to Ron Alexander, his pseudonym.\\nThe name of Alessandroni had become one of worship across the board, and had crossed generations and musical styles, especially he had conquered the library music enthusiasts. Among the last to want in their drive Baustelle, group of Montepulciano, who have chosen it for one of their best albums. \"Alessandro Alessandroni is the oldest guest,\" explained Francesco Bianconi, the singer, \"a wonderful eighty-four and played the sitar, accordion, acoustic guitar and he did blow the whistle\". The song title, not surprisingly, was Spaghetti Western. The Album, Amen.\\nBorn: 3/18/1925, Rome, Lazio, Italy\\nDied: 3/26/2017, Rome, Lazio, Italy\\nAlessandro Alessandroni’s westerns – composer, musician, whistler, choir:\\nA Fistful of Dollars – 1964 [guitar, whistle, choir]\\nMassacre at Marble City – 1964 [choir]\\nFor a Few Dollars More – 1965 [guitar, whistle]\\nThe Good, the Bad and the Ugly – 1966 [guitar]\\nSeven Dollars on the Red – 1966 [choir]\\nAny Gun Can Play – 1967 [composer]\\nPayment in Blood – 1967 [choir]\\nWanted – 1967 [choir]\\nOnce Upon a Time in the West – 1968 [whistle]\\nThe Wild and the Dirty – 1968 [composer]\\nEl Puro – 1969 [composer]\\nRaise Your Hands, Dead Man, You\\'re Under Arrest – 1971 [composer]\\nZorro the Invincible – 1971 [composer]\\nThe Crazy Bunch – 1974 [composer]\\nWhite Fang and the Gold Diggers – 1975 [composer]\\nWhite Fang and the Hunter – 1975 [composer]\\nLucky Luke – 1991 [whistle]\\nLucky Luke (TV) – 1991-1992 [whistle]'\n",
|
467 |
-
"\n"
|
468 |
-
]
|
469 |
-
}
|
470 |
-
],
|
471 |
-
"source": [
|
472 |
-
"print(f\"Categories: {qas[0][\"question_categories\"]}\")\n",
|
473 |
-
"print(f\"Question: {qas[0][\"question\"]}\")\n",
|
474 |
-
"print(f\"Answer: {qas[0][\"answer\"]}\")\n",
|
475 |
-
"print(\"Supporting documents:\")\n",
|
476 |
-
"for i, (doc_id, content) in enumerate(zip(qas[0][\"document_ids\"], qas[0][\"context\"], strict=True)):\n",
|
477 |
-
" print(f\"{i + 1})\\n{doc_id=}\\n{content=}\\n\")"
|
478 |
-
]
|
479 |
-
}
|
480 |
-
],
|
481 |
-
"metadata": {
|
482 |
-
"kernelspec": {
|
483 |
-
"display_name": ".venv",
|
484 |
-
"language": "python",
|
485 |
-
"name": "python3"
|
486 |
-
},
|
487 |
-
"language_info": {
|
488 |
-
"codemirror_mode": {
|
489 |
-
"name": "ipython",
|
490 |
-
"version": 3
|
491 |
-
},
|
492 |
-
"file_extension": ".py",
|
493 |
-
"mimetype": "text/x-python",
|
494 |
-
"name": "python",
|
495 |
-
"nbconvert_exporter": "python",
|
496 |
-
"pygments_lexer": "ipython3",
|
497 |
-
"version": "3.12.8"
|
498 |
-
}
|
499 |
-
},
|
500 |
-
"nbformat": 4,
|
501 |
-
"nbformat_minor": 2
|
502 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|