prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  MA: Where are the Republicans?
  All state legislators in MA are in either the Democratic party or Other.  It's a nice fantasy but it's not reality!
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `openstates/ma/legislators.py`
  Content:
  ```
  1 import re
  2 
  3 import lxml.html
  4 from billy.scrape.legislators import LegislatorScraper, Legislator
  5 
  6 
  7 def clean_district(district):
  8     mappings = {
  9         1: 'First',
  10         2: 'Second',
  11         3: 'Third',
  12         4: 'Fourth',
  13         5: 'Fifth',
  14         6: 'Sixth',
  15         7: 'Seventh',
  16         8: 'Eighth',
  17         9: 'Ninth',
  18         10: 'Tenth',
  19         11: 'Eleventh',
  20         12: 'Twelfth',
  21         13: 'Thirteenth',
  22         14: 'Fourteenth',
  23         15: 'Fifteenth',
  24         16: 'Sixteenth',
  25         17: 'Seventeenth',
  26         18: 'Eighteenth',
  27         19: 'Nineteenth',
  28         20: 'Twentieth',
  29     }
  30     pieces = re.match('(\d+)\w\w\s(.+)', district)
  31     if pieces:
  32         ordinal, rest = pieces.groups()
  33         ordinal = int(ordinal)
  34         if ordinal <= 20:
  35             ordinal = mappings[ordinal]
  36         elif ordinal < 30:
  37             ordinal = 'Twenty-' + mappings[ordinal-20]
  38         elif ordinal == 30:
  39             ordinal = 'Thirtieth'
  40         elif ordinal < 40:
  41             ordinal = 'Thirty-' + mappings[ordinal-30]
  42         district = '{} {}'.format(ordinal, rest)
  43 
  44     return district
  45 
  46 
  47 class MALegislatorScraper(LegislatorScraper):
  48     jurisdiction = 'ma'
  49 
  50     def scrape(self, chamber, term):
  51         self.validate_term(term, latest_only=True)
  52 
  53         if chamber == 'upper':
  54             chamber_type = 'Senate'
  55         else:
  56             chamber_type = 'House'
  57 
  58         url = "https://malegislature.gov/People/%s" % chamber_type
  59         page = self.get(url).text
  60         doc = lxml.html.fromstring(page)
  61         doc.make_links_absolute("https://malegislature.gov")
  62 
  63         for member_url in doc.xpath('//td[@class="pictureCol"]/a/@href'):
  64             self.scrape_member(chamber, term, member_url)
  65 
  66     def scrape_member(self, chamber, term, member_url):
  67         page = self.get(member_url).text
  68         root = lxml.html.fromstring(page)
  69         root.make_links_absolute(member_url)
  70 
  71         photo_url = root.xpath('//div[@class="thumbPhoto"]/img/@src')[0]
  72         full_name = root.xpath('//h1/span')[0].tail.strip()
  73 
  74         email = root.xpath('//a[contains(@href, "mailto")]/@href')[0]
  75         email = email.replace('mailto:', '')
  76 
  77         party, district = root.xpath('//h1/span')[1].text.split('-')
  78         party = party.strip()
  79         district = clean_district(district.strip())
  80 
  81         if party == 'Democrat':
  82             party = 'Democratic'
  83         elif party == 'R':
  84             party = 'Republican'
  85         else:
  86             party = 'Other'
  87 
  88         leg = Legislator(term, chamber, district, full_name, party=party,
  89                          photo_url=photo_url, url=member_url)
  90         leg.add_source(member_url)
  91 
  92         # offices
  93 
  94         # this bool is so we only attach the email to one office
  95         # and we make sure to create at least one office
  96         email_stored = True
  97         if email:
  98             email_stored = False
  99 
  100         for addr in root.xpath('//address/div[@class="contactGroup"]'):
  101             office_name = addr.xpath('../preceding-sibling::h4/text()'
  102                                      )[0].strip()
  103             address = addr.xpath('a')[0].text_content()
  104             address = re.sub('\s{2,}', '\n', address)
  105 
  106             phone = fax = next = None
  107             for phonerow in addr.xpath('./div/div'):
  108                 phonerow = phonerow.text_content().strip()
  109                 if phonerow == 'Phone:':
  110                     next = 'phone'
  111                 elif phonerow == 'Fax:':
  112                     next = 'fax'
  113                 elif next == 'phone':
  114                     phone = phonerow
  115                     next = None
  116                 elif next == 'fax':
  117                     fax = phonerow
  118                     next = None
  119                 else:
  120                     self.warning('unknown phonerow %s', phonerow)
  121 
  122             # all pieces collected
  123             if 'District' in office_name:
  124                 otype = 'district'
  125             elif 'State' in office_name:
  126                 otype = 'capitol'
  127 
  128             if not email_stored:
  129                 email_stored = True
  130                 leg.add_office(otype, office_name, phone=phone, fax=fax,
  131                                address=address, email=email)
  132             else:
  133                 leg.add_office(otype, office_name, phone=phone, fax=fax,
  134                                address=address)
  135 
  136         if not email_stored:
  137             leg.add_office('capitol', 'Capitol Office', email=email)
  138 
  139         self.save_legislator(leg)
  140
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/openstates/ma/legislators.py b/openstates/ma/legislators.py
  --- a/openstates/ma/legislators.py
  +++ b/openstates/ma/legislators.py
  @@ -78,9 +78,9 @@
           party = party.strip()
           district = clean_district(district.strip())
   
  -        if party == 'Democrat':
  +        if party in ('D', 'Democrat', 'Democratic'):
               party = 'Democratic'
  -        elif party == 'R':
  +        elif party in ('R', 'Republican'):
               party = 'Republican'
           else:
               party = 'Other'
  
verification_info: {"golden_diff": "diff --git a/openstates/ma/legislators.py b/openstates/ma/legislators.py\n--- a/openstates/ma/legislators.py\n+++ b/openstates/ma/legislators.py\n@@ -78,9 +78,9 @@\n         party = party.strip()\n         district = clean_district(district.strip())\n \n-        if party == 'Democrat':\n+        if party in ('D', 'Democrat', 'Democratic'):\n             party = 'Democratic'\n-        elif party == 'R':\n+        elif party in ('R', 'Republican'):\n             party = 'Republican'\n         else:\n             party = 'Other'\n", "issue": "MA: Where are the Republicans?\nAll state legislators in MA are in either the Democratic party or Other.  It's a nice fantasy but it's not reality!\r\n\n", "before_files": [{"content": "import re\n\nimport lxml.html\nfrom billy.scrape.legislators import LegislatorScraper, Legislator\n\n\ndef clean_district(district):\n    mappings = {\n        1: 'First',\n        2: 'Second',\n        3: 'Third',\n        4: 'Fourth',\n        5: 'Fifth',\n        6: 'Sixth',\n        7: 'Seventh',\n        8: 'Eighth',\n        9: 'Ninth',\n        10: 'Tenth',\n        11: 'Eleventh',\n        12: 'Twelfth',\n        13: 'Thirteenth',\n        14: 'Fourteenth',\n        15: 'Fifteenth',\n        16: 'Sixteenth',\n        17: 'Seventeenth',\n        18: 'Eighteenth',\n        19: 'Nineteenth',\n        20: 'Twentieth',\n    }\n    pieces = re.match('(\\d+)\\w\\w\\s(.+)', district)\n    if pieces:\n        ordinal, rest = pieces.groups()\n        ordinal = int(ordinal)\n        if ordinal <= 20:\n            ordinal = mappings[ordinal]\n        elif ordinal < 30:\n            ordinal = 'Twenty-' + mappings[ordinal-20]\n        elif ordinal == 30:\n            ordinal = 'Thirtieth'\n        elif ordinal < 40:\n            ordinal = 'Thirty-' + mappings[ordinal-30]\n        district = '{} {}'.format(ordinal, rest)\n\n    return district\n\n\nclass MALegislatorScraper(LegislatorScraper):\n    jurisdiction = 'ma'\n\n    def scrape(self, chamber, term):\n        self.validate_term(term, latest_only=True)\n\n        if chamber == 'upper':\n            chamber_type = 'Senate'\n        else:\n            chamber_type = 'House'\n\n        url = \"https://malegislature.gov/People/%s\" % chamber_type\n        page = self.get(url).text\n        doc = lxml.html.fromstring(page)\n        doc.make_links_absolute(\"https://malegislature.gov\")\n\n        for member_url in doc.xpath('//td[@class=\"pictureCol\"]/a/@href'):\n            self.scrape_member(chamber, term, member_url)\n\n    def scrape_member(self, chamber, term, member_url):\n        page = self.get(member_url).text\n        root = lxml.html.fromstring(page)\n        root.make_links_absolute(member_url)\n\n        photo_url = root.xpath('//div[@class=\"thumbPhoto\"]/img/@src')[0]\n        full_name = root.xpath('//h1/span')[0].tail.strip()\n\n        email = root.xpath('//a[contains(@href, \"mailto\")]/@href')[0]\n        email = email.replace('mailto:', '')\n\n        party, district = root.xpath('//h1/span')[1].text.split('-')\n        party = party.strip()\n        district = clean_district(district.strip())\n\n        if party == 'Democrat':\n            party = 'Democratic'\n        elif party == 'R':\n            party = 'Republican'\n        else:\n            party = 'Other'\n\n        leg = Legislator(term, chamber, district, full_name, party=party,\n                         photo_url=photo_url, url=member_url)\n        leg.add_source(member_url)\n\n        # offices\n\n        # this bool is so we only attach the email to one office\n        # and we make sure to create at least one office\n        email_stored = True\n        if email:\n            email_stored = False\n\n        for addr in root.xpath('//address/div[@class=\"contactGroup\"]'):\n            office_name = addr.xpath('../preceding-sibling::h4/text()'\n                                     )[0].strip()\n            address = addr.xpath('a')[0].text_content()\n            address = re.sub('\\s{2,}', '\\n', address)\n\n            phone = fax = next = None\n            for phonerow in addr.xpath('./div/div'):\n                phonerow = phonerow.text_content().strip()\n                if phonerow == 'Phone:':\n                    next = 'phone'\n                elif phonerow == 'Fax:':\n                    next = 'fax'\n                elif next == 'phone':\n                    phone = phonerow\n                    next = None\n                elif next == 'fax':\n                    fax = phonerow\n                    next = None\n                else:\n                    self.warning('unknown phonerow %s', phonerow)\n\n            # all pieces collected\n            if 'District' in office_name:\n                otype = 'district'\n            elif 'State' in office_name:\n                otype = 'capitol'\n\n            if not email_stored:\n                email_stored = True\n                leg.add_office(otype, office_name, phone=phone, fax=fax,\n                               address=address, email=email)\n            else:\n                leg.add_office(otype, office_name, phone=phone, fax=fax,\n                               address=address)\n\n        if not email_stored:\n            leg.add_office('capitol', 'Capitol Office', email=email)\n\n        self.save_legislator(leg)\n", "path": "openstates/ma/legislators.py"}], "after_files": [{"content": "import re\n\nimport lxml.html\nfrom billy.scrape.legislators import LegislatorScraper, Legislator\n\n\ndef clean_district(district):\n    mappings = {\n        1: 'First',\n        2: 'Second',\n        3: 'Third',\n        4: 'Fourth',\n        5: 'Fifth',\n        6: 'Sixth',\n        7: 'Seventh',\n        8: 'Eighth',\n        9: 'Ninth',\n        10: 'Tenth',\n        11: 'Eleventh',\n        12: 'Twelfth',\n        13: 'Thirteenth',\n        14: 'Fourteenth',\n        15: 'Fifteenth',\n        16: 'Sixteenth',\n        17: 'Seventeenth',\n        18: 'Eighteenth',\n        19: 'Nineteenth',\n        20: 'Twentieth',\n    }\n    pieces = re.match('(\\d+)\\w\\w\\s(.+)', district)\n    if pieces:\n        ordinal, rest = pieces.groups()\n        ordinal = int(ordinal)\n        if ordinal <= 20:\n            ordinal = mappings[ordinal]\n        elif ordinal < 30:\n            ordinal = 'Twenty-' + mappings[ordinal-20]\n        elif ordinal == 30:\n            ordinal = 'Thirtieth'\n        elif ordinal < 40:\n            ordinal = 'Thirty-' + mappings[ordinal-30]\n        district = '{} {}'.format(ordinal, rest)\n\n    return district\n\n\nclass MALegislatorScraper(LegislatorScraper):\n    jurisdiction = 'ma'\n\n    def scrape(self, chamber, term):\n        self.validate_term(term, latest_only=True)\n\n        if chamber == 'upper':\n            chamber_type = 'Senate'\n        else:\n            chamber_type = 'House'\n\n        url = \"https://malegislature.gov/People/%s\" % chamber_type\n        page = self.get(url).text\n        doc = lxml.html.fromstring(page)\n        doc.make_links_absolute(\"https://malegislature.gov\")\n\n        for member_url in doc.xpath('//td[@class=\"pictureCol\"]/a/@href'):\n            self.scrape_member(chamber, term, member_url)\n\n    def scrape_member(self, chamber, term, member_url):\n        page = self.get(member_url).text\n        root = lxml.html.fromstring(page)\n        root.make_links_absolute(member_url)\n\n        photo_url = root.xpath('//div[@class=\"thumbPhoto\"]/img/@src')[0]\n        full_name = root.xpath('//h1/span')[0].tail.strip()\n\n        email = root.xpath('//a[contains(@href, \"mailto\")]/@href')[0]\n        email = email.replace('mailto:', '')\n\n        party, district = root.xpath('//h1/span')[1].text.split('-')\n        party = party.strip()\n        district = clean_district(district.strip())\n\n        if party in ('D', 'Democrat', 'Democratic'):\n            party = 'Democratic'\n        elif party in ('R', 'Republican'):\n            party = 'Republican'\n        else:\n            party = 'Other'\n\n        leg = Legislator(term, chamber, district, full_name, party=party,\n                         photo_url=photo_url, url=member_url)\n        leg.add_source(member_url)\n\n        # offices\n\n        # this bool is so we only attach the email to one office\n        # and we make sure to create at least one office\n        email_stored = True\n        if email:\n            email_stored = False\n\n        for addr in root.xpath('//address/div[@class=\"contactGroup\"]'):\n            office_name = addr.xpath('../preceding-sibling::h4/text()'\n                                     )[0].strip()\n            address = addr.xpath('a')[0].text_content()\n            address = re.sub('\\s{2,}', '\\n', address)\n\n            phone = fax = next = None\n            for phonerow in addr.xpath('./div/div'):\n                phonerow = phonerow.text_content().strip()\n                if phonerow == 'Phone:':\n                    next = 'phone'\n                elif phonerow == 'Fax:':\n                    next = 'fax'\n                elif next == 'phone':\n                    phone = phonerow\n                    next = None\n                elif next == 'fax':\n                    fax = phonerow\n                    next = None\n                else:\n                    self.warning('unknown phonerow %s', phonerow)\n\n            # all pieces collected\n            if 'District' in office_name:\n                otype = 'district'\n            elif 'State' in office_name:\n                otype = 'capitol'\n\n            if not email_stored:\n                email_stored = True\n                leg.add_office(otype, office_name, phone=phone, fax=fax,\n                               address=address, email=email)\n            else:\n                leg.add_office(otype, office_name, phone=phone, fax=fax,\n                               address=address)\n\n        if not email_stored:\n            leg.add_office('capitol', 'Capitol Office', email=email)\n\n        self.save_legislator(leg)\n", "path": "openstates/ma/legislators.py"}]}