# -*- coding: utf-8 -*-
"""Contains core classes and functions for defining populations and acting upon
them.
"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from __future__ import unicode_literals

from collections import namedtuple


RECORD_FIELDS = (
   'first_name',
   'middle_name',
   'last_name',
   'suffix',
   'address',
   'sex',
   'gender',
   'ssn',
   'birthdate',
   'blood_type',
)

_RECORD_FIELDS = (
   'soundex',
   'nysiis',
   'metaphone',
   'dmetaphone',
)


class Record(namedtuple('Record', RECORD_FIELDS)):
    __slots__ = ()  # Prevent per-instance dictionaries to reduce memory


class _Record(namedtuple('_Record', Record._fields + _RECORD_FIELDS)):
    """An immutable representation of an electronic health record, primarily
    containing identifying patient information.

    This is an internal class that is not indented to be used directly.
    """
    __slots__ = ()  # Prevent per-instance dictionaries to reduce memory


class Herd(object):
    """A collection of :py:class:`._Record`s with methods for interacting with
    and linking records in the herd.

    You need:
    - validate names (check for commas, weird chars, convert to unicode/ascii?)
        * remove Mrs, PhD, Ms., etc.
        * check for commas, weird chars
        * convert to unicode/ascii?
    - validate that you only have certain field names in the incoming dict
    - parse names into first, last, prefix, suffix

    need to make separate .csv's for each region
    get male and female names and combine
    only use the No. 1, No. 2, and No. 3 names
    download whatever is in the first <a> (some names will be left out)
    split by / and add to list
    split by , and add to list
    split by ( and remove whatever comes after the opening parenthesis
              then convert everything to ASCII (i.e. need to remove accented
                                                characters, umlaus)

              when you generate a single file, you might make 1000 names and
              make the population of names representative of the population of
              ethnicities in the US. or just compare separately.

              what do you do with names with JR...SR...I...II?

    HAVE ABILITY to grow a herd, which doesn't mean adding to the tuple of
    Records...have it be a way around memory limitations. That means that
    instead of 'appending' to the tuple of Records, it immediately sends
    the data to append to the ES database. It should therefore be that you
    require a connection object in order to create a herd (maybe not).

    """
    def __init__(self, population=None):
        self._population = None  # Declaration for readability
        self.population = () if population is None else population

    def __str__(self):
        population = self.population
        if len(population) > 6:
            return "[\n  {},\n  {},\n  {}\n...,\n  {},\n  {}\n]".format(
                population[0],
                population[1],
                population[2],
                population[-2],
                population[-1]
            )
        else:
            return str(population)

    def __repr__(self):
        return "Herd(population={})".format(str(self))

    @property
    def population(self):
        """Get the current population."""
        return self._population

    @population.setter
    def population(self, value):
        """Validate and set the herd's population."""
        if not isinstance(value, (tuple, list)):
            raise ValueError("Expected a tuple or list.")
        #if not all(isinstance(profile, dict) for profile in value):
        #    raise ValueError("Expected a tuple of dictionaries.")
        
        self._population = value

@@ -315,16 +315,17 @@
  = (%0A   
+ 
 'first_n
@@ -326,24 +326,25 @@
 irst_name',%0A
+ 
    'middle_n
@@ -352,16 +352,17 @@
 me',%0A   
+ 
 'last_na
@@ -362,24 +362,25 @@
 last_name',%0A
+ 
    'suffix',
@@ -383,16 +383,17 @@
 ix',%0A   
+ 
 'address
@@ -402,15 +402,17 @@
 %0A   
+ 
 'sex',%0A
+ 
    '
@@ -427,15 +427,17 @@
 %0A   
+ 
 'ssn',%0A
+ 
    '
@@ -444,24 +444,25 @@
 birthdate',%0A
+ 
    'blood_ty
@@ -469,23 +469,20 @@
 pe',%0A)%0A%0A
-_RECORD
+META
 _FIELDS 
@@ -485,16 +485,27 @@
 LDS = (%0A
+    'id',%0A 
    'soun
@@ -510,16 +510,17 @@
 undex',%0A
+ 
    'nysi
@@ -527,16 +527,17 @@
 is',%0A   
+ 
 'metapho
@@ -541,16 +541,17 @@
 phone',%0A
+ 
    'dmet
@@ -693,360 +693,8 @@
 y%0A%0A%0A
-class _Record(namedtuple('_Record', Record._fields + _RECORD_FIELDS)):%0A    %22%22%22An immutable representation of an electronic health record, primarily%0A    containing identifying patient information.%0A%0A    This is an internal class that is not indented to be used directly.%0A    %22%22%22%0A    __slots__ = ()  # Prevent per-instance dictionaries to reduce memory%0A%0A%0A
 clas
@@ -2337,157 +2337,39 @@
 self
-, population=None):%0A        self._population = None  # Declaration for readability%0A        self.population = () if population is None else population
+):%0A        self.population = ()
 %0A%0A  
@@ -2751,16 +2751,17 @@
 ation)%0A%0A
+#
     def 
@@ -2768,32 +2768,33 @@
 __repr__(self):%0A
+#
         return %22
@@ -2837,22 +2837,8 @@
 ))%0A%0A
-    @property%0A
     
@@ -2848,24 +2848,31 @@
  populat
-ion
+e
 (self
+, records
 ):%0A     
@@ -2881,24 +2881,28 @@
  %22%22%22
-G
+S
 et
+s
  the 
-current 
+Herd's sub-
 popu
@@ -2900,35 +2900,33 @@
  sub-population.
-%22%22%22
+%0A
 %0A        return 
@@ -2922,139 +2922,98 @@
     
-return self._population%0A%0A    @population.setter%0A    def population(self, value):%0A        %22%22%22Validate and set the herd's population.
+Args:%0A            records (list, tuple): A list or tuple of :py:class:%60._Record%60s%0A        
 %22%22%22%0A
@@ -3038,21 +3038,23 @@
 nstance(
-value
+records
 , (tuple
@@ -3133,20 +3133,11 @@
     
-#
 if 
-not all(
 isin
@@ -3147,43 +3147,21 @@
 nce(
-profile, dict) for profile in value
+records, list
 ):%0A 
@@ -3171,76 +3171,37 @@
     
-#
     r
-aise ValueError(%22Expected a tuple of dictionaries.%22
+ecords = tuple(records
 )%0A
-        %0A
     
@@ -3209,17 +3209,16 @@
    self.
-_
 populati
@@ -3226,10 +3226,12 @@
 n = 
-value
+records
 %0A

Create method to populate a herd, remove population getter and setter