From a92f647fbb34c611f21c5308e050f53029c41bf6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aur=C3=A9lien=20Lamercerie?=
 <aurelien.lamercerie@tetras-libre.fr>
Date: Tue, 8 Aug 2023 19:30:00 +0200
Subject: [PATCH] Update module Metrics to refine metrics calculation

---
 .../__pycache__/__init__.cpython-311.pyc      | Bin 607 -> 0 bytes
 .../__pycache__/metrics.cpython-311.pyc       | Bin 2460 -> 0 bytes
 .../__pycache__/ontology.cpython-311.pyc      | Bin 8889 -> 0 bytes
 ontoScorer/__pycache__/report.cpython-311.pyc | Bin 2283 -> 0 bytes
 ontoScorer/__pycache__/scorer.cpython-311.pyc | Bin 1772 -> 0 bytes
 ontoScorer/metrics.py                         |  82 +++++++++++++++---
 ontoScorer/ontology.py                        |  24 ++---
 ontoScorer/report.py                          |   6 +-
 tests/test_metrics.py                         |  36 +++++++-
 tests/test_ontology.py                        |   2 +-
 10 files changed, 120 insertions(+), 30 deletions(-)
 delete mode 100644 ontoScorer/__pycache__/__init__.cpython-311.pyc
 delete mode 100644 ontoScorer/__pycache__/metrics.cpython-311.pyc
 delete mode 100644 ontoScorer/__pycache__/ontology.cpython-311.pyc
 delete mode 100644 ontoScorer/__pycache__/report.cpython-311.pyc
 delete mode 100644 ontoScorer/__pycache__/scorer.cpython-311.pyc

diff --git a/ontoScorer/__pycache__/__init__.cpython-311.pyc b/ontoScorer/__pycache__/__init__.cpython-311.pyc
deleted file mode 100644
index 15c9d4b5e58309a39ad2614703ebff6ad3759740..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 607
zcmZ3^%ge>Uz`*eQ%$bxW3=9m9K^z!ngEBs|F)}brXGmd4Va#EOg3ydnjHwJ+Oi&dJ
z3z%UnWEw>U3$hH1oyxk5k%3_~BaDyAOJS;FU|@)1V`4~U$YO`7No7M-#mJD#h~yFu
zm^x%S1!Mxkwb<Q)X6`a328PveJ&X(~jKK_=%r8O4`u$?m*W|p#lwW*{xwx|U7E3{5
zNyaVql+2>M#N5<d?1@RmU=fb^__WNN)cE*Y96p{-@d1t@9=BMNGg2~(Zn0(N6{i-J
ztYr8MGVqs!enx(7s(wylZfagurha&SQFd`bVsff}NNPz@VzGXHUP*p&a(+>25ttba
zVaCU2=4F<|$LkeT{^GF7%}*)KNwq5yU|?VXg=ldF0|UbcW=2NF2Ml}-DDVb1Z;yGu
zeV6?VqdDgD?PuAqu(&8~az)zYBDd)kZqpsi7rCt)IBqa-G%&SrbVyue5W2!3bb&$W
u1_N^oM>~HL{{+SfMpMkE+fTAzU~y4c=Zdh-MF!m~47wL!sECh&fdK$ee}YB;

diff --git a/ontoScorer/__pycache__/metrics.cpython-311.pyc b/ontoScorer/__pycache__/metrics.cpython-311.pyc
deleted file mode 100644
index 261155446af384b3fa8a8d952545d43dda6c6dec..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2460
zcmZ3^%ge>Uz`)RHcqwHI3j@Pr5C?`?pp4HB3=9m@8B!Qh7;_kM8KW3;nWC6-nWLB)
zL1IifEV-;vtc(my4DJjm%q<KlEX$Y}7*;bubu&b<rLYDwXtKQo31~9k;x8ylP0lRN
z%+HH2PR=h%y~R_Mnw*%E1Lbj~8A4c^jJG)a^Gfn_^3yAmL3&}B5z6>11$I{|Llk2Q
zLljdAV+%tRa|%-nLljF2b1;J@%Pn@_)RLmi<l<zQ7LZPm!<ZQu7(N?-wWl!FFvNqz
z!5GYgs|NEx>LGFr!3>&AenlVwP3BviaDUulgZSVUQ<|YB<1Lor)SR?pkRb}c?DaG9
zb5r$m5_41YvNH9<^NX^J3lfu4^+QriiV}<U^Ycpb!J$wDW(I=-q)0y(;%vQw%3B=q
z@tJv<CGqi90#MKB!9@5N7#NDB85kHE7;Z>Pb+GjC-4GM+VCmt$Atc<v(!<`t-ogGE
z<nm;YcR>sgW@TVt0P#OhV`N}xXKQDl&QJn!D@cxkfdLeXHH-_8M4%E33=GQ{7#LQ=
zxh`n@WsD3AtKs^(*ilSnYGJ5hqJpVxo$L!h;SYBOjM2%4YJV+r2YVW03Udob4Kun+
zYgszj(il@%u*$KPu*1w`V5niKVMR^NH4O2ve8Et{O+Y0ZOumF4#=>DH2TVQ%l*m~9
zP*N<&LSayfH3O&EbcPy+Sg~5h8pZ`MT_`kaG)-jc5f5fq$*_{~7E4}YZt6;=TTFTe
zx0sW2ii<%Zsi05<N=U!BY;rP-OOo?*3+$>?VM#4HF(<h+C$S_|&n727IWec$P7k3>
z1mq+IaQeHT5CK6Om=_2ymsljRP-=-3MC5`(M3Ddk0|T{vR0Il<B9I%3#6TGV$uC8c
z3=9lJdP0<efuRUgkl=A7$d6MQr!#;9o(mN4olIp6MNBCSd5kHH6PbFrgBeyby#%Fw
zaNz)UnkI9RILK@X1_p*(f<>umsYR)I$*J+lIf=!^sl~;hJgA`1Py`BmQXC92@3RI2
z1H+F7h6{pz5VXU1Lh%JT{R`qCG(mBK;)Xzo#05b=3O!aN3-Sdhuu*-Ko|>0hlvt9Q
zLa~oPu~h^LW3Wp#Id3r+r<UB}PERd?8GVbjG%qthuLu-oMW70+2$Us?K-sSdRGt;_
zFfcG^auo4`!deIs)}YcARDIkMLbw(##to`-ps{g_tunr(s5BKs7ZjzY6e)o`Ee}dp
zpq!}y1`ZD3$hyS|&lOdI7#Rf=P{mh4(etB$;jWB4G!vM6UN;ZDWFC6aJp77z_yvWC
ziwY4}6e2FlL|&1Jyucwzyvhe+>et0|FNx`1(6hfN=5R&Kp@aJdEFD}B^gEz^LD27_
zpx+fizYaE>5>F*HR)}p7yC`XKMbZLPb=(zGT41)q?4p>_6)_`FC306tYKGYYvx`Dn
zSA?`+)d@I;{4`lX)e@*MiI2a<6(66QpHiBW8Xtd)CqBNgG%*JvQv@pWinKui2?`Xj
zR&W3ofr1oFfa0sz2wZ|RFhJl3CT3QV4-9aEi;GqJ0|O=jF%D#spC<b){^IPM)Wo7Z
zJ!s7dNh#n&0!kmZgh8<msa*9yOi-dI0+r5SXMpo7#6VDP{Ka7d@sVATAp-*gC|eh2
xF)%QEU}j`w{2;=>=)!n`!5J62!Ju&g6@6e4VATG=fJuA=iG2YPXtH3p006+<GA;lB

diff --git a/ontoScorer/__pycache__/ontology.cpython-311.pyc b/ontoScorer/__pycache__/ontology.cpython-311.pyc
deleted file mode 100644
index b71e1d0f3cad1e8ed6574796cb86610805e54287..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 8889
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

diff --git a/ontoScorer/__pycache__/report.cpython-311.pyc b/ontoScorer/__pycache__/report.cpython-311.pyc
deleted file mode 100644
index 3ac64f032d3c2903f9d0664b49ed1fe36c6d71ac..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2283
zcmZ3^%ge>Uz`(Hl!kLt<><kQ#K^z!nfigZTFfcGoXJBG*XGmdaVMt+I#>Bv|nh7e)
z5XF$f6wIK>oD35H(TpI1fq~((6j*O6Llk2QLljdAV+%tRa|%-nLljF2b1;J@%PqE`
z)Pnq?l4Mq>4iE)0n;E3r4y?O|v4$ZYBo4+kOf?MgF!LE|m}?l~LFyrLEHw=AAe~@d
z3PUi1CZnGw%Ppaz)U?#1)V$=>`24(*{G9ys%3DI|sd=eIi6yBi2r<Fr{M>@XqRis_
zy!fKj;?kUwTkN^1B}JLZ#hR?QSc+3~(uzP1En;I}U?^e-5gZH*48<TZ1rYdUr=O9Z
zo2s9an46lHm8l<|UzA;3keHmRACg*9lvu0}vc5PuzbLf`%nXJwi@;%^S5SG2BR)Pe
zFS8^*zKS0bFnTZnZjeQ)3=9kn3^$ZaI#{l7$irzxBM@KihPYe@OAk*6PY2IuPzWT$
zgNcEG0pvzd(0q1a0!3#EV=ZG1V+vCZLl#IW7-zxN&t{m*RK?4{09M0X0@4ds!N7o`
z9%LR^d>JDH!)olhS!x)vU`dGqhYhS~HXzg!V*?w+rD$e=-321DaF~Ino}iuCU=>Ad
zHH<0j5F7LC(aZo@2gX#h6KopTP7bJ@tTl`&oDg;mV+t3X#a+XY1&^mJPyz+(MTtos
z6g8mqi>ZbeMGYu<W2gyc(B$*0Qnt0VRq%&qCk5BC#GKN^lFa-(1xUhGu(h@2suJZ2
zf@M9pS}TPrEiS*(+@#bZh5R&y<ebFf;?!b=Ops1!Hbqt|#>M3h%c{uYILyGRR+Nj&
z8J@Kjg1}kZN}<X%BqLP;UJfXLGAF2PP{>FuR!B=NPc4Ewt|TKdPoX3uRRLa-z*Xy2
zx!^G-H@_&AI8%afn39;6g2QHojKs23uv~FsZmL2adXVZ>iE?ovMT{?`D6^{K;R+~9
zP0lRN%+Iq@sN&=bN=;78$+1$X;^uNQQ~(!BRtlP&;Ii%(OF?2u#x3TY)Vy2l(71w>
zf1tE+i?aY`(k-?kuraro(hN13iZ~e<7;bSvO1AjolA>ZzDXpMT1gdaualir{Ud+J+
z1VP1IFeA8_6SeN(dcYxcLCkkW$rXLKEBf9S#C$J^`CjDk?cllrlE^yhe1heQNBk9!
z^ouSTS6nhKh-F<6%eu&s1=Z=lLF9^|#}z~03u68k#QZOE_!FV?0~-UU@C7mbiyZnL
zTz9$oI!dnat6kyOyU4A7g<F5C@`jWvX1-U<LN6MHT`>x~#2t2lJM0FJ*afM?i#&-P
zUL9U{c?BkjToKf`B4}`t*YFCj;a2AzELSZ2uULd%G>N!k5^;$);sS33SWm)5o&=Dd
z2OtCTF7o7cc!B*4u^sG7y9Fsra;~V^ToALnAZB-w!w%{Piv=c2Y_2GqT@bUlAZBrq
z!vZR9wjg9l%#!#EVrCb_%r0`6b#Oi4m%P9sS;WJ@z~HCJ3aVxD5_41I<8N`r$LHp!
zl;(igJn`{`rHMHZnIceqQzXj3z_5}5tPdP<MWC`2On{=X*a%!5H84Qn2PPI)`40?m
zf=8TH>H`BN0Wl6_lAk6c*svl=P*n<Y9oUv%95xU~*%g7>51@Lb*qniZ;R7=xBjX1V
VIYy}u44A}6kk}UxfhG&K4*(zdK6n5C

diff --git a/ontoScorer/__pycache__/scorer.cpython-311.pyc b/ontoScorer/__pycache__/scorer.cpython-311.pyc
deleted file mode 100644
index 7696fe257f510bead13598ef2ee71e027b9b4612..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1772
zcmZ3^%ge>Uz`*dy@KTC8D+9x05C?`?pp4Hh3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI
zW-yyMhb5Oaij|RpiNT#Ag{6fdg>@Md1H)=2s0j>FY$<HP44UjOK?0hLw>bRsO7e5^
z(<?O@Z?OfX7UUO|Xfobn_f0J+%1ka!2C0H!MkwR60@xL)3{i|J3{gxej4cdN%qdJQ
z3{fm8%q<L2tSKzP44SOBxIjh+C+8QX79}%7^@1o68-zdCfXyj^najYyP{X*4k%3_~
zT%?8}9?nKl$AqB{?!yvxkR=ejjDdk+HG~N=ogp3;k_;&f!3--I{WMvNKu)<ORFs;Q
zT9lfXoEo1G4Uk(x>8W|CMTsS;DR8kORt5%!TkN@z(9vYR#ZsJ_lXgoSQ+IqpVoAm=
zaZDq?62%}(6%-VH+39EG=celCB<7~(Wo7Dz=NDxc7bGU9>W8G36eSkxgB()~4ni;!
z5}NuD5xs)STO9H6nR%Hd@$pr{h|t!93Gy>AFccdzFfcSQ+*Q)LpzU-~$@z+sa|g>6
z4tY!gak+_=Qz|=HdU!f`I(R;Vf-M;y`V0&Vps)kE`|}KNywxydfs}yp0%Uby5fD+s
zkOhwwjQ9eX1X9FM!;l3s8O&Y)3STe_nLxG)#Y~ix4NCvP3`Lv_3=EoVMWD=diz_)l
zw;-`7HNGUjh#M4hf)Ihs;{3e$qSWHjoRT6QkT_>@Voq{tPGU)_CSwsVDAYh6QYaDt
zNwPyUrB(?c1u;}i1f<pp9KtsgRj(*oTvv3yr09IW<%&!6Ma7saiZP(Tmb<~h)5CL}
zL+%oX+>DYd@@6|&u2}eA<OsOJ5pV&9ii8*#7*GP7je&sy6ilC|fCC&Q12ANPTnG*&
z<RGbG$O7qriNgbS84Cl$YB;Z!u>=$xU{#<@w*X`ll!u^DGY@J6A_q2m5y)V0h=W79
zNR)wr0TQmP1x1;8CAT<W*+7#C9J;sIiohjJF(`Q`K!cedrYIgFStW%O+-PzVpkQ|g
z2m4(?@fj>vB=m1c$iPUw8xk^ecs{Z-3#ol!U=~vAVEf9!z{%H<)}P;%f00lA3ZMK%
z4uvZm3Kw7q9QJ;iY@qy<mzbLxAAgH0K0Y@;r8Eb`=82ClEKSUT$P@{JyeAGKWEdD2
zRx*G!gOf@TsOSL`d>{vcO6vv&82rG*%&Pc-0Zwo+u?8}JU_c@{SV0Of35W$Cv;8#L
zZ*hRi1W<_$F1d=NK@I^&04ODc3n;J)ia@0_L?<W}|KhNLc*m|tiGhIulz58s85kHo
xFf%eTeh^_`l)Jzni;QkCNM1liHyETZprQ{f{EUhp7%+*CAh9nX0!<d|AOMULfPer1

diff --git a/ontoScorer/metrics.py b/ontoScorer/metrics.py
index 73fd413..feedd33 100644
--- a/ontoScorer/metrics.py
+++ b/ontoScorer/metrics.py
@@ -2,28 +2,84 @@
 # -*-coding:Utf-8 -*
 
 #==============================================================================
-# ontoScorer: [brief description of the module]
+# ontoScorer: Ontology Scoring Module
 #------------------------------------------------------------------------------
-# Detailed module description
+# This module provides metrics to evaluate and compare different ontologies.
+# It calculates precision, recall, and F1 score for various ontology elements
+# such as classes, object properties, data properties, restrictions, individuals,
+# and annotations. It also computes an overall score taking into account all
+# the ontology elements. The comparison is performed between a reference ontology
+# and a generated ontology, allowing users to evaluate how well the generated 
+# ontology matches the reference.
 #==============================================================================
 
+
 from sklearn.metrics import precision_score, recall_score, f1_score
 from ontoScorer.ontology import Ontology
 
 class Metrics:
+    
+    #--------------------------------------------------------------------------
+    # Constructor(s)
+    #--------------------------------------------------------------------------
+    
     def __init__(self):
-        self.precision = 0
-        self.recall = 0
-        self.f1 = 0
+        self.scores = {
+            "class": {"precision": 0, "recall": 0, "f1": 0},
+            "object_property": {"precision": 0, "recall": 0, "f1": 0},
+            "data_property": {"precision": 0, "recall": 0, "f1": 0},
+            "restriction": {"precision": 0, "recall": 0, "f1": 0},
+            "individual": {"precision": 0, "recall": 0, "f1": 0},
+            "annotation": {"precision": 0, "recall": 0, "f1": 0},
+            "overall": {"precision": 0, "recall": 0, "f1": 0}
+        }
+
+
+    #--------------------------------------------------------------------------
+    # Computing Method(s)
+    #--------------------------------------------------------------------------
 
     def calculate(self, reference_ontology, generated_ontology):
-        reference_classes = set([cls.name() for cls in reference_ontology.get_classes()])
-        generated_classes = set([cls.name() for cls in generated_ontology.get_classes()])
+        methods = [
+            ("class", "get_classes"),
+            ("object_property", "get_object_properties"),
+            ("data_property", "get_data_properties"),
+            ("restriction", "get_restrictions"),
+            ("individual", "get_individuals"),
+            #("annotation", "get_annotations")
+        ]
+
+        y_true_overall = []
+        y_pred_overall = []
+
+        for score_name, method_name in methods:
+            reference_elements = set([elem.name() for elem in getattr(reference_ontology, method_name)()])
+            generated_elements = set([elem.name() for elem in getattr(generated_ontology, method_name)()])
+
+            all_elements = reference_elements.union(generated_elements)
+            y_true = [1 if elem in reference_elements else 0 for elem in all_elements]
+            y_pred = [1 if elem in generated_elements else 0 for elem in all_elements]
+
+            self.scores[score_name]["precision"] = precision_score(y_true, y_pred)
+            self.scores[score_name]["recall"] = recall_score(y_true, y_pred)
+            self.scores[score_name]["f1"] = f1_score(y_true, y_pred)
 
-        all_classes = reference_classes.union(generated_classes)
-        y_true = [1 if cls in reference_classes else 0 for cls in all_classes]
-        y_pred = [1 if cls in generated_classes else 0 for cls in all_classes]
+            y_true_overall.extend(y_true)
+            y_pred_overall.extend(y_pred)
 
-        self.precision = precision_score(y_true, y_pred)
-        self.recall = recall_score(y_true, y_pred)
-        self.f1 = f1_score(y_true, y_pred)
\ No newline at end of file
+        self.scores["overall"]["precision"] = precision_score(y_true_overall, y_pred_overall)
+        self.scores["overall"]["recall"] = recall_score(y_true_overall, y_pred_overall)
+        self.scores["overall"]["f1"] = f1_score(y_true_overall, y_pred_overall)
+        
+        
+    #--------------------------------------------------------------------------
+    # Printing Method(s)
+    #--------------------------------------------------------------------------
+    
+    def print_scores(self):
+        for element, scores in self.scores.items():
+            print(f"Metrics for {element.capitalize()}:")
+            print(f"\tPrecision: {scores['precision']:.4f}")
+            print(f"\tRecall: {scores['recall']:.4f}")
+            print(f"\tF1 Score: {scores['f1']:.4f}")
+            print("----------------------------")
\ No newline at end of file
diff --git a/ontoScorer/ontology.py b/ontoScorer/ontology.py
index 90d4329..cb2d501 100644
--- a/ontoScorer/ontology.py
+++ b/ontoScorer/ontology.py
@@ -114,17 +114,21 @@ class Ontology:
         return self._get_elements_of_type(OWL.Restriction)
 
     def get_individuals(self) -> list:
-        """Extract all individuals from the ontology."""
-        all_types = set(self.graph.subjects(RDF.type))
-        non_individuals = {element.reference for element in 
-                           self.get_classes() + 
-                           self.get_object_properties() + 
-                           self.get_data_properties()}
+        """Extract all individuals from the ontology, including elements explicitly typed as owl:Individual, 
+        owl:NamedIndividual or any class."""
         
-        individuals = all_types - non_individuals
-        
-        return [NamedElement(i, self.graph) if isinstance(i, URIRef) else BlankElement(i, self.graph) 
-                for i in individuals]
+        # Getting elements of type owl:NamedIndividual and owl:Individual
+        individuals = self._get_elements_of_type(OWL.NamedIndividual)
+        individuals += self._get_elements_of_type(URIRef("http://www.w3.org/2002/07/owl#Individual"))
+    
+        # Getting all elements typed as one of the classes
+        all_classes = {cls.reference for cls in self.get_classes()}
+        for cls in all_classes:
+            individuals += [NamedElement(s, self.graph) if isinstance(s, URIRef) else BlankElement(s, self.graph)
+                            for s, _, o in self.graph.triples((None, RDF.type, cls))]
+    
+        return list(set(individuals))  # Ensuring uniqueness
+
 
     def get_annotations(self):
         """Extract all annotation comments from the ontology."""
diff --git a/ontoScorer/report.py b/ontoScorer/report.py
index 30f7659..a5df58a 100644
--- a/ontoScorer/report.py
+++ b/ontoScorer/report.py
@@ -33,9 +33,9 @@ class Report:
             report_str += "The generated ontology and the reference ontology have the same number of classes."
 
         report_str += "\n\nEvaluation Metrics:"
-        report_str += f"\nPrecision: {self.metrics.precision}"
-        report_str += f"\nRecall: {self.metrics.recall}"
-        report_str += f"\nF1 Score: {self.metrics.f1}"
+        report_str += f'\nPrecision: {self.metrics.scores["overall"]["precision"]}'
+        report_str += f'\nRecall: {self.metrics.scores["overall"]["recall"]}'
+        report_str += f'\nF1 Score: {self.metrics.scores["overall"]["f1"]}'
 
         return report_str
 
diff --git a/tests/test_metrics.py b/tests/test_metrics.py
index 4415d78..9dc6501 100644
--- a/tests/test_metrics.py
+++ b/tests/test_metrics.py
@@ -2,9 +2,39 @@
 # -*-coding:Utf-8 -*
 
 #==============================================================================
-# ontoScorer: [brief description of the module]
+# test_metrics: Metrics Testing Module
 #------------------------------------------------------------------------------
-# Detailed module description, if needed
+# Contains tests for verifying functionality of the Metrics class.
 #==============================================================================
 
-# TODO
+import unittest
+import os
+from context import ontoScorer
+from ontoScorer.ontology import Ontology
+from ontoScorer.metrics import Metrics
+
+class TestMetrics(unittest.TestCase):
+
+    def setUp(self):
+        DATA_FOLDER_PATH = f'{os.path.dirname(os.path.abspath(__file__))}/test_data'
+        self.ontology1_path = f"{DATA_FOLDER_PATH}/ontology_a.ttl"
+        self.ontology2_path = f"{DATA_FOLDER_PATH}/ontology_b.ttl"
+        self.onto1 = Ontology(self.ontology1_path)
+        self.onto2 = Ontology(self.ontology2_path)
+        self.metrics = Metrics()
+
+    def test_calculate_scores(self):
+        self.metrics.calculate(self.onto1, self.onto2)
+        for key in self.metrics.scores:
+            self.assertTrue(0 <= self.metrics.scores[key]["precision"] <= 1)
+            self.assertTrue(0 <= self.metrics.scores[key]["recall"] <= 1)
+            self.assertTrue(0 <= self.metrics.scores[key]["f1"] <= 1)
+
+
+    def test_print_scores(self):
+        self.metrics.calculate(self.onto1, self.onto2)
+        self.metrics.print_scores()
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/tests/test_ontology.py b/tests/test_ontology.py
index 8da3b2e..da89d12 100644
--- a/tests/test_ontology.py
+++ b/tests/test_ontology.py
@@ -68,7 +68,7 @@ class TestOntology(unittest.TestCase):
 
     def test_get_individuals(self):
         individuals_names = {ind.name() for ind in self.onto1.get_individuals()}
-        
+        self.assertEqual(len(individuals_names), 1)
         self.assertIn("SolarSystem", individuals_names)
         self.assertNotIn("gravitation", individuals_names)
 
-- 
GitLab