.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 119 of file wikidata_units.py.

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

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 128 of file wikidata_units.py.

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

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 269 of file wikidata_units.py.

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

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

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 137 of file wikidata_units.py.

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

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 9 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 57 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 101 of file wikidata_units.py.

◆ pos_from_si

int searx.wikidata_units.pos_from_si = 2

Definition at line 160 of file wikidata_units.py.

◆ pos_si_name

int searx.wikidata_units.pos_si_name = 1

Definition at line 159 of file wikidata_units.py.

◆ pos_symbol

int searx.wikidata_units.pos_symbol = 0

Definition at line 158 of file wikidata_units.py.

◆ pos_to_si

int searx.wikidata_units.pos_to_si = 3

Definition at line 161 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 249 of file wikidata_units.py.

◆ SYMBOL_TO_SI

list searx.wikidata_units.SYMBOL_TO_SI = []

Definition at line 115 of file wikidata_units.py.

◆ UNITS_BY_SI_NAME

dict searx.wikidata_units.UNITS_BY_SI_NAME = {}

Definition at line 116 of file wikidata_units.py.