Skip to content

Commit

Permalink
Add ruff
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnScolaro committed Oct 5, 2024
1 parent affb0e5 commit d36b93b
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 50 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ __pycache__
*.egg-info

# The created deck
*.apkg
*.apkg

# Ruff
.ruff_cache
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ I've lived in Brisbane my whole life, and I don't know all the suburbs. That's b

## Creating the Deck

```
```bash
# Install the repo
pip install -e.

Expand Down
2 changes: 1 addition & 1 deletion brisbane_suburbs_anki_cards/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

current_file = os.path.dirname(os.path.abspath(__file__))

DOC_KML = os.path.join(current_file, 'doc.kml')
DOC_KML = os.path.join(current_file, "doc.kml")
2 changes: 1 addition & 1 deletion brisbane_suburbs_anki_cards/constants.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
LOCAL_GOVERNMENT_AREAS_WE_CARE_ABOUT: set[str] = {'Brisbane City'}
LOCAL_GOVERNMENT_AREAS_WE_CARE_ABOUT: set[str] = {"Brisbane City"}
3 changes: 2 additions & 1 deletion brisbane_suburbs_anki_cards/entry.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from brisbane_suburbs_anki_cards.generate_anki_deck import create_anki_deck
from brisbane_suburbs_anki_cards.generate_images import create_and_save_images


def main():
# This is the entrypoint for the whole package. This is what's ran when you
# call `create-deck` when the package is installed.
create_and_save_images()
create_anki_deck()
create_anki_deck()
52 changes: 35 additions & 17 deletions brisbane_suburbs_anki_cards/generate_anki_deck.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,19 @@
MODEL_ID,
NOTE_MODEL_NAME,
fields=[
{'name': 'Image'},
{'name': 'Suburb'},
{"name": "Image"},
{"name": "Suburb"},
],
templates=[
{
'name': 'ImageSuburbCard',
'qfmt': '{{Image}}',
'afmt': '''{{FrontSide}}<hr id="answer" style="border:none;"/><div style="text-align:center; font-size: 1.5em;">{{Suburb}}</div>''',
"name": "ImageSuburbCard",
"qfmt": "{{Image}}",
"afmt": """{{FrontSide}}<hr id="answer" style="border:none;"/><div style="text-align:center; font-size: 1.5em;">{{Suburb}}</div>""",
}
]
],
)


def create_anki_deck() -> None:
suburb_to_cbd_mapping = get_suburb_to_due_order_mapping()

Expand All @@ -35,32 +36,33 @@ def create_anki_deck() -> None:
media_files = []

# Loop over all images in the output folder and add them to the deck
for root, dirs, files in os.walk(os.path.join('output', 'Brisbane City')):
for root, dirs, files in os.walk(os.path.join("output", "Brisbane City")):
for file in files:
if file.endswith(".jpg"):
# The image path is the media file
image_path = os.path.join(root, file)

# Extract locality name from file name (remove .jpg extension)
locality = os.path.splitext(file)[0]

# Add the image and locality to the Anki deck
my_note = genanki.Note(
model=my_model,
fields=[f'<img src="{file}">', locality],
due=suburb_to_cbd_mapping[locality]
due=suburb_to_cbd_mapping[locality],
)
my_deck.add_note(my_note)
media_files.append(image_path)

# Generate the Anki package
output_anki_file = 'suburb_maps.apkg'
output_anki_file = "suburb_maps.apkg"
my_package = genanki.Package(my_deck)
my_package.media_files = media_files # Add media files
my_package.write_to_file(output_anki_file)

print(f"Anki deck created and saved as {output_anki_file}")


def get_suburb_to_due_order_mapping() -> dict[str, int]:
"""
I have found that the default order that cards are introduced is
Expand All @@ -85,23 +87,39 @@ def get_suburb_to_due_order_mapping() -> dict[str, int]:
"""
suburbs_df = get_localities_df(DOC_KML)

brisbane_city_point = suburbs_df[suburbs_df['locality'] == 'Brisbane City']['geometry'].to_crs(epsg=3857).centroid
brisbane_city_point = (
suburbs_df[suburbs_df["locality"] == "Brisbane City"]["geometry"]
.to_crs(epsg=3857)
.centroid
)

# Reproject all geometries to the same CRS for distance calculations
suburbs_df['geometry'] = suburbs_df['geometry'].to_crs(epsg=3857)
suburbs_df["geometry"] = suburbs_df["geometry"].to_crs(epsg=3857)

# Calculate the distance of each suburb's centroid to Brisbane City's centroid
suburbs_df['distance_to_cbd'] = suburbs_df['geometry'].centroid.apply(lambda x: x.distance(brisbane_city_point))
suburbs_df["distance_to_cbd"] = suburbs_df["geometry"].centroid.apply(
lambda x: x.distance(brisbane_city_point)
)

# Sort the suburbs by distance to the CBD
sorted_suburbs = suburbs_df.sort_values(by='distance_to_cbd')
sorted_suburbs = suburbs_df.sort_values(by="distance_to_cbd")

# Create a mapping of suburb names to their order in the sorted list
suburb_to_order_mapping = { (lga, locality): order for order, (lga, locality) in enumerate(zip(sorted_suburbs['lga'], sorted_suburbs['locality'])) }
suburb_to_order_mapping = {
(lga, locality): order
for order, (lga, locality) in enumerate(
zip(sorted_suburbs["lga"], sorted_suburbs["locality"])
)
}

# Only keep the suburbs in the LGA's we care about
filtered_mapping = {locality: order for (lga, locality), order in suburb_to_order_mapping.items() if lga in LOCAL_GOVERNMENT_AREAS_WE_CARE_ABOUT}
filtered_mapping = {
locality: order
for (lga, locality), order in suburb_to_order_mapping.items()
if lga in LOCAL_GOVERNMENT_AREAS_WE_CARE_ABOUT
}
return filtered_mapping


if __name__ == "__main__":
create_anki_deck()
create_anki_deck()
38 changes: 25 additions & 13 deletions brisbane_suburbs_anki_cards/generate_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,35 @@
from brisbane_suburbs_anki_cards.process_kml import get_localities_df
from brisbane_suburbs_anki_cards.constants import LOCAL_GOVERNMENT_AREAS_WE_CARE_ABOUT

ZOOM_OUT_FACTOR = 0.8 # 80%
TILE_SET: Literal['google', 'openstreetmap'] = 'openstreetmap'
ZOOM_OUT_FACTOR = 0.8 # 80%
TILE_SET: Literal["google", "openstreetmap"] = "openstreetmap"


def get_output_path(lga: str, locality: str) -> str:
save_directory = os.path.join('output', lga)
save_directory = os.path.join("output", lga)
if not os.path.exists(save_directory):
os.makedirs(save_directory)

save_path = os.path.join(save_directory, f'{locality}.jpg')
save_path = os.path.join(save_directory, f"{locality}.jpg")
return save_path


def get_zoom_level_from_distance(distance_meters: float) -> int:
# Earth's circumference in meters (at the equator)
earth_circumference_meters = 40075016.686

# Loop through zoom levels from 0 to 21 (Google Maps max zoom)
for zoom in range(0, 22):
# Calculate tile width at this zoom level in meters
tile_width_meters = earth_circumference_meters / (2 ** zoom)
tile_width_meters = earth_circumference_meters / (2**zoom)

# If the distance is smaller than the tile width, this zoom level is good
if tile_width_meters < distance_meters:
return zoom

return 0 # Default to zoom level 0 if no match found


def create_and_save_images() -> None:
suburb_df = get_localities_df(DOC_KML)

Expand All @@ -47,15 +50,17 @@ def create_and_save_images() -> None:
selected_suburb = selected_suburb.to_crs(epsg=3857)

# Plot the selected suburb with a solid fill color
ax = selected_suburb.plot(figsize=(5, 5), alpha=1.0, edgecolor='k', color='white')
ax = selected_suburb.plot(
figsize=(5, 5), alpha=1.0, edgecolor="k", color="white"
)

# Get current bounds and expand them to zoom out
minx, miny, maxx, maxy = selected_suburb.total_bounds

# Calculate expanded bounds
x_range = maxx - minx
y_range = maxy - miny

# Expand the bounds by the zoom-out factor
minx -= x_range * ZOOM_OUT_FACTOR
maxx += x_range * ZOOM_OUT_FACTOR
Expand All @@ -74,20 +79,27 @@ def create_and_save_images() -> None:
zoom_level = get_zoom_level_from_distance(maxx - minx)

# Zoom out by reducing the zoom level
if TILE_SET == 'google':
if TILE_SET == "google":
google_maps_tile_url = "http://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}"
ctx.add_basemap(ax, source=google_maps_tile_url, zoom=zoom_level)
elif TILE_SET == 'openstreetmap':
ctx.add_basemap(ax, source=ctx.providers.OpenStreetMap.Mapnik, attribution='')
elif TILE_SET == "openstreetmap":
ctx.add_basemap(
ax, source=ctx.providers.OpenStreetMap.Mapnik, attribution=""
)

# Hide axes
ax.set_axis_off()

plt.subplots_adjust(left=0, right=1, top=1, bottom=0)

# Save the plot to an image file
plt.savefig(get_output_path(lga, locality), bbox_inches='tight', pad_inches=0, dpi=150, transparent=False)
plt.savefig(
get_output_path(lga, locality),
bbox_inches="tight",
pad_inches=0,
dpi=150,
transparent=False,
)
plt.close()

print(f"Map for {locality}, {lga} created!")

30 changes: 17 additions & 13 deletions brisbane_suburbs_anki_cards/process_kml.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,42 @@
import geopandas as gpd
from brisbane_suburbs_anki_cards import DOC_KML


def get_localities_df(filename: str) -> pd.DataFrame:
suburb_df = gpd.read_file(filename)

# Apply the function to extract locality and LGA
suburb_df[['locality', 'lga']] = suburb_df['Description'].apply(lambda x: pd.Series(extract_locality_lga(x)))
suburb_df = suburb_df.drop(columns=['Name', 'Description'])
suburb_df[["locality", "lga"]] = suburb_df["Description"].apply(
lambda x: pd.Series(extract_locality_lga(x))
)
suburb_df = suburb_df.drop(columns=["Name", "Description"])
return suburb_df


# Function to extract locality and lga
def extract_locality_lga(html_description):
soup = BeautifulSoup(html_description, 'html.parser')
soup = BeautifulSoup(html_description, "html.parser")

# Find all rows in the table
rows = soup.find_all('tr')
rows = soup.find_all("tr")

# Initialize variables
locality = None
lga = None

# Iterate over rows to find locality and lga
for row in rows:
cells = row.find_all('td')
cells = row.find_all("td")
if len(cells) == 2:
header = cells[0].get_text(strip=True).lower()
value = cells[1].get_text(strip=True)
if header == 'locality':
if header == "locality":
locality = value
elif header == 'lga':
elif header == "lga":
lga = value

return locality, lga


if __name__ == "__main__":
get_localities_df(DOC_KML)
get_localities_df(DOC_KML)
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,10 @@ dependencies = [
"geopandas==1.0.1"
]

[project.optional-dependencies]
dev = [
"ruff==0.6.9"
]

[project.scripts]
create-deck = "brisbane_suburbs_anki_cards.entry:main"
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from setuptools import setup, find_packages

setup(
packages=find_packages(exclude=['output']),
)
packages=find_packages(exclude=["output"]),
)

0 comments on commit d36b93b

Please sign in to comment.