MikeMann commited on
Commit
d22fd24
·
1 Parent(s): fac6de6

added EvalDataset Generation

Browse files
app.py CHANGED
@@ -18,6 +18,8 @@ import torch
18
  import gradio as gr
19
  import threading
20
  import re
 
 
21
 
22
  from openai import OpenAI
23
  from langchain.text_splitter import RecursiveCharacterTextSplitter
@@ -410,7 +412,7 @@ class BSIChatbot:
410
  stepBackQuery = self.queryRemoteLLM(systemPrompt, query, False)
411
  return stepBackQuery
412
 
413
- def ragPromptNew(self, query, rerankingStep, history, stepBackPrompt):
414
  global rerankingModel
415
  prompt_in_chat_format = [
416
  {
@@ -458,9 +460,14 @@ class BSIChatbot:
458
 
459
  #def queryRemoteLLM(self, systemPrompt, query, summary):
460
 
461
- prompt_in_chat_format[-1]["content"] = prompt_in_chat_format[-1]["content"].format(
462
- question=query, context=context, history=history[:-1]
463
- )
 
 
 
 
 
464
  final_prompt = prompt_in_chat_format
465
 
466
  # final_prompt = prompt_in_chat_format[-1]["content"].format(
@@ -474,12 +481,21 @@ class BSIChatbot:
474
  match = re.findall(pattern, last_value)
475
  self.images = match
476
 
477
- stream = self.llm_client.chat.completions.create(
478
- messages=final_prompt,
479
- model=self.llm_remote_model,
480
- stream=True
481
- )
482
- return stream
 
 
 
 
 
 
 
 
 
483
  #@spaces.GPU
484
  def ragPromptRemote(self, query, rerankingStep, history, stepBackPrompt):
485
  global rerankingModel
@@ -666,7 +682,36 @@ class BSIChatbot:
666
  def launchGr(self):
667
  gr.Interface.from_pipeline(self.llmpipeline).launch()
668
 
669
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
670
 
671
  if __name__ == '__main__':
672
  #RAW_KNOWLEDGE_BASE = []
@@ -677,7 +722,7 @@ if __name__ == '__main__':
677
  #time.sleep(10)
678
 
679
  #{doc.page_content} [{doc.metadata}] => aktuellen Header in jeden Chunk embedden; Doc.Metadata retrieven
680
-
681
  renewEmbeddings = False
682
  reranking = True
683
  stepBackEnable = True
@@ -702,7 +747,8 @@ if __name__ == '__main__':
702
  #C: wie die Informationssicherheit im laufenden Betrieb aufrechterhalten und kontinuierlich verbessert werden kann,
703
  #D: effiziente Verfahren, um die allgemeinen Anforderungen des BSI-Standards 200-1 zu konkretisieren
704
  #""", True)
705
-
 
706
  #bot.launchGr()
707
 
708
  with gr.Blocks() as demo:
@@ -731,7 +777,7 @@ if __name__ == '__main__':
731
  print(f"DBG: ragQuery hist 0:{history[0].get('content')}")
732
  print(f"DBG: fullHistory: {history}" )
733
  #bot_response = bot.ragPromptRemote(history[-1].get('content'), reranking, history)
734
- bot_response = bot.ragPromptNew(history[-1].get('content'), reranking, history, stepBackEnable)
735
  history.append({"role": "assistant", "content": ""})
736
 
737
  image_gallery = returnImages()
 
18
  import gradio as gr
19
  import threading
20
  import re
21
+ import csv
22
+ import json
23
 
24
  from openai import OpenAI
25
  from langchain.text_splitter import RecursiveCharacterTextSplitter
 
412
  stepBackQuery = self.queryRemoteLLM(systemPrompt, query, False)
413
  return stepBackQuery
414
 
415
+ def ragPromptNew(self, query, rerankingStep, history, stepBackPrompt, returnContext):
416
  global rerankingModel
417
  prompt_in_chat_format = [
418
  {
 
460
 
461
  #def queryRemoteLLM(self, systemPrompt, query, summary):
462
 
463
+ if (history != None):
464
+ prompt_in_chat_format[-1]["content"] = prompt_in_chat_format[-1]["content"].format(
465
+ question=query, context=context, history=history[:-1]
466
+ )
467
+ else:
468
+ prompt_in_chat_format[-1]["content"] = prompt_in_chat_format[-1]["content"].format(
469
+ question=query, context=context, history="None"
470
+ )
471
  final_prompt = prompt_in_chat_format
472
 
473
  # final_prompt = prompt_in_chat_format[-1]["content"].format(
 
481
  match = re.findall(pattern, last_value)
482
  self.images = match
483
 
484
+ if (returnContext == False):
485
+ stream = self.llm_client.chat.completions.create(
486
+ messages=final_prompt,
487
+ model=self.llm_remote_model,
488
+ stream=True
489
+ )
490
+ return stream
491
+
492
+ else:
493
+ answer = self.llm_client.chat.completions.create(
494
+ messages=final_prompt,
495
+ model=self.llm_remote_model,
496
+ stream=False)
497
+ return answer, context
498
+
499
  #@spaces.GPU
500
  def ragPromptRemote(self, query, rerankingStep, history, stepBackPrompt):
501
  global rerankingModel
 
682
  def launchGr(self):
683
  gr.Interface.from_pipeline(self.llmpipeline).launch()
684
 
685
+ def generateEvalDataset(self):
686
+ filepath = "/home/user/app/docs/_eval/BSI_Lektion_Ground_Truth.CSV"
687
+ with open(filepath, mode='r') as file:
688
+ # Create a CSV reader with DictReader
689
+ csv_reader = csv.DictReader(file, delimiter="|")
690
+
691
+ # Initialize an empty list to store the dictionaries
692
+ data_list = []
693
+
694
+ # Iterate through each row in the CSV file
695
+ for row in csv_reader:
696
+ # Append each row (as a dictionary) to the list
697
+ data_list.append(row)
698
+
699
+ # Print the list of dictionaries
700
+ for data in data_list:
701
+ print(data)
702
+ data["Context"] = None
703
+ data["Answer"] = None
704
+ print(data)
705
+
706
+ for data in data_list[:3]:
707
+ #def ragPromptNew(self, query, rerankingStep, history, stepBackPrompt)
708
+ data["Answer"],data["Context"] = ragPromptNew(data["Frage"],True,None,True)
709
+ print(data)
710
+
711
+ with open('/home/user/app/docs/_eval/eval_dataset.json', 'w') as fout:
712
+ json.dump(data_list, fout)
713
+ # Print full response as JSON
714
+ # print(chat_completion)
715
 
716
  if __name__ == '__main__':
717
  #RAW_KNOWLEDGE_BASE = []
 
722
  #time.sleep(10)
723
 
724
  #{doc.page_content} [{doc.metadata}] => aktuellen Header in jeden Chunk embedden; Doc.Metadata retrieven
725
+ eval = True # generates Eval Dataset
726
  renewEmbeddings = False
727
  reranking = True
728
  stepBackEnable = True
 
747
  #C: wie die Informationssicherheit im laufenden Betrieb aufrechterhalten und kontinuierlich verbessert werden kann,
748
  #D: effiziente Verfahren, um die allgemeinen Anforderungen des BSI-Standards 200-1 zu konkretisieren
749
  #""", True)
750
+ if (eval==True):
751
+ bot.generateEvalDataset()
752
  #bot.launchGr()
753
 
754
  with gr.Blocks() as demo:
 
777
  print(f"DBG: ragQuery hist 0:{history[0].get('content')}")
778
  print(f"DBG: fullHistory: {history}" )
779
  #bot_response = bot.ragPromptRemote(history[-1].get('content'), reranking, history)
780
+ bot_response = bot.ragPromptNew(history[-1].get('content'), reranking, history, stepBackEnable, False)
781
  history.append({"role": "assistant", "content": ""})
782
 
783
  image_gallery = returnImages()
docs/_eval/BSI_Lektion_Ground_Truth.CSV ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Frage_index|Lektion|Frage|Ground_truth
2
+ 1|2|Welches Modell liegt dem in BSI-Standard 200-1 beschriebenen Sicherheitsprozess zugrunde?|ein Zyklus aus den Schritten Plan, Do, Check und Act,ein auf stetige Verbesserung angelegtes Modell
3
+ 2|2|Was sollte eine Leitlinie zur Informationssicherheit enthalten?|Aussagen zur Bedeutung der Informationssicherheit f�r die betroffene Institution,grundlegende Regelungen zur Organisation der Informationssicherheit
4
+ 3|2|Welche Aufgaben haben �blicherweise Informationssicherheitsbeauftragte?|die Entwicklung von Sicherheitskonzepten zu koordinieren,der Leitungsebene �ber den Stand der Informationssicherheit zu berichten
5
+ 4|2|Wie setzt sich ein IS-Management-Team geeignet zusammen?|Die Gesch�ftsleitung setzt das Team aus Verantwortlichen f�r bestimmte IT-Systeme, Anwendungen, Datenschutz und IT-Service und (sofern vorhanden) dem ICS-ISB zusammen.
6
+ 5|2|Wer ist f�r die Freigabe der Leitlinie zur Informationssicherheit verantwortlich?|die Unternehmens- oder Beh�rdenleitung
7
+ 6|2|Warum kann es sinnvoll sein, sich f�r eine Sicherheitskonzeption gem�� der Basis-Absicherung zu entscheiden?|Weil schnell Informationssicherheit umgesetzt werden muss und die Basis-Absicherung hierf�r einen geeigneten Einstieg bietet.,Weil Informationssicherheit Schritt f�r Schritt umgesetzt werden soll. Mittelfristig kann das Sicherheitskonzept nach Standard-Absicherung ausgebaut werden.
8
+ 1|3|Welche Ziele verfolgt die Strukturanalyse im Rahmen der IT-Grundschutz-Methodik?|die Ermittlung der Objekte, die in einem Sicherheitskonzept zu ber�cksichtigen sind; die angemessene Zusammenfassung von Objekten, f�r die gleiche Sicherheitsma�nahmen angewendet werden k�nnen
9
+ 2|3|Welche Informationen sollten Netzpl�ne enthalten, die f�r die Strukturanalyse ben�tigt werden?|die Art der Vernetzung der IT-Systeme eines Informationsverbundes; die Au�enverbindungen des Netzes eines Informationsverbundes; die Art der IT-Systeme eines Informationsverbundes
10
+ 3|3|Wann bietet es sich an, IT-Systeme bei der Strukturanalyse zu gruppieren?|wenn diese den gleichen Schutzbedarf und �hnliche Eigenschaften (Betriebssystem, Netzanbindung, unterst�tzte Anwendungen) haben
11
+ 4|3|Welche der folgenden Aufgaben geh�ren gem�� BSI-Standard 200-2 zur Strukturanalyse?|die angemessene Gruppierung der Komponenten eines Informationsverbundes; die Erhebung der Informationen, Gesch�ftsprozesse, Anwendungen, IT-Systeme, Kommunikationsverbindungen und r�umlichen Gegebenheiten eines Informationsverbundes
12
+ 5|3|Welche Angaben sind f�r IT-Systeme bei der Strukturanalyse zu erfassen?|Typ und Einsatzzweck; Benutzer und Administrator; Standort (Geb�ude und Raum)
13
+ 6|3|Welche Anwendungen sind in der Strukturanalyse zu erfassen?|alle Anwendungen, die f�r mindestens einen der bereits erfassten Gesch�ftsprozesse erforderlich sind
14
+ 1|4|Welche klassischen Schutzziele werden bei der Schutzbedarfsfeststellung gem�� IT-Grundschutz empfohlen?|Verf�gbarkeit, Vertraulichkeit, Integrit�t
15
+ 2|4|In welchen F�llen k�nnen Sie gem�� IT-Grundschutz-Methodik auf die Schutzbedarfsfeststellung f�r ein IT-System verzichten?|wenn das IT-System nicht eingesetzt wird
16
+ 3|4|Welche Kriterien ber�cksichtigen Sie bei der Bestimmung des Bedarfs an Verf�gbarkeit eines IT-Systems?|die maximal tolerierbare Ausfallzeit des IT-Systems
17
+ 4|4|Was ber�cksichtigen Sie, wenn Sie den Schutzbedarf einer Anwendung bestimmen?|die Informationen, die im Zusammenhang mit der Anwendung verwendet werden, die Bedeutung der Anwendung f�r die Gesch�ftsprozesse oder Fachaufgaben
18
+ 5|4|Unter welchen Bedingungen kann der Schutzbedarf eines IT-Systems bez�glich Verf�gbarkeit geringer sein als derjenige der Anwendungen, f�r die es eingesetzt wird?|wenn das IT-System nur solche Teile der Anwendungen bedient, die einen geringeren Schutzbedarf haben, wenn mindestens ein weiteres redundantes IT-System in Betrieb ist, das die betreffenden Anwendungen bereitstellen kann
19
+ 6|4|Wenn bei der Schutzbedarfsfeststellung f�r ein IT-System Kumulationseffekte ber�cksichtigt werden, bedeutet dies, dass?|Das bedeutet, dass sich der Schutzbedarf des IT-Systems erh�ht, weil sich Einzelsch�den zu einem h�heren Gesamtschaden addieren.
20
+ 1|5|Welche Aufgaben stellen sich Ihnen bei der Modellierung gem�� IT-Grundschutz?|Sie bilden den in der Strukturanalyse dokumentierten Informationsverbund mithilfe der IT-Grundschutz-Bausteine ab.,Sie merken Zielobjekte, die nicht geeignet modelliert werden k�nnen, f�r eine Risikoanalyse vor.,Sie pr�fen, welche IT-Grundschutz-Bausteine f�r den betrachteten Informationsverbund relevant sind.
21
+ 2|5|Welche Informationen sind Bestandteil eines IT-Grundschutz-Bausteins?|Angaben zur spezifischen Gef�hrdungslage,Verweise auf weiterf�hrende Informationen,Sicherheitsanforderungen zu einem gegebenen Sachverhalt
22
+ 3|5|Welche Aufgaben stellen sich Ihnen, nachdem Sie bei der Modellierung festgelegt haben, welche Bausteine f�r den Informationsverbund und seine einzelnen Zielobjekte anzuwenden sind?|die Festlegung von Ma�nahmen, mit denen die Anforderungen erf�llt werden k�nnen,die Pr�fung, ob f�r einzelne Anforderungen, deren Umsetzung im gegebenen Anwendungskontext mit vertretbarem Aufwand nicht m�glich ist, Alternativen erforderlich sind,die Dokumentation der Ergebnisse der Modellierung
23
+ 4|5|Worauf sollten Sie bei der Auswahl und Anpassung der Sicherheitsma�nahmen auf Basis der Anforderungen achten?|auf die Wirtschaftlichkeit der Ma�nahmen,auf die Wirksamkeit der Ma�nahmen,auf die Benutzerfreundlichkeit der Ma�nahmen
24
+ 5|5|Welche Aussagen zur Anwendung von Bausteinen auf Server sind korrekt?|Neben dem Baustein SYS.1.1 Allgemeiner Server ist immer auch der zutreffende betriebssystemspezifische Baustein anzuwenden.,F�r Virtualisierungsserver m�ssen neben dem Baustein sowohl der Baustein SYS.1.1 Allgemeiner Server als auch der zutreffende betriebssystemspezifische Baustein angewendet werden.
25
+ 6|5|Auf welche Zielobjekte ist bei der Modellierung der Baustein ISMS.1 Sicherheitsmanagement anzuwenden?|Er MUSS einmal angewendet werden, und zwar auf den gesamten Informationsverbund.
26
+ 1|6|Welche Aussagen zum IT-Grundschutz-Check sind zutreffend?|Ein IT-Grundschutz-Check erm�glicht, Defizite bei der Erf�llung von Sicherheitsanforderungen zu ermitteln.,Ein IT-Grundschutz-Check ist ein Soll-Ist-Vergleich zwischen Sicherheitsanforderungen und tats�chlich umgesetzten Sicherheitsma�nahmen.
27
+ 2|6|Welche Vorarbeiten erfordert der IT-Grundschutz-Check?|die Festlegung eines Zeitplans,die Auswahl von geeigneten Gespr�chspartnern,die Zusammenstellung und Lekt�re der vorhandenen Dokumente zur Informationssicherheit in dem betrachteten Informationsverbund
28
+ 3|6|Welche Verfahren verwenden Sie, um in einem IT-Grundschutz-Check zu pr�fen, wie gut eine Gruppe von Clients gesch�tzt ist?|Sie f�hren Interviews mit den zust�ndigen Systembetreuern.,Sie untersuchen stichprobenartig vor Ort, wie die Clients konfiguriert sind.,Sie lesen die vorhandene Dokumentation zur Konfiguration der Clients.
29
+ 4|6|Wann bewerten Sie beim IT-Grundschutz-Check eine Anforderung eines IT-Grundschutz-Bausteins als erf�llt?|wenn zu der Anforderung geeignete Ma�nahmen vollst�ndig, wirksam und angemessen umgesetzt sind,wenn sowohl im Interview mit einem f�r das IT-System Zust�ndigen als auch bei einer stichprobenartigen �berpr�fung keine Sicherheitsm�ngel festgestellt wurden
30
+ 5|6|Wie verfahren Sie beim ersten IT-Grundschutz-Check, also vor der Durchf�hrung von Risikoanalysen, mit Anforderungen f�r den erh�hten Schutzbedarf?|Sie betrachten Anforderungen f�r den hohen und sehr hohen Schutzbedarf erst nach Abschluss der Risikoanalyse.
31
+ 6|6|Sie stellen fest, dass eine Standard-Anforderung f�r ein IT-System nicht umgesetzt ist, das nur noch kurze Zeit in Betrieb ist. Wie behandeln Sie diese Anforderung beim IT-Grundschutz-Check?|Sie dokumentieren diese als nicht erf�llt, und merken gegebenenfalls an, dass gepr�ft werden muss, ob Ma�nahmen zur Behebung dieses Defizits angesichts der kurzen Einsatzzeit des IT-Systems noch angemessen sind.,Sie dokumentieren diese als nicht erf�llt und merken an, dass gepr�ft werden muss, ob die daraus resultierenden Risiken in der Restlaufzeit des IT-Systems noch tragbar sind.
32
+ 1|7|Wer tr�gt die Verantwortung f�r die bei einer Risikoanalyse getroffenen Entscheidungen zu einem IT-System?|die Leitung der Institution
33
+ 2|7|Welche Gef�hrdungen werden bei der Erstellung der Gef�hrdungs�bersicht im ersten Schritt betrachtet?|die relevanten elementaren Gef�hrdungen aus dem IT-Grundschutz-Kompendium
34
+ 3|7|Was bewerten Sie bei der Risikoeinsch�tzung?|die H�ufigkeit des Eintretens einer Gef�hrdung, das mit einer Gef�hrdung verbundene Schadensausma�
35
+ 4|7|Wodurch verlagern Sie ein Risiko?|durch den Abschluss einer Versicherung oder durch Outsourcing des risikobehafteten Gesch�ftsprozesses an einen externen Dienstleister
36
+ 5|7|Aus welchen Gr�nden kann es gerechtfertigt sein, auch ein hohes Risiko zu akzeptieren?|Der Aufwand f�r m�gliche Schutzma�nahmen ist unangemessen hoch oder es gibt keine wirksamen Schutzma�nahmen gegen das Risiko.
37
+ 6|7|Wann ist die Risikoakzeptanz grunds�tzlich unzul�ssig?|bei der Nichterf�llung von Basis-Anforderungen
38
+ 1|8|Was m�ssen Sie pr�fen, wenn Sie die Umsetzung von Sicherheitsma�nahmen planen?|welche begleitenden Ma�nahmen f�r eine erfolgreiche Umsetzung erforderlich sind, ob die Ma�nahme mit anderen Ma�nahmen vereinbar ist, in welcher Reihenfolge die verschiedenen Ma�nahmen umgesetzt werden sollen
39
+ 2|8|Welche Informationen aus dem IT-Grundschutz-Kompendium unterst�tzen Sie bei der Festlegung einer sinnvollen Umsetzungsreihenfolge der geplanten Ma�nahmen?|die Aufteilung der Anforderungen in Basis- und Standard-Anforderungen sowie solchen f�r den h�heren Schutzbedarf, der Vorschlag zur Kennzeichnung einer sinnvollen Bearbeitungsreihenfolge der Bausteine mithilfe der K�rzel R1, R2 und R3
40
+ 3|8|Was unternehmen Sie als Informationssicherheitsbeauftragter, wenn die Leitung Ihrer Institution nicht bereit ist, den Aufwand f�r eine bestimmte Sicherheitsma�nahme zu tragen?|Sie verdeutlichen ihr, welche Risiken mit dem Fehlen der Ma�nahme verbunden sind. Sie bitten die Leitung, durch Unterschrift zu best�tigen, dass sie die damit verbundenen Gefahren kennt und tr�gt.
41
+ 4|8|Wer sollte in der Regel technische Ma�nahmen zur Absicherung eines bestimmten�IT-Systems umsetzen?|der zust�ndige Systemadministrator
42
+ 5|8|Wer sollte �blicherweise pr�fen, ob eine Sicherheitsma�nahme wie geplant umgesetzt ist?|der Informationssicherheitsbeauftragte
43
+ 6|8|Welches Hilfsmittel im IT-Grundschutz-Kompendium k�nnen Sie verwenden, um Ihrer Leitung zu verdeutlichen, welche Risiken die Nichterf�llung von Anforderungen mit sich bringt?|die Kreuzreferenztabellen am Ende eines Bausteins�
44
+ 1|9|Warum sollten Sie Ihr Sicherheitskonzept regelm��ig �berpr�fen?|weil sich die Gef�hrdungslage �ndert, weil sich die Prozesse und Strukturen einer Institution �ndern und weil sich die Zielsetzungen und Priorit�ten einer Institution �ndern
45
+ 2|9|Welche Kriterien sollten Sie bei der �berpr�fung Ihres Sicherheitskonzepts ber�cksichtigen?|die Aktualit�t des Sicherheitskonzepts und die Vollst�ndigkeit des Sicherheitskonzepts
46
+ 3|9|Welche Vorteile bieten Reifegradmodelle f�r die Bewertung eines�ISMS?|Mit einem Reifegradmodell k�nnen der Grad der Strukturiertheit und das Ma� der systematischen Steuerung eines Prozesses bewertet werden. Ein Reifegradmodell kann auf Teilaspekte des ISMS angewendet werden und Defizite bei einzelnen Prozessen abbilden.
47
+ 4|9|Welche Voraussetzungen m�ssen f�r den Erwerb eines ISO 27001-Zertifikats auf der Basis von IT-Grundschutz erf�llt sein?|die durch Sichtung von Dokumenten und Vor-Ort-Pr�fungen begr�ndete Feststellung der erfolgreichen Erf�llung der IT-Grundschutz-Anforderungen durch einen zertifizierten Auditor und ein positives Resultat bei der �berpr�fung des Audit-Berichts durch das BSI.
48
+ 5|9|Welche der folgenden Untersuchungen haben die systematische �berpr�fung der Informationssicherheit in einer Institution zum Ziel?|die IT-Sicherheitsrevision oder ein Audit im Rahmen einer ISO 27001-Zertifizierung auf der Basis von IT-Grundschutz
49
+ 6|9|Was sollte vor der Einf�hrung einer Kennzahl zur Informationssicherheit unbedingt festgelegt werden?|welches Ziel mit der Kennzahl verfolgt werden soll und mit welchem Verfahren die Werte einer Kennzahl erhoben werden.
requirements.txt CHANGED
@@ -22,6 +22,7 @@ click
22
  colbert-ai
23
  colorama
24
  contourpy
 
25
  cycler
26
  dataclasses-json
27
  datasets
@@ -58,6 +59,7 @@ itsdangerous
58
  Jinja2
59
  jiter
60
  joblib
 
61
  jsonpatch
62
  jsonpointer
63
  kiwisolver
@@ -125,6 +127,7 @@ python-dotenv
125
  python-multipart
126
  pytz
127
  PyYAML
 
128
  RAGatouille
129
  rank_bm25
130
  regex
 
22
  colbert-ai
23
  colorama
24
  contourpy
25
+ csv
26
  cycler
27
  dataclasses-json
28
  datasets
 
59
  Jinja2
60
  jiter
61
  joblib
62
+ json
63
  jsonpatch
64
  jsonpointer
65
  kiwisolver
 
127
  python-multipart
128
  pytz
129
  PyYAML
130
+ ragas
131
  RAGatouille
132
  rank_bm25
133
  regex