1- from Orange .data import StringVariable , DiscreteVariable , ContinuousVariable , \
2- TimeVariable
1+ from datetime import date
2+ from html import escape
3+
4+ from AnyQt .QtCore import Qt
5+
6+ from orangewidget .utils .signals import summarize , PartialSummary
7+
8+ from Orange .data import (
9+ StringVariable , DiscreteVariable , ContinuousVariable , TimeVariable ,
10+ Table
11+ )
12+
13+ from Orange .evaluation import Results
14+ from Orange .misc import DistMatrix
15+ from Orange .preprocess import Preprocess
16+ from Orange .preprocess .score import Scorer
17+ from Orange .widgets .utils .signals import AttributeList
18+ from Orange .base import Model , Learner
319
420
521def format_variables_string (variables ):
@@ -37,7 +53,11 @@ def format_variables_string(variables):
3753 return var_string
3854
3955
40- def format_summary_details (data ):
56+ def _plural (number ):
57+ return 's' * (number % 100 != 1 )
58+
59+
60+ def format_summary_details (data , format = Qt .PlainText ):
4161 """
4262 A function that forms the entire descriptive part of the input/output
4363 summary.
@@ -46,31 +66,53 @@ def format_summary_details(data):
4666 :type data: Orange.data.Table
4767 :return: A formatted string
4868 """
49- def _plural (number ):
50- return 's' * (number != 1 )
51-
52- details = ''
53- if data :
54- features = format_variables_string (data .domain .attributes )
55- targets = format_variables_string (data .domain .class_vars )
56- metas = format_variables_string (data .domain .metas )
57-
58- features_missing = missing_values (data .has_missing_attribute ()
59- and data .get_nan_frequency_attribute ())
60- n_features = len (data .domain .variables ) + len (data .domain .metas )
69+ if data is None :
70+ return ""
71+
72+ if format == Qt .PlainText :
73+ def b (s ):
74+ return s
75+ else :
76+ def b (s ):
77+ return f"<b>{ s } </b>"
78+
79+ features = format_variables_string (data .domain .attributes )
80+ targets = format_variables_string (data .domain .class_vars )
81+ metas = format_variables_string (data .domain .metas )
82+
83+ features_missing = missing_values (data .has_missing_attribute ()
84+ and data .get_nan_frequency_attribute ())
85+ n_features = len (data .domain .variables ) + len (data .domain .metas )
86+ name = getattr (data , "name" , None )
87+ if name == "untitled" :
88+ name = None
89+ basic = f'{ len (data )} instance{ _plural (len (data ))} , ' \
90+ f'{ n_features } variable{ _plural (n_features )} '
91+
92+ if format == Qt .PlainText :
93+ details = \
94+ (f"'{ name } ': " if name else "" ) + basic \
95+ + f'\n Features: { features } { features_missing } ' \
96+ + f'\n Target: { targets } '
97+ if data .domain .metas :
98+ details += f'\n Metas: { metas } '
99+ else :
61100 details = \
62- f'{ len (data )} instance{ _plural (len (data ))} , ' \
63- f'{ n_features } variable{ _plural (n_features )} \n ' \
64- f'Features: { features } { features_missing } \n ' \
65- f'Target: { targets } \n Metas: { metas } '
66- return details
101+ _nobr (f"<b>'{ escape (name )} '</b>: { basic } " if name else basic ) \
102+ + '<br/>' \
103+ + _nobr (f'<b>Features</b>: { features } { features_missing } ' ) \
104+ + '<br/>' \
105+ + _nobr (f"<b>Target</b>: { targets } " )
106+ if data .domain .metas :
107+ details += "<br/>" + _nobr ("<b>Metas</b>: {metas}" )
108+ return details
67109
68110
69111def missing_values (value ):
70112 if value :
71113 return f'({ value * 100 :.1f} % missing values)'
72114 else :
73- return '(No missing values)'
115+ return '(no missing values)'
74116
75117
76118def format_multiple_summaries (data_list , type_io = 'input' ):
@@ -101,3 +143,58 @@ def new_line(text):
101143 details = f'No data on { type_io } .'
102144 full_details .append (details if not name else f'{ name } :<br>{ details } ' )
103145 return '<hr>' .join (full_details )
146+
147+
148+ def _name_of (object ):
149+ return _nobr (getattr (object , 'name' , type (object ).__name__ ))
150+
151+
152+ def _nobr (s ):
153+ return f"<nobr>{ s } </nobr>"
154+
155+
156+ @summarize .register (Table )
157+ def summarize_ (data : Table ):
158+ return PartialSummary (
159+ data .approx_len (),
160+ format_summary_details (data , format = Qt .RichText ))
161+
162+
163+ @summarize .register (DistMatrix )
164+ def summarize_ (matrix : DistMatrix ):
165+ n , m = matrix .shape
166+ return PartialSummary (f"{ n } ×{ m } " , _nobr (f"{ n } ×{ m } distance matrix" ))
167+
168+
169+ @summarize .register (Results )
170+ def summarize_ (results : Results ):
171+ nmethods , ninstances = results .predicted .shape
172+ summary = f"{ nmethods } ×{ ninstances } "
173+ details = f"{ nmethods } method{ _plural (nmethods )} " \
174+ f"on { ninstances } test instance{ _plural (ninstances )} "
175+ return PartialSummary (summary , _nobr (details ))
176+
177+
178+ @summarize .register (AttributeList )
179+ def summarize_ (attributes ):
180+ n = len (attributes )
181+ if n == 0 :
182+ details = "empty list"
183+ elif n <= 3 :
184+ details = _nobr (", " .join (var .name for var in attributes ))
185+ else :
186+ details = _nobr (", " .join (var .name for var in attributes [:2 ]) +
187+ f" and { n - 2 } others" )
188+ return PartialSummary (n , details )
189+
190+
191+ def summarize_by_name (type_ , symbol ):
192+ @summarize .register (type_ )
193+ def summarize_ (model : type_ ):
194+ return PartialSummary (symbol , _name_of (model ))
195+
196+
197+ summarize_by_name (Model , "⛄" if date .month == 12 else "🄼" )
198+ summarize_by_name (Learner , "🄻" )
199+ summarize_by_name (Preprocess , "🄿" )
200+ summarize_by_name (Scorer , "🅂" )
0 commit comments