Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/scripts/sales_tax.py
Views: 687
#!/usr/bin/env python12# Prints a CoffeeScript map from zip codes to tax rates based on3# http://dor.wa.gov/Content/FindTaxesAndRates/RetailSalesTax/DestinationBased/ClientInterface.aspx4# only for the State of Washington.5# Output is large. Pipe into a file.67import urllib28import re9import csv101112def parse_tax_rate(text):13match = re.search("Rate=([0-][\.1][0-9]*)", text)14if match is not None:15return match.group(1)16else:17return None181920def parse_result_code(text):21match = re.search("ResultCode=([0-9])", text)22if match is not None:23return match.group(1)24else:25return None262728def get_tax_rate_of_zip(zip_code):29"""30This function returns the tax rate of a given zipcode (no +4 extension) in WA3132Uses the interface described here33http://dor.wa.gov/Content/FindTaxesAndRates/RetailSalesTax/DestinationBased/ClientInterface.aspx3435A result code will be returned for both XML and text response formats. The codes are defined as:36370: The address was found.381: The address was not found, but the ZIP+4 was located.392: Neither the address or ZIP+4 was found, but the 5-digit ZIP was located.403: The address, ZIP+4, and ZIP could not be found.414: Invalid arguments.425: Internal error.4344A tax rate of 9.7% is reported as a float .09745"""46URL = "http://dor.wa.gov/AddressRates.aspx?output=text&addr=&city=&zip={}".format(47zip_code)48response = urllib2.urlopen(URL)49text = response.read()50# Example responses:51# LocationCode=4000 Rate=0.086 ResultCode=252# LocationCode=-1 Rate=-1 ResultCode=3 debughint=53tax_rate = parse_tax_rate(text)54result_code = parse_result_code(text)5556if int(result_code) != 2:57return None58elif tax_rate < 0:59raise ValueError(60"Result code was 0 but tax rate was negative for zip code {}".61format(zip_code))62else:63return float(tax_rate)646566## list of WA_zips retriven this way:67# import pandas as pd68# import json69# import requests70# url = 'https://www.unitedstateszipcodes.org/wa/'71# data = pd.read_html(requests.get(url, headers={'User-agent': 'Mozilla/5.0'}).text, attrs={"class":"table-striped"})72# x = data[1]73# y = x['ZIP Code'].as_matrix().tolist()74# json.dumps(y)7576WA_zips = [7798001, 98002, 98003, 98004, 98005, 98006, 98007, 98008, 98009, 98010,7898011, 98012, 98013, 98014, 98015, 98019, 98020, 98021, 98022, 98023,7998024, 98025, 98026, 98027, 98028, 98029, 98030, 98031, 98032, 98033,8098034, 98035, 98036, 98037, 98038, 98039, 98040, 98041, 98042, 98043,8198045, 98046, 98047, 98050, 98051, 98052, 98053, 98054, 98055, 98056,8298057, 98058, 98059, 98061, 98062, 98063, 98064, 98065, 98068, 98070,8398071, 98072, 98073, 98074, 98075, 98077, 98082, 98083, 98087, 98089,8498092, 98093, 98101, 98102, 98103, 98104, 98105, 98106, 98107, 98108,8598109, 98110, 98111, 98112, 98113, 98114, 98115, 98116, 98117, 98118,8698119, 98121, 98122, 98124, 98125, 98126, 98127, 98129, 98131, 98132,8798133, 98134, 98136, 98138, 98139, 98141, 98144, 98145, 98146, 98148,8898151, 98154, 98155, 98158, 98160, 98161, 98164, 98165, 98166, 98168,8998170, 98171, 98174, 98175, 98177, 98178, 98181, 98184, 98185, 98188,9098189, 98190, 98191, 98194, 98195, 98198, 98199, 98201, 98203, 98204,9198205, 98206, 98207, 98208, 98213, 98220, 98221, 98222, 98223, 98224,9298225, 98226, 98227, 98228, 98229, 98230, 98231, 98232, 98233, 98235,9398236, 98237, 98238, 98239, 98240, 98241, 98243, 98244, 98245, 98247,9498248, 98249, 98250, 98251, 98252, 98253, 98255, 98256, 98257, 98258,9598259, 98260, 98261, 98262, 98263, 98264, 98266, 98267, 98270, 98271,9698272, 98273, 98274, 98275, 98276, 98277, 98278, 98279, 98280, 98281,9798282, 98283, 98284, 98286, 98287, 98288, 98290, 98291, 98292, 98293,9898294, 98295, 98296, 98297, 98303, 98304, 98305, 98310, 98311, 98312,9998314, 98315, 98320, 98321, 98322, 98323, 98324, 98325, 98326, 98327,10098328, 98329, 98330, 98331, 98332, 98333, 98335, 98336, 98337, 98338,10198339, 98340, 98342, 98343, 98344, 98345, 98346, 98348, 98349, 98350,10298351, 98352, 98353, 98354, 98355, 98356, 98357, 98358, 98359, 98360,10398361, 98362, 98363, 98364, 98365, 98366, 98367, 98368, 98370, 98371,10498372, 98373, 98374, 98375, 98376, 98377, 98378, 98380, 98381, 98382,10598383, 98384, 98385, 98386, 98387, 98388, 98390, 98391, 98392, 98393,10698394, 98395, 98396, 98397, 98398, 98401, 98402, 98403, 98404, 98405,10798406, 98407, 98408, 98409, 98411, 98412, 98413, 98415, 98416, 98417,10898418, 98419, 98421, 98422, 98424, 98430, 98431, 98433, 98438, 98439,10998442, 98443, 98444, 98445, 98446, 98447, 98448, 98450, 98455, 98460,11098464, 98465, 98466, 98467, 98471, 98477, 98481, 98490, 98492, 98493,11198496, 98497, 98498, 98499, 98501, 98502, 98503, 98504, 98505, 98506,11298507, 98508, 98509, 98511, 98512, 98513, 98516, 98520, 98522, 98524,11398526, 98527, 98528, 98530, 98531, 98532, 98533, 98535, 98536, 98537,11498538, 98539, 98540, 98541, 98542, 98544, 98546, 98547, 98548, 98550,11598552, 98554, 98555, 98556, 98557, 98558, 98559, 98560, 98561, 98562,11698563, 98564, 98565, 98566, 98568, 98569, 98570, 98571, 98572, 98575,11798576, 98577, 98579, 98580, 98581, 98582, 98583, 98584, 98585, 98586,11898587, 98588, 98589, 98590, 98591, 98592, 98593, 98595, 98596, 98597,11998599, 98601, 98602, 98603, 98604, 98605, 98606, 98607, 98609, 98610,12098611, 98612, 98613, 98614, 98616, 98617, 98619, 98620, 98621, 98622,12198623, 98624, 98625, 98626, 98628, 98629, 98631, 98632, 98635, 98637,12298638, 98639, 98640, 98641, 98642, 98643, 98644, 98645, 98647, 98648,12398649, 98650, 98651, 98660, 98661, 98662, 98663, 98664, 98665, 98666,12498667, 98668, 98670, 98671, 98672, 98673, 98674, 98675, 98682, 98683,12598684, 98685, 98686, 98687, 98801, 98802, 98807, 98811, 98812, 98813,12698814, 98815, 98816, 98817, 98819, 98821, 98822, 98823, 98824, 98826,12798827, 98828, 98829, 98830, 98831, 98832, 98833, 98834, 98836, 98837,12898840, 98841, 98843, 98844, 98845, 98846, 98847, 98848, 98849, 98850,12998851, 98852, 98853, 98855, 98856, 98857, 98858, 98859, 98860, 98862,13098901, 98902, 98903, 98904, 98907, 98908, 98909, 98920, 98921, 98922,13198923, 98925, 98926, 98929, 98930, 98932, 98933, 98934, 98935, 98936,13298937, 98938, 98939, 98940, 98941, 98942, 98943, 98944, 98946, 98947,13398948, 98950, 98951, 98952, 98953, 99001, 99003, 99004, 99005, 99006,13499008, 99009, 99011, 99012, 99013, 99014, 99016, 99017, 99018, 99019,13599020, 99021, 99022, 99023, 99025, 99026, 99027, 99029, 99030, 99031,13699032, 99033, 99034, 99036, 99037, 99039, 99040, 99101, 99102, 99103,13799104, 99105, 99107, 99109, 99110, 99111, 99113, 99114, 99115, 99116,13899117, 99118, 99119, 99121, 99122, 99123, 99124, 99125, 99126, 99128,13999129, 99130, 99131, 99133, 99134, 99135, 99136, 99137, 99138, 99139,14099140, 99141, 99143, 99144, 99146, 99147, 99148, 99149, 99150, 99151,14199152, 99153, 99154, 99155, 99156, 99157, 99158, 99159, 99160, 99161,14299163, 99164, 99165, 99166, 99167, 99169, 99170, 99171, 99173, 99174,14399176, 99179, 99180, 99181, 99185, 99201, 99202, 99203, 99204, 99205,14499206, 99207, 99208, 99209, 99210, 99211, 99212, 99213, 99214, 99215,14599216, 99217, 99218, 99219, 99220, 99223, 99224, 99228, 99251, 99252,14699256, 99258, 99260, 99299, 99301, 99302, 99320, 99321, 99322, 99323,14799324, 99326, 99328, 99329, 99330, 99333, 99335, 99336, 99337, 99338,14899341, 99343, 99344, 99345, 99346, 99347, 99348, 99349, 99350, 99352,14999353, 99354, 99356, 99357, 99359, 99360, 99361, 99362, 99363, 99371,15099401, 99402, 99403151]152153taxes_per_zip = []154closest_rate = 0.065155for zip_code in WA_zips:156tax_rate = get_tax_rate_of_zip(zip_code)157if tax_rate is None:158tax_rate = closest_rate159if tax_rate is not None:160taxes_per_zip.append("{}:{:.6f}".format(zip_code, tax_rate))161closest_rate = tax_rate162163print("WA_sales_tax = {%s}" % (', '.join(taxes_per_zip[0:])))164165166