howmany is a Python package that leverages the Wikidata REST API to easily find and compare the dimensions of any object. You can use howmany to find the answers to questions including:
- How tall is the Eiffel Tower?
- How many association football pitches would fit inside Germany (or that giant new wind farm)?
- And eventually anything else that Wikidata has dimensions for!
Of note is that howmany can also do unit (ex: m <-> km) and dimension (ex: area <-> length x width) conversions during comparison calculations.
Installation ⇧
howmany can be downloaded from PyPI via pip or sourced directly from this repository:
pip install howmany
git clone https://github.com/andrewtavis/howmany.git
cd howmany
python setup.py install
import howmany
Environment Setup ⇧
The development environment for howmany can be installed via the following steps:
- Fork the howmany repo, clone your fork, and configure the remotes:
Note
Consider using SSH
Alternatively to using HTTPS as in the instructions below, consider SSH to interact with GitHub from the terminal. SSH allows you to connect without a user-pass authentication flow.
To run git commands with SSH, remember then to substitute the HTTPS URL, https://github.com/...
, with the SSH one, [email protected]:...
.
- e.g. Cloning now becomes
git clone [email protected]:<your-username>/howmany.git
GitHub also has their documentation on how to Generate a new SSH key 🔑
# Clone your fork of the repo into the current directory.
git clone https://github.com/<your-username>/howmany.git
# Navigate to the newly cloned directory.
cd howmany
# Assign the original repo to a remote called "upstream".
git remote add upstream https://github.com/andrewtavis/howmany.git
- Now, if you run
git remote -v
you should see two remote repositories named:origin
(forked repository)upstream
(howmany repository)
-
Use Anaconda to create the local development environment within your howmany directory:
conda env create -f environment.yml
Examples ⇧
See the example Jupyter notebook for full examples.
import howmany
from howmany.utils import (
float_to_str,
get_wd_ent_label,
get_wd_ent_prop_amount,
get_wd_ent_prop_unit,
)
eiffel_tower_qid = "Q243"
height_pid = "P2048"
eiffel_tower_label = get_wd_ent_label(qid=eiffel_tower_qid)
eiffel_tower_height = get_wd_ent_prop_amount(qid=eiffel_tower_qid, pid=height_pid)
eiffel_tower_height_unit = get_wd_ent_prop_unit(qid=eiffel_tower_qid, pid=height_pid)
print(
f"The {eiffel_tower_label} is {round(eiffel_tower_height)} {eiffel_tower_height_unit}s tall."
)
# The Eiffel Tower is 324 metres tall.
germany_qid = "Q183"
soccer_field_qid = "Q8524"
area_pid = "P2046"
soccer_fields_in_germany_dict = howmany.compare(
containers=germany_qid, entities=soccer_field_qid, pid=area_pid
)
for k in soccer_fields_in_germany_dict.keys():
amount = round(soccer_fields_in_germany_dict[k]["amount"], 2)
print(
f"You could fit {amount:,} {soccer_fields_in_germany_dict[k]['entity']}es inside {k}."
)
# You could fit 50,453,300.88 association football pitches inside Germany.
germanies_in_soccer_fields_dict = howmany.compare(
containers=soccer_field_qid, entities=germany_qid, pid=area_pid
)
for k in germanies_in_soccer_fields_dict.keys():
amount = float_to_str(f=germanies_in_soccer_fields_dict[k]["amount"])
print(
f"You could fit {amount} {germanies_in_soccer_fields_dict[k]['entity']}s inside an {k}."
)
# You could fit 0.0000000198 Germanys inside an association football pitch.
# Variables defined above...
giant_new_wind_farm_label = "giant new wind farm"
area_of_giant_new_wind_farm = 50
unit_of_giant_new_wind_farm_area = "square kilometre"
soccer_fields_in_giant_new_wind_farm_dict = howmany.compare(
containers=giant_new_wind_farm_label,
container_amounts=area_of_giant_new_wind_farm,
container_units=unit_of_giant_new_wind_farm_area,
entities=soccer_field_qid,
pid=area_pid,
)
for k in soccer_fields_in_giant_new_wind_farm_dict.keys():
amount = round(soccer_fields_in_giant_new_wind_farm_dict[k]["amount"], 2)
print(
f"You could fit {amount:,} {soccer_fields_in_giant_new_wind_farm_dict[k]['entity']}es inside the {k}."
)
# You could fit 7,054.67 association football pitches inside the giant new wind farm.
# Variables defined above...
import matplotlib.pyplot as plt
import seaborn as sns
all_german_state_qids = ["Q64", ...]
saarland_qid = "Q1201"
saarlands_in_german_states_dict = howmany.compare(
containers=all_german_state_qids, entities=saarland_qid, pid=area_pid
)
# Code to order labels and area ratios...
ax = sns.barplot(
x=german_states_desc_saarland_area, y=german_state_desc_areas_in_saarlands
)
ax.set_title("Area of German States in Saarlands", size=18)
ax.set(xlabel="German State", ylabel="Area (Saarlands)")
ax.bar_label(ax.containers[0])
ax.xaxis.label.set_size(14)
ax.yaxis.label.set_size(14)
plt.xticks(rotation=45)
plt.show()
To-Do ⇧
Please see the contribution guidelines if you are interested in contributing to this project. Work that is in progress or could be implemented includes:
- Expand the unit conversion process in utils.py
- Keep requests below the Wikidata REST API rate limit in
howmany.compare()
- Other suggestions welcome!