Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ cache/
*.xlsx
*.xlsm
*.html
!hugo/layouts/**/*.html
*.rmarkdown

# Ignore scratch documents
Expand Down
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ repos:
args: ['--maxkb=200']
- id: mixed-line-ending
args: ['--fix=no']
- id: trailing-whitespace
exclude: activate.R
- repo: local
hooks:
- id: forbid-to-commit
Expand Down
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ single-family home or multifamily home with six or fewer units.

## Developing

We currently support two ways of generating PINVAL reports: With
[Quarto](#quarto) or with [Hugo](#hugo).

### Quarto

This project expects that you have R and the [Quarto
CLI](https://quarto.org/docs/get-started/) installed on your machine.
A working installation of RStudio is recommended, but not required.
Expand Down Expand Up @@ -40,3 +45,27 @@ renv::restore()
```
quarto render pinval.qmd --to html -o pinval.html
```

### Hugo

This project expects that you have the [Hugo CLI](https://gohugo.io/installation/)
installed on your machine.

> [!INFO]
> While the Data team often does work on the server, you should do Hugo
> development on your laptop in order to run the development site. Hugo
> installation is easiest using WSL, where you can install it by running
> `sudo snap install hugo` and entering your WSL user password (most likely
> the first password you ever set on your laptop, if you haven't changed it).

1. Ensure that Hugo is installed correctly by running `hugo version`.
2. Navigate to the `hugo/` subdirectory and run the development server:

```
cd hugo
hugo serve
```

3. For a quick sample report, see the examples:
- http://localhost:1313/example-single-card
- http://localhost:1313/example-multi-card
2 changes: 2 additions & 0 deletions hugo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
public/
.hugo_build.lock
4 changes: 4 additions & 0 deletions hugo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
baseURL = 'http://example.org/'
languageCode = 'en-us'
title = 'PINVAL'
disableKinds = ['sitemap', 'rss']
Comment on lines +1 to +4
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just Hugo boilerplate. It's not really important at this point.

278 changes: 278 additions & 0 deletions hugo/content/example-multi-card.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
---
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an example of the Markdown frontmatter that Hugo needs for a multi-card PIN in order to render a PINVAL report. The higher-level vision here is that eventually we'll have a GitHub workflow (#37) that runs a Python script (#38) that queries the PINVAL tables in Athena (ccao-data/data-architecture#793) and generates one of these Markdown files in the hugo/content/ directory for every PIN in a tri (or in a list of input PINs); then it will call the hugo command to compile those Markdown files into output HTML pages using the template defined in the hugo/layouts/ subdir below.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me. It's a sort of params file through which our html layout dynamically generates the static webpage html file.

layout: report
title: "Cook County Assessor's Model Value Report (Experimental)"
assessment_year: "2025"
final_model_run_date: "February 11, 2025"
pin: "05204070690000"
pin_pretty: "14-33-100-024-0000"
pred_pin_final_fmv_round: "$415,000"
cards:
- card_num: 1
location:
property_address: "123 Main St"
municipality: "Chicago"
township: "Jefferson"
meta_nbhd_code: "10022"
loc_school_elementary_district_name: "City Elementary School District 61"
loc_school_secondary_district_name: "City High School District 217"
loc_latitude: 41.978876
loc_longitude: -87.659015
chars:
char_class: "203 - Two to six apartments, over 62 years"
char_yrblt: 1925
char_bldg_sf: "2,800"
char_land_sf: "4,950"
char_beds: 6
char_fbath: 2
char_hbath: 0
has_subject_pin_sale: true
pred_card_initial_fmv: "$415,000"
pred_card_initial_fmv_per_sqft: "$148"
comps:
- comp_num: 1
pin: "14291230160000"
pin_pretty: "14-29-123-016-0000"
is_subject_pin_sale: false
sale_price: "$390,000"
sale_price_short: "$390K"
sale_price_per_sq_ft: "$146"
sale_date: "Dec 2023"
document_num: "2335112098"
property_address: "234 Oak St"
char_class: "203 - Two to six apartments, over 62 years"
char_yrblt: 1920
char_bldg_sf: "2,675"
char_land_sf: "4,125"
char_beds: 6
char_fbath: 2
char_hbath: 0
meta_nbhd_code: "10022"
loc_latitude: 41.982014
loc_longitude: -87.666812
- comp_num: 2
pin: "14331000240000"
pin_pretty: "14-33-100-024-0000"
is_subject_pin_sale: true
sale_price: "$350,000"
sale_price_short: "$350K"
sale_price_per_sq_ft: "$125"
sale_date: "Apr 2022"
document_num: "2211234567"
property_address: "123 Main St"
char_class: "203 - Two to six apartments, over 62 years"
char_yrblt: 1925
char_bldg_sf: "2,800"
char_land_sf: "4,950"
char_beds: 6
char_fbath: 2
char_hbath: 0
meta_nbhd_code: "10022"
loc_latitude: 41.978876
loc_longitude: -87.659015
- comp_num: 3
pin: "14292340250000"
pin_pretty: "14-29-234-025-0000"
is_subject_pin_sale: false
sale_price: "$425,000"
sale_price_short: "$425K"
sale_price_per_sq_ft: "$155"
sale_date: "Nov 2023"
document_num: "2332198765"
property_address: "345 Pine St"
char_class: "203 - Two to six apartments, over 62 years"
char_yrblt: 1923
char_bldg_sf: "2,740"
char_land_sf: "3,900"
char_beds: 5
char_fbath: 2
char_hbath: 1
meta_nbhd_code: "10022"
loc_latitude: 41.979654
loc_longitude: -87.661234
- comp_num: 4
pin: "14324750890000"
pin_pretty: "14-32-475-089-0000"
is_subject_pin_sale: false
sale_price: "$405,000"
sale_price_short: "$405K"
sale_price_per_sq_ft: "$149"
sale_date: "Sep 2023"
document_num: "2326543217"
property_address: "456 Elm St"
char_class: "203 - Two to six apartments, over 62 years"
char_yrblt: 1926
char_bldg_sf: "2,720"
char_land_sf: "4,100"
char_beds: 6
char_fbath: 3
char_hbath: 0
meta_nbhd_code: "10023"
loc_latitude: 41.975432
loc_longitude: -87.658123
- comp_num: 5
pin: "14295670340000"
pin_pretty: "14-29-567-034-0000"
is_subject_pin_sale: false
sale_price: "$380,000"
sale_price_short: "$380K"
sale_price_per_sq_ft: "$139"
sale_date: "Oct 2023"
document_num: "2329876543"
property_address: "567 Maple St"
char_class: "203 - Two to six apartments, over 62 years"
char_yrblt: 1918
char_bldg_sf: "2,730"
char_land_sf: "3,950"
char_beds: 5
char_fbath: 2
char_hbath: 1
meta_nbhd_code: "10022"
loc_latitude: 41.981243
loc_longitude: -87.664532
comp_summary:
sale_year_range_prefix: "between"
sale_year_range: "2022 and 2023"
avg_sale_price: "$390,000"
avg_price_per_sqft: "$143"
predictors:
- "char_yrblt"
- "char_bldg_sf"
- "char_land_sf"
- "char_beds"
- "char_fbath"
- "char_hbath"
- card_num: 2
location:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So our new multi-card strategy for comps spits outs the same comps for all cards within 2-3 card properties. I was going to suggest some sort of condensed data structure here, but as I started typing this I realized we will have different comps for 4+ multi-card PINs. So I think a bit of duplication in the 2-3 card case is ideal here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be open to a condensed data structure! I didn't spend too much time thinking about the 2-3 card case, which I'm saving for #31.

property_address: "123 Main St"
municipality: "Chicago"
township: "Jefferson"
meta_nbhd_code: "10022"
loc_school_elementary_district_name: "City Elementary School District 61"
loc_school_secondary_district_name: "City High School District 217"
loc_latitude: 41.978876
loc_longitude: -87.659015
chars:
char_class: "203 - Two to six apartments, over 62 years"
char_yrblt: 1925
char_bldg_sf: "2,800"
char_land_sf: "4,950"
char_beds: 6
char_fbath: 2
char_hbath: 0
has_subject_pin_sale: true
pred_card_initial_fmv: "$415,000"
pred_card_initial_fmv_per_sqft: "$148"
comps:
- comp_num: 1
pin: "14291230160000"
pin_pretty: "14-29-123-016-0000"
is_subject_pin_sale: false
sale_price: "$390,000"
sale_price_short: "$390K"
sale_price_per_sq_ft: "$146"
sale_date: "Dec 2023"
document_num: "2335112098"
property_address: "234 Oak St"
char_class: "203 - Two to six apartments, over 62 years"
char_yrblt: 1920
char_bldg_sf: "2,675"
char_land_sf: "4,125"
char_beds: 6
char_fbath: 2
char_hbath: 0
meta_nbhd_code: "10022"
loc_latitude: 41.982014
loc_longitude: -87.666812
- comp_num: 2
pin: "14331000240000"
pin_pretty: "14-33-100-024-0000"
is_subject_pin_sale: true
sale_price: "$350,000"
sale_price_short: "$350K"
sale_price_per_sq_ft: "$125"
sale_date: "Apr 2022"
document_num: "2211234567"
property_address: "123 Main St"
char_class: "203 - Two to six apartments, over 62 years"
char_yrblt: 1925
char_bldg_sf: "2,800"
char_land_sf: "4,950"
char_beds: 6
char_fbath: 2
char_hbath: 0
meta_nbhd_code: "10022"
loc_latitude: 41.978876
loc_longitude: -87.659015
- comp_num: 3
pin: "14292340250000"
pin_pretty: "14-29-234-025-0000"
is_subject_pin_sale: false
sale_price: "$425,000"
sale_price_short: "$425K"
sale_price_per_sq_ft: "$155"
sale_date: "Nov 2023"
document_num: "2332198765"
property_address: "345 Pine St"
char_class: "203 - Two to six apartments, over 62 years"
char_yrblt: 1923
char_bldg_sf: "2,740"
char_land_sf: "3,900"
char_beds: 5
char_fbath: 2
char_hbath: 1
meta_nbhd_code: "10022"
loc_latitude: 41.979654
loc_longitude: -87.661234
- comp_num: 4
pin: "14324750890000"
pin_pretty: "14-32-475-089-0000"
is_subject_pin_sale: false
sale_price: "$405,000"
sale_price_short: "$405K"
sale_price_per_sq_ft: "$149"
sale_date: "Sep 2023"
document_num: "2326543217"
property_address: "456 Elm St"
char_class: "203 - Two to six apartments, over 62 years"
char_yrblt: 1926
char_bldg_sf: "2,720"
char_land_sf: "4,100"
char_beds: 6
char_fbath: 3
char_hbath: 0
meta_nbhd_code: "10023"
loc_latitude: 41.975432
loc_longitude: -87.658123
- comp_num: 5
pin: "14295670340000"
pin_pretty: "14-29-567-034-0000"
is_subject_pin_sale: false
sale_price: "$380,000"
sale_price_short: "$380K"
sale_price_per_sq_ft: "$139"
sale_date: "Oct 2023"
document_num: "2329876543"
property_address: "567 Maple St"
char_class: "203 - Two to six apartments, over 62 years"
char_yrblt: 1918
char_bldg_sf: "2,730"
char_land_sf: "3,950"
char_beds: 5
char_fbath: 2
char_hbath: 1
meta_nbhd_code: "10022"
loc_latitude: 41.981243
loc_longitude: -87.664532
comp_summary:
sale_year_range_prefix: "between"
sale_year_range: "2022 and 2023"
avg_sale_price: "$390,000"
avg_price_per_sqft: "$143"
predictors:
- "char_yrblt"
- "char_bldg_sf"
- "char_land_sf"
- "char_beds"
- "char_fbath"
- "char_hbath"
---
Loading