.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
searx.wikidata_units Namespace Reference

Classes

class  Beaufort
 

Functions

float convert_from_si (str si_name, str symbol, float|int value)
 
float convert_to_si (str si_name, str symbol, float|int value)
 
 units_by_si_name (si_name)
 
 symbol_to_si ()
 
 fetch_units ()
 

Variables

list __all__ = ["convert_from_si", "convert_to_si", "symbol_to_si"]
 
list ADDITIONAL_UNITS
 
dict ALIAS_SYMBOLS
 
list SYMBOL_TO_SI = []
 
dict UNITS_BY_SI_NAME = {}
 
int pos_symbol = 0
 
int pos_si_name = 1
 
int pos_from_si = 2
 
int pos_to_si = 3
 
str SARQL_REQUEST
 

Detailed Description

Unit conversion on the basis of `SPARQL/WIKIDATA Precision, Units and
Coordinates`_

.. _SPARQL/WIKIDATA Precision, Units and Coordinates:
   https://en.wikibooks.org/wiki/SPARQL/WIKIDATA_Precision,_Units_and_Coordinates#Quantities

Function Documentation

◆ convert_from_si()

float searx.wikidata_units.convert_from_si ( str si_name,
str symbol,
float | int value )

Definition at line 120 of file wikidata_units.py.

120def convert_from_si(si_name: str, symbol: str, value: float | int) -> float:
121 from_si = units_by_si_name(si_name)[symbol][pos_from_si]
122 if isinstance(from_si, (float, int)):
123 value = float(value) * from_si
124 else:
125 value = from_si(float(value))
126 return value
127
128

References units_by_si_name().

+ Here is the call graph for this function:

◆ convert_to_si()

float searx.wikidata_units.convert_to_si ( str si_name,
str symbol,
float | int value )

Definition at line 129 of file wikidata_units.py.

129def convert_to_si(si_name: str, symbol: str, value: float | int) -> float:
130 to_si = units_by_si_name(si_name)[symbol][pos_to_si]
131 if isinstance(to_si, (float, int)):
132 value = float(value) * to_si
133 else:
134 value = to_si(float(value))
135 return value
136
137

References units_by_si_name().

+ Here is the call graph for this function:

◆ fetch_units()

searx.wikidata_units.fetch_units ( )
Fetch units from Wikidata.  Function is used to update persistence of
:py:obj:`searx.data.WIKIDATA_UNITS`.

Definition at line 270 of file wikidata_units.py.

270def fetch_units():
271 """Fetch units from Wikidata. Function is used to update persistence of
272 :py:obj:`searx.data.WIKIDATA_UNITS`."""
273
274 results = collections.OrderedDict()
275 response = wikidata.send_wikidata_query(SARQL_REQUEST)
276 for unit in response['results']['bindings']:
277
278 symbol = unit['symbol']['value']
279 name = unit['item']['value'].rsplit('/', 1)[1]
280 si_name = unit.get('tosiUnit', {}).get('value', '')
281 if si_name:
282 si_name = si_name.rsplit('/', 1)[1]
283
284 to_si_factor = unit.get('tosi', {}).get('value', '')
285 if name not in results:
286 # ignore duplicate: always use the first one
287 results[name] = {
288 'symbol': symbol,
289 'si_name': si_name if si_name else None,
290 'to_si_factor': float(to_si_factor) if to_si_factor else None,
291 }
292 return results

◆ symbol_to_si()

searx.wikidata_units.symbol_to_si ( )
Generates a list of tuples, each tuple is a measure unit and the fields
in the tuple are:

0. Symbol of the measure unit (e.g. 'mi' for measure unit 'miles' Q253276)

1. SI name of the measure unit (e.g. Q11573 for SI unit 'metre')

2. Factor to get SI value from measure unit (e.g. 1mi is equal to SI 1m
   multiplied by 1609.344)

3. Factor to get measure value from from SI value (e.g. SI 100m is equal to
   100mi divided by 1609.344)

The returned list is sorted, the first items are created from
``WIKIDATA_UNITS``, the second group of items is build from
:py:obj:`ADDITIONAL_UNITS` and items created from :py:obj:`ALIAS_SYMBOLS`.

If you search this list for a symbol, then a match with a symbol from
Wikidata has the highest weighting (first hit in the list), followed by the
symbols from the :py:obj:`ADDITIONAL_UNITS` and the lowest weighting is
given to the symbols resulting from the aliases :py:obj:`ALIAS_SYMBOLS`.

Definition at line 166 of file wikidata_units.py.

166def symbol_to_si():
167 """Generates a list of tuples, each tuple is a measure unit and the fields
168 in the tuple are:
169
170 0. Symbol of the measure unit (e.g. 'mi' for measure unit 'miles' Q253276)
171
172 1. SI name of the measure unit (e.g. Q11573 for SI unit 'metre')
173
174 2. Factor to get SI value from measure unit (e.g. 1mi is equal to SI 1m
175 multiplied by 1609.344)
176
177 3. Factor to get measure value from from SI value (e.g. SI 100m is equal to
178 100mi divided by 1609.344)
179
180 The returned list is sorted, the first items are created from
181 ``WIKIDATA_UNITS``, the second group of items is build from
182 :py:obj:`ADDITIONAL_UNITS` and items created from :py:obj:`ALIAS_SYMBOLS`.
183
184 If you search this list for a symbol, then a match with a symbol from
185 Wikidata has the highest weighting (first hit in the list), followed by the
186 symbols from the :py:obj:`ADDITIONAL_UNITS` and the lowest weighting is
187 given to the symbols resulting from the aliases :py:obj:`ALIAS_SYMBOLS`.
188
189 """
190
191 global SYMBOL_TO_SI # pylint: disable=global-statement
192 if SYMBOL_TO_SI:
193 return SYMBOL_TO_SI
194
195 # filter out units which can't be normalized to a SI unit and filter out
196 # units without a symbol / arcsecond does not have a symbol
197 # https://www.wikidata.org/wiki/Q829073
198
199 for item in data.WIKIDATA_UNITS.values():
200 if item['to_si_factor'] and item['symbol']:
201 SYMBOL_TO_SI.append(
202 (
203 item['symbol'],
204 item['si_name'],
205 1 / item['to_si_factor'], # from_si
206 item['to_si_factor'], # to_si
207 item['symbol'],
208 )
209 )
210
211 for item in ADDITIONAL_UNITS:
212 SYMBOL_TO_SI.append(
213 (
214 item['symbol'],
215 item['si_name'],
216 item['from_si'],
217 item['to_si'],
218 item['symbol'],
219 )
220 )
221
222 alias_items = []
223 for item in SYMBOL_TO_SI:
224 for alias in ALIAS_SYMBOLS.get(item[0], ()):
225 alias_items.append(
226 (
227 alias,
228 item[1],
229 item[2], # from_si
230 item[3], # to_si
231 item[0], # origin unit
232 )
233 )
234 SYMBOL_TO_SI = SYMBOL_TO_SI + alias_items
235 return SYMBOL_TO_SI
236
237
238# the response contains duplicate ?item with the different ?symbol
239# "ORDER BY ?item DESC(?rank) ?symbol" provides a deterministic result
240# even if a ?item has different ?symbol of the same rank.
241# A deterministic result
242# see:
243# * https://www.wikidata.org/wiki/Help:Ranking
244# * https://www.mediawiki.org/wiki/Wikibase/Indexing/RDF_Dump_Format ("Statement representation" section)
245# * https://w.wiki/32BT
246# * https://en.wikibooks.org/wiki/SPARQL/WIKIDATA_Precision,_Units_and_Coordinates#Quantities
247# see the result for https://www.wikidata.org/wiki/Q11582
248# there are multiple symbols the same rank
249

Referenced by units_by_si_name().

+ Here is the caller graph for this function:

◆ units_by_si_name()

searx.wikidata_units.units_by_si_name ( si_name)

Definition at line 138 of file wikidata_units.py.

138def units_by_si_name(si_name):
139
140 global UNITS_BY_SI_NAME # pylint: disable=global-statement,global-variable-not-assigned
141 if UNITS_BY_SI_NAME:
142 return UNITS_BY_SI_NAME[si_name]
143
144 # build the catalog ..
145 for item in symbol_to_si():
146
147 item_si_name = item[pos_si_name]
148 item_symbol = item[pos_symbol]
149
150 by_symbol = UNITS_BY_SI_NAME.get(item_si_name)
151 if by_symbol is None:
152 by_symbol = {}
153 UNITS_BY_SI_NAME[item_si_name] = by_symbol
154 by_symbol[item_symbol] = item
155
156 return UNITS_BY_SI_NAME[si_name]
157
158

References symbol_to_si().

Referenced by convert_from_si(), and convert_to_si().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ __all__

list searx.wikidata_units.__all__ = ["convert_from_si", "convert_to_si", "symbol_to_si"]
private

Definition at line 10 of file wikidata_units.py.

◆ ADDITIONAL_UNITS

list searx.wikidata_units.ADDITIONAL_UNITS
Initial value:
1= [
2 {
3 "si_name": "Q11579",
4 "symbol": "°C",
5 "to_si": lambda val: val + 273.15,
6 "from_si": lambda val: val - 273.15,
7 },
8 {
9 "si_name": "Q11579",
10 "symbol": "°F",
11 "to_si": lambda val: (val + 459.67) * 5 / 9,
12 "from_si": lambda val: (val * 9 / 5) - 459.67,
13 },
14 {
15 "si_name": "Q182429",
16 "symbol": "Bft",
17 "to_si": Beaufort.to_si,
18 "from_si": Beaufort.from_si,
19 },
20]

Definition at line 58 of file wikidata_units.py.

◆ ALIAS_SYMBOLS

dict searx.wikidata_units.ALIAS_SYMBOLS
Initial value:
1= {
2 '°C': ('C',),
3 '°F': ('F',),
4 'mi': ('L',),
5 'Bft': ('bft',),
6}

Definition at line 102 of file wikidata_units.py.

◆ pos_from_si

int searx.wikidata_units.pos_from_si = 2

Definition at line 161 of file wikidata_units.py.

◆ pos_si_name

int searx.wikidata_units.pos_si_name = 1

Definition at line 160 of file wikidata_units.py.

◆ pos_symbol

int searx.wikidata_units.pos_symbol = 0

Definition at line 159 of file wikidata_units.py.

◆ pos_to_si

int searx.wikidata_units.pos_to_si = 3

Definition at line 162 of file wikidata_units.py.

◆ SARQL_REQUEST

str searx.wikidata_units.SARQL_REQUEST
Initial value:
1= """
2SELECT DISTINCT ?item ?symbol ?tosi ?tosiUnit
3WHERE
4{
5 ?item wdt:P31/wdt:P279 wd:Q47574 .
6 ?item p:P5061 ?symbolP .
7 ?symbolP ps:P5061 ?symbol ;
8 wikibase:rank ?rank .
9 OPTIONAL {
10 ?item p:P2370 ?tosistmt .
11 ?tosistmt psv:P2370 ?tosinode .
12 ?tosinode wikibase:quantityAmount ?tosi .
13 ?tosinode wikibase:quantityUnit ?tosiUnit .
14 }
15 FILTER(LANG(?symbol) = "en").
16}
17ORDER BY ?item DESC(?rank) ?symbol
18"""

Definition at line 250 of file wikidata_units.py.

◆ SYMBOL_TO_SI

list searx.wikidata_units.SYMBOL_TO_SI = []

Definition at line 116 of file wikidata_units.py.

◆ UNITS_BY_SI_NAME

dict searx.wikidata_units.UNITS_BY_SI_NAME = {}

Definition at line 117 of file wikidata_units.py.