# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# # More advanced PDF practice
#
# This example shows how to parse a slightly more difficult PDF using our good friend [`pdfplumber`](https://github.com/jsvine/pdfplumber).
#
# For this exercise, we'll pull the data out of a PDF that has a fixed-width table of Colorado county-level voter registration data from April 2008. That file lives here: `../pdfs/apr08_party.pdf`.
#
# We'll need to use a text-based strategy and [explicit vertical lines](https://github.com/jsvine/pdfplumber#table-extraction-settings) in the table extraction settings, and we'll make _liberal_ use of [list comprehensions](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions), my favorite thing in Python.
#
# 👉 For more details on using list comprehensions, [see this notebook](../reference/Python%20data%20types%20and%20basic%20syntax.ipynb#List-comprehensions).
#
# First, let's do our imports:

import pdfplumber
import pandas as pd

# Now let's open the PDF and dive in.

# open the PDF with the pdfplumber `open` function
with pdfplumber.open('../pdfs/apr08_party.pdf') as pdf:
    
    # the table settings I came up with after fiddling for a bit
    table_settings = {
        'vertical_strategy': 'text', 
        'horizontal_strategy': 'text',
        'explicit_vertical_lines': [95, 205, 245, 290]
    }
    
    # extract the table from the page
    table = pdf.pages[0].extract_table(table_settings=table_settings)
    
    # ~ lots of fiddling at this point to see what the results looked like ~
    
    # use a list comprehension to grab the headers (which are in row 4)
    # and tack on a conditional to remove blank items
    # https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions
    headers = [x for x in table[4] if x]
    
    # remove the useless 'PREC' item from the headers
    headers.remove('PREC')
    
    # create an empty dataframe
    df = pd.DataFrame(columns=headers)
    
    # loop over the table, slicing so that we start with row 6 and leave off some cruft at the bottom
    for row in table[6:-2]:
        
        # clean up the row a little -- remove blanks and kill out commas
        data = [x.replace(',', '') for x in row if x]
        
        # use zip() and dict() to marry the data and headers and then create a dictionary
        # https://docs.python.org/3/library/functions.html#func-dict
        # https://docs.python.org/3/library/functions.html#zip
        d = dict(zip(headers, data))
        
        # append the dict to the dataframe
        df = df.append(d, ignore_index=True)

# Where'd we land?

df.sort_values('COUNTY NAME')

StarcoderdataJupyterScriptsDedupFiltered