Python #properties raising an error - python

I am trying to write a class to pass the following unittest:
import unittest
from property_address import *
class TestAddresses(unittest.TestCase):
def setUp(self):
self.home = Address( name='Steve Holden', street_address='1972 Flying Circus', city='Arlington', state='VA', zip_code='12345' )
def test_name(self):
self.assertEqual(self.home.name, 'Steve Holden')
self.assertRaises(AttributeError, setattr, self.home, 'name', 'Daniel Greenfeld')
def test_state(self):
self.assertEqual(self.home.state, 'VA')
self.assertRaises(StateError, setattr, self.home, 'state', 'Not a state')
self.home.state = 'CO'
self.assertEqual(self.home.state, 'CO')
The part I am having issues with is the self.assertRaises(StateError, setattr, self.home, 'state', 'Not a state')
I can't seem how to get a StatError to be raised.
The code I am using is:
class Address(object):
states = ['IA', 'KS', 'UT', 'VA', 'NC', 'NE', 'SD', 'AL', 'ID', 'FM', 'DE', 'AK', 'CT', 'PR', 'NM', 'MS', 'PW', 'CO', 'NJ', 'FL', 'MN',
'VI', 'NV', 'AZ', 'WI', 'ND', 'PA', 'OK', 'KY', 'RI', 'NH', 'MO', 'ME', 'VT', 'GA', 'GU', 'AS', 'NY', 'CA', 'HI', 'IL', 'TN',
'MA', 'OH', 'MD', 'MI', 'WY', 'WA', 'OR', 'MH', 'SC', 'IN', 'LA', 'MP', 'DC', 'MT', 'AR', 'WV', 'TX']
def __init__(self,name, street_address, city, state, zip_code):
self._name = name
self._street_address = street_address
self._city = city
self._state = state
self._zip_code = zip_code
#property
def name(self):
return self._name.title()
#property
def state(self):
return self._state
#state.setter
def state(self,value):
if value in self.states:
self._state = value
else:
raise ### This is where I am stuck
do I need to create a new #property for StateError, or should I work it into state def somehow.

You need to raise a StateError exception; that is all:
#state.setter
def state(self,value):
if value not in self.states:
raise StateError(value)
self._state = value
This does require you to have defined the exception class first, of course:
class StateError(Exception):
"""Invalid state value used"""
Demo:
>>> class StateError(Exception): pass
...
>>> class Address(object):
... states = ['IA', 'KS', 'UT', 'VA', 'NC', 'NE', 'SD', 'AL', 'ID', 'FM', 'DE', 'AK', 'CT', 'PR', 'NM', 'MS', 'PW', 'CO', 'NJ', 'FL', 'MN',
... 'VI', 'NV', 'AZ', 'WI', 'ND', 'PA', 'OK', 'KY', 'RI', 'NH', 'MO', 'ME', 'VT', 'GA', 'GU', 'AS', 'NY', 'CA', 'HI', 'IL', 'TN',
... 'MA', 'OH', 'MD', 'MI', 'WY', 'WA', 'OR', 'MH', 'SC', 'IN', 'LA', 'MP', 'DC', 'MT', 'AR', 'WV', 'TX']... #property
... def state(self):
... return self._state
... #state.setter
... def state(self,value):
... if value not in self.states:
... raise StateError(value)
... self._state = value
...
>>> a = Address()
>>> a.state = 'VA'
>>> a.state = 'Nonesuch'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 11, in state
__main__.StateError: Nonesuch

Related

How can I extract values in parentheses from a Python list using a regex?

This is the data as a list:
states = ['Alabama (AL)', 'Alaska (AK)', 'Arizona (AZ)', 'Arkansas (AR)', 'California (CA)', 'Colorado (CO)', 'Connecticut (CT)', 'Delaware (DE)', 'District of Columbia (DC)', 'Florida (FL)', 'Georgia (GA)', 'Hawaii (HI)', 'Idaho (ID)', 'Illinois (IL)', 'Indiana (IN)', 'Iowa (IA)', 'Kansas (KS)', 'Kentucky (KY)', 'Louisiana (LA)', 'Maine (ME)', 'Maryland (MD)', 'Massachusetts (MA)', 'Michigan (MI)', 'Minnesota (MN)', 'Mississippi (MS)', 'Missouri (MO)', 'Montana (MT)', 'Nebraska (NE)', 'Nevada (NV)', 'New Hampshire (NH)', 'New Jersey (NJ)', 'New Mexico (NM)', 'New York (NY)', 'North Carolina (NC)', 'North Dakota (ND)', 'Ohio (OH)', 'Oklahoma (OK)', 'Oregon (OR)', 'Pennsylvania (PA)', 'Rhode Island (RI)', 'South Carolina (SC)', 'South Dakota (SD)', 'Tennessee (TN)', 'Texas (TX)', 'Utah (UT)', 'Vermont (VT)', 'Virginia (VA)', 'Washington (WA)', 'West Virginia (WV)', 'Wisconsin (WI)', 'Wyoming (WY)']
I want to extract all the codes in parentheses.
This code returned None:
re.search('[(A-Z)]')
How can I do this?
Since you're using a list, you probably don't need a regex. If you're guaranteed that's the format, something like this should do it:
abbreviations = [state[-3:-1] for state in states]
That code uses a List Comprehension to make a new list from your old list. For each item in the states list, we're using negative indexes (which start at the back of the string) and the slice operator to pull out the abbreviations since they're always the 2nd to last and 3rd to last characters in the strings.
Sample usage:
>>> states = ['Alabama (AL)', 'Alaska (AK)', 'Arizona (AZ)', 'Arkansas (AR)', 'California (CA)']
>>> [state[-3:-1] for state in states]
['AL', 'AK', 'AZ', 'AR', 'CA']
import re
regex = r"(?<=\()[A-Z]+(?=\))"
print(re.findall(regex, "".join(states)))
Output:
['AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'DC', 'FL', 'GA', 'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 'WI', 'WY']

Is there a way to take country two letter alpha codes and display them on a map?

I had a DataFrame with country names and values corresponding to them. I used the following code to convert the countries into codes:
import pycountry
input_countries = happiness_data["Country or region"]
countries = {}
for country in pycountry.countries:
countries[country.name] = country.alpha_2
codes = [countries.get(country, 'Unknown code') for country in input_countries]
print(codes)
Which returns this:
['FI', 'DK', 'NO', 'IS', 'NL', 'CH', 'SE', 'NZ', 'CA', 'AT', 'AU', 'CR', 'IL', 'LU', 'GB', 'IE', 'DE', 'BE', 'US', 'Unknown code', 'AE', 'MT', 'MX', 'FR', 'Unknown code', 'CL', 'GT', 'SA', 'QA', 'ES', 'PA', 'BR', 'UY', 'SG', 'SV', 'IT', 'BH', 'SK', 'Unknown code', 'PL', 'UZ', 'LT', 'CO', 'SI', 'NI', 'Unknown code', 'AR', 'RO', 'CY', 'EC', 'KW', 'TH', 'LV', 'Unknown code', 'EE', 'JM', 'MU', 'JP', 'HN', 'KZ', 'Unknown code', 'HU', 'PY', 'Unknown code', 'PE', 'PT', 'PK', 'Unknown code', 'PH', 'RS', 'Unknown code', 'LY', 'ME', 'TJ', 'HR', 'HK', 'DO', 'BA', 'TR', 'MY', 'BY', 'GR', 'MN', 'MK', 'NG', 'KG', 'TM', 'DZ', 'MA', 'AZ', 'LB', 'ID', 'CN', 'Unknown code', 'BT', 'CM', 'BG', 'GH', 'Unknown code', 'NP', 'JO', 'BJ', 'Unknown code', 'GA', 'Unknown code', 'ZA', 'AL', 'Unknown code', 'KH', 'Unknown code', 'SN', 'SO', 'NA', 'NE', 'BF', 'AM', 'Unknown code', 'GN', 'GE', 'GM', 'KE', 'MR', 'MZ', 'TN', 'BD', 'IQ', 'Unknown code', 'ML', 'SL', 'LK', 'MM', 'TD', 'UA', 'ET', 'Unknown code', 'UG', 'EG', 'ZM', 'TG', 'IN', 'LR', 'KM', 'MG', 'LS', 'BI', 'ZW', 'HT', 'BW', 'Unknown code', 'MW', 'YE', 'RW', 'Unknown code', 'AF', 'CF', 'SS']
I dropped all of the unknown codes, so I only have known codes left. I want to plot these codes on a map so I can get a visualization of where my data is coming from. Is there a way to do this? I tried using pygal to no avail.
Thanks for any help and or advice you can give me. If you want to try this out, feel free to copy that list of countries and make up some random integer values to see if you are able to plot values corresponding to those country labels on a map. Additionally, if I can just use country names (i.e. "Bangladesh") with a value (i.e. (8)) and plot hues on a map according to that, that would work too.
Thanks so much!
You can map your alpha_2 country codes to coordinates using this list of countries, codes and coordinates then plot your data on a map using any sophisticated plotting libraries, like matplotlib and cartopy, matplotlib and geopandas or – if you want the map interactive and/or for the web – plotly and mapbox.
Have a look at Plotly and Built-in Country and State Geometries
https://plotly.com/python/choropleth-maps/

Dynamically naming saved dataframes in loop

I'm attempting to use the GTab package to query Google Search trends data for every state in the US, but am having some trouble getting my loop to work.
For one state it's easy enough to do this, and new_query produces a dataframe.
t = gtab.GTAB()
t.set_options(pytrends_config={"geo": "US-NY", "timeframe": "2020-09-01 2020-10-01"})
query = t.new_query("weather")
To loop through I'm trying to use a dict to assign geo dynamically. However, I can't figure out how to do the same for the df name (query).
state_abbrevs = {
'Alabama': 'AL',
'Alaska': 'AK',
'Arizona': 'AZ',
'Arkansas': 'AR',
'California': 'CA',
'Colorado': 'CO',
'Connecticut': 'CT',
'Delaware': 'DE',
'District of Columbia': 'DC',
'Florida': 'FL',
'Georgia': 'GA',
'Guam': 'GU',
'Hawaii': 'HI',
'Idaho': 'ID',
'Illinois': 'IL',
'Indiana': 'IN',
'Iowa': 'IA',
'Kansas': 'KS',
'Kentucky': 'KY',
'Louisiana': 'LA',
'Maine': 'ME',
'Maryland': 'MD',
'Massachusetts': 'MA',
'Michigan': 'MI',
'Minnesota': 'MN',
'Mississippi': 'MS',
'Missouri': 'MO',
'Montana': 'MT',
'Nebraska': 'NE',
'Nevada': 'NV',
'New Hampshire': 'NH',
'New Jersey': 'NJ',
'New Mexico': 'NM',
'New York': 'NY',
'North Carolina': 'NC',
'North Dakota': 'ND',
'Northern Mariana Islands':'MP',
'Ohio': 'OH',
'Oklahoma': 'OK',
'Oregon': 'OR',
'Pennsylvania': 'PA',
'Puerto Rico': 'PR',
'Rhode Island': 'RI',
'South Carolina': 'SC',
'South Dakota': 'SD',
'Tennessee': 'TN',
'Texas': 'TX',
'Utah': 'UT',
'Vermont': 'VT',
'Virgin Islands': 'VI',
'Virginia': 'VA',
'Washington': 'WA',
'Washington DC' : 'DC',
'West Virginia': 'WV',
'Wisconsin': 'WI',
'Wyoming': 'WY'
}
for v in state_abbrevs.values():
t = gtab.GTAB()
t.set_options(pytrends_config={"geo": f"US-{v}", "timeframe": "2020-09-01 2020-10-01"})
query = t.new_query("weather")
I've tried using an f string but that produces SyntaxError: can't assign to literal.
I used two answers from here. I think your best option is just storing the DataFrames in a dictionary but this should work to create your query_* variables.
query_dict = {}
for n, v in enumerate(state_abbrevs.values()):
t = gtab.GTAB()
t.set_options(pytrends_config={"geo": f"US-{v}", "timeframe": "2020-09-01 2020-10-01"})
query = t.new_query("weather")
key = "query_" + str(n)
query_dict[key] = query
for k in query_dict.keys():
exec("%s = query_dict['%s']" % (k,k))

Add two dictionaries into a json

I am trying to write two dictionaries into a JSON one after another in Python.
I have made two dictionaries which look like ---
dictionary_quant =
{'dmin': [0.003163, 14.325], 'magNst': [0.0, 414.0], 'horizontalError': [0.12, 12.9], 'nst': [3.0, 96.0], 'depth': [-3.09, 581.37], 'latitude': [-43.3468, 67.1524], 'rms': [0.0, 1.49], 'depthError': [0.0, 32.0], 'magError': [0.0, 1.34], 'mag': [-0.57, 6.9], 'gap': [18.0, 342.0], 'longitude': [-179.8024, 179.3064]}
dictionary_categorical =
{'magType': ['ml', 'md', 'mb', 'mb_lg', 'mwr', 'Md', 'mwb', nan, 'mww'], 'net': ['ci', 'nc', 'us', 'ak', 'mb', 'uw', 'nn', 'pr', 'se', 'nm', 'ismpkansas', 'hv', 'uu'], 'type': ['earthquake', 'explosion'], 'status': ['reviewed', 'automatic'], 'locationSource': ['ci', 'nc', 'us', 'ak', 'mb', 'uw', 'nn', 'pr', 'se', 'nm', 'ismp', 'hv', 'uu', 'ott', 'guc'], 'magSource': ['ci', 'nc', 'us', 'ak', 'mb', 'uw', 'nn', 'pr', 'se', 'nm', 'ismp', 'hv', 'uu', 'ott', 'guc']}
I am trying to write a json which looks like --
data = [
{
'name' : 'dmin',
'type' : 'quant',
'minmax' : [0.003163, 14.325]
},
{
'name' : 'magNSt',
'type' : 'quant',
'minmax' : [0.0, 414.0]
},
{....},
{....},
{
'name' : 'magType',
'type' : 'categor',
'categories' : ['ml', 'md', 'mb', 'mb_lg', 'mwr', 'Md', 'mwb', nan, 'mww']
},
{
'name' : 'net',
'type' : 'categor',
'categories' : ['ci', 'nc', 'us', 'ak', 'mb', 'uw', 'nn', 'pr', 'se', 'nm', 'ismpkansas', 'hv', 'uu']
}
]
Assuming that the exact output format can be flexible (see comment below), this can be done as follow.
import json
dictionary_quant = {'dmin': [0.003163, 14.325], 'magNst': [0.0, 414.0], 'horizontalError': [0.12, 12.9], 'nst': [3.0, 96.0], 'depth': [-3.09, 581.37], 'latitude': [-43.3468, 67.1524], 'rms': [0.0, 1.49], 'depthError': [0.0, 32.0], 'magError': [0.0, 1.34], 'mag': [-0.57, 6.9], 'gap': [18.0, 342.0], 'longitude': [-179.8024, 179.3064]}
# Replaced the undefined keyword / variable "nan" with None
dictionary_categorical = {'magType': ['ml', 'md', 'mb', 'mb_lg', 'mwr', 'Md', 'mwb', None, 'mww'], 'net': ['ci', 'nc', 'us', 'ak', 'mb', 'uw', 'nn', 'pr', 'se', 'nm', 'ismpkansas', 'hv', 'uu'], 'type': ['earthquake', 'explosion'], 'status': ['reviewed', 'automatic'], 'locationSource': ['ci', 'nc', 'us', 'ak', 'mb', 'uw', 'nn', 'pr', 'se', 'nm', 'ismp', 'hv', 'uu', 'ott', 'guc'], 'magSource': ['ci', 'nc', 'us', 'ak', 'mb', 'uw', 'nn', 'pr', 'se', 'nm', 'ismp', 'hv', 'uu', 'ott', 'guc']}
#Start with an empty data list
data = []
# Add each item in dictionary_quant with type set to "quant" and the
# value on key minmax
for k, v in dictionary_quant.items():
data.append({'type': 'quant',
'name': k,
'minmax': v})
# Add each item in dictionary_categorical with type set to "categor"
# and the value on key "categories"
for k, v in dictionary_categorical.items():
data.append({'type': 'categor',
'name': k,
'categories': v})
# Note: The json.dumps() function will output list attribute elements
# one-per-line when using indented output.
print(json.dumps(data, indent=4))
Assuming you know beforehand the type of each subsequent dictionary, you could do the following:
def format_data(data, data_type, value_name):
return [{'name': key, 'type': data_type, value_name: val} for key, val in data.items()]
where data is your dict, data_type is either quant or categor and value_name is either minmax or categories.
Then, combined that would be:
combined = format(dictionary_quant, 'quant', 'minmax') + format_data(dictionary_categorical, 'categor', 'categories')

Python convert string in array

Hello i have a string that looks like that
el-gu-en-tr-ca-it-eu-ca#valencia-ar-eo-cs-et-th_TH-gl-id-es-bn_IN-ru-he-nl-pt-no-nb-id_ID-lv-lt-pa-te-pl-ta-bg_BG-be-fr-de-bn_BD-uk-pt_BR-ast-hr-jv-zh_TW-sr#latin-da-fa-hi-tr_TR-fi-hu-ja-fo-bs_BA-ro-fa_IR-zh_CN-sr-sq-mn-ko-sv-km-sk-km_KH-en_GB-ms-sc-ug-bal
how can i break items by - and place them in an array like
array[0]->el
array[1]->gu
.....
Use the .split() method on your string:
>>> example = 'el-gu-en-tr-ca-it-eu-ca#valencia-ar-eo-cs-et-th_TH-gl-id-es-bn_IN-ru-he-nl-pt-no-nb-id_ID-lv-lt-pa-te-pl-ta-bg_BG-be-fr-de-bn_BD-uk-pt_BR-ast-hr-jv-zh_TW-sr#latin-da-fa-hi-tr_TR-fi-hu-ja-fo-bs_BA-ro-fa_IR-zh_CN-sr-sq-mn-ko-sv-km-sk-km_KH-en_GB-ms-sc-ug-bal'
>>> example.split('-')
['el', 'gu', 'en', 'tr', 'ca', 'it', 'eu', 'ca#valencia', 'ar', 'eo', 'cs', 'et', 'th_TH', 'gl', 'id', 'es', 'bn_IN', 'ru', 'he', 'nl', 'pt', 'no', 'nb', 'id_ID', 'lv', 'lt', 'pa', 'te', 'pl', 'ta', 'bg_BG', 'be', 'fr', 'de', 'bn_BD', 'uk', 'pt_BR', 'ast', 'hr', 'jv', 'zh_TW', 'sr#latin', 'da', 'fa', 'hi', 'tr_TR', 'fi', 'hu', 'ja', 'fo', 'bs_BA', 'ro', 'fa_IR', 'zh_CN', 'sr', 'sq', 'mn', 'ko', 'sv', 'km', 'sk', 'km_KH', 'en_GB', 'ms', 'sc', 'ug', 'bal']
Call str.split():
s = "el-gu-en-tr-ca-it-eu-ca#valencia-ar-eo-cs-et-th_TH-gl-id-es-bn_IN-ru-he-nl-pt-no-nb-id_ID-lv-lt-pa-te-pl-ta-bg_BG-be-fr-de-bn_BD-uk-pt_BR-ast-hr-jv-zh_TW-sr#latin-da-fa-hi-tr_TR-fi-hu-ja-fo-bs_BA-ro-fa_IR-zh_CN-sr-sq-mn-ko-sv-km-sk-km_KH-en_GB-ms-sc-ug-bal"
locales = s.split("-")

Categories

Resources