<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from distutils.util import strtobool

def yn_prompt(query):
    """Generic Y/N Prompt"""

    sys.stdout.write('%s [y/n]: ' % query)
    val = raw_input()
    try:
        ret = strtobool(val)
    except ValueError:
        sys.stdout.write('Please answer with a y/n\n')
        return yn_prompt(query)
    return ret

# prompts
install = yn_prompt("\nInstall UCP using 'non-interactive' mode on the controller instance?")

if install:
    txt = 'docker run --rm --name ucp -v /var/run/docker.sock:/var/run/docker.sock docker/ucp install'
else:
    txt = 'docker run --name ucp --rm -v /var/run/docker.sock:/var/run/docker.sock docker/ucp images'

# scripts
PRIMARY_OS = 'Ubuntu-14.04'
CONTROLLER = '''#!/bin/sh

FQDN="{{fqdn}}"

export DEBIAN_FRONTEND=noninteractive

# locale
sudo locale-gen en_US.UTF-8

# /etc/hostname - /etc/hosts
sed -i "1 c\\127.0.0.1 $FQDN localhost" /etc/hosts
echo $FQDN > /etc/hostname
service hostname restart
sleep 5

# docker
curl -sSL https://get.docker.com/ | sh

usermod -aG docker ubuntu

# docker compose
curl -L https://github.com/docker/compose/releases/download/1.6.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

# packages
apt-get install -y git tree jq

# download/install upc
{0}

{{dinfo}}
'''.format(txt)

NODE = '''#!/bin/sh

FQDN="{fqdn}"

export DEBIAN_FRONTEND=noninteractive

# locale
sudo locale-gen en_US.UTF-8

# /etc/hostname - /etc/hosts
sed -i "1 c\\127.0.0.1 $FQDN localhost" /etc/hosts
echo $FQDN > /etc/hostname
service hostname restart
sleep 5

# docker
curl -sSL https://get.docker.com/ | sh

usermod -aG docker ubuntu

# docker compose
curl -L https://github.com/docker/compose/releases/download/1.6.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

# packages
apt-get install -y git tree jq

# download upc
docker run --name ucp --rm -v /var/run/docker.sock:/var/run/docker.sock docker/ucp images

{dinfo}
'''

AMIBUILD = '''#!/bin/sh
#
FQDN="{{fqdn}}"

# /etc/hostname - /etc/hosts
sed -i "1 c\\127.0.0.1 $FQDN localhost" /etc/hosts
echo $FQDN > /etc/hostname
service hostname restart
sleep 5

{{dinfo}}
reboot
'''

def pre_process():
    """Executed before launching instances in AWS"""
    pass

def post_process():
    """Executed after launching instances in AWS"""
    print "Instances Launched ...\n\nNOTE: If you selected the non-interactive install during launch the default user/pass is: admin/orca\n"
<commit_msg>Add public IP with --sans to UCP install<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from distutils.util import strtobool

def yn_prompt(query):
    """Generic Y/N Prompt"""

    sys.stdout.write('%s [y/n]: ' % query)
    val = raw_input()
    try:
        ret = strtobool(val)
    except ValueError:
        sys.stdout.write('Please answer with a y/n\n')
        return yn_prompt(query)
    return ret

# prompts
install = yn_prompt("\nInstall UCP using 'non-interactive' mode on the controller instance?")

if install:
    txt = 'docker run --rm --name ucp -v /var/run/docker.sock:/var/run/docker.sock docker/ucp install --san $(curl http://169.254.169.254/latest/meta-data/public-ipv4)'
else:
    txt = 'docker run --name ucp --rm -v /var/run/docker.sock:/var/run/docker.sock docker/ucp images'

# scripts
PRIMARY_OS = 'Ubuntu-14.04'
CONTROLLER = '''#!/bin/sh

FQDN="{{fqdn}}"

export DEBIAN_FRONTEND=noninteractive

# locale
sudo locale-gen en_US.UTF-8

# /etc/hostname - /etc/hosts
sed -i "1 c\\127.0.0.1 $FQDN localhost" /etc/hosts
echo $FQDN > /etc/hostname
service hostname restart
sleep 5

# docker
curl -sSL https://get.docker.com/ | sh

usermod -aG docker ubuntu

# docker compose
curl -L https://github.com/docker/compose/releases/download/1.6.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

# packages
apt-get install -y git tree jq

# download/install upc
{0}

{{dinfo}}
'''.format(txt)

NODE = '''#!/bin/sh

FQDN="{fqdn}"

export DEBIAN_FRONTEND=noninteractive

# locale
sudo locale-gen en_US.UTF-8

# /etc/hostname - /etc/hosts
sed -i "1 c\\127.0.0.1 $FQDN localhost" /etc/hosts
echo $FQDN > /etc/hostname
service hostname restart
sleep 5

# docker
curl -sSL https://get.docker.com/ | sh

usermod -aG docker ubuntu

# docker compose
curl -L https://github.com/docker/compose/releases/download/1.6.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

# packages
apt-get install -y git tree jq

# download upc
docker run --name ucp --rm -v /var/run/docker.sock:/var/run/docker.sock docker/ucp images

{dinfo}
'''

AMIBUILD = '''#!/bin/sh
#
FQDN="{{fqdn}}"

# /etc/hostname - /etc/hosts
sed -i "1 c\\127.0.0.1 $FQDN localhost" /etc/hosts
echo $FQDN > /etc/hostname
service hostname restart
sleep 5

{{dinfo}}
reboot
'''

def pre_process():
    """Executed before launching instances in AWS"""
    pass

def post_process():
    """Executed after launching instances in AWS"""
    print "Instances Launched ...\n\nNOTE: If you selected the non-interactive install during launch the default user/pass is: admin/orca\n"
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from distutils.util import strtobool

def yn_prompt(query):
    """Generic Y/N Prompt"""

    sys.stdout.write('%s [y/n]: ' % query)
    val = raw_input()
    try:
        ret = strtobool(val)
    except ValueError:
        sys.stdout.write('Please answer with a y/n\n')
        return yn_prompt(query)
    return ret

# prompts
install = yn_prompt("\nInstall UCP using 'non-interactive' mode on the controller instance?")

if install:
    txt = 'docker run --rm --name ucp -v /var/run/docker.sock:/var/run/docker.sock docker/ucp install --san $(curl http://169.254.169.254/latest/meta-data/public-ipv4)'
else:
    txt = 'docker run --name ucp --rm -v /var/run/docker.sock:/var/run/docker.sock docker/ucp images'

# scripts
PRIMARY_OS = 'Ubuntu-14.04'
CONTROLLER = '''#!/bin/sh

FQDN="{{fqdn}}"

export DEBIAN_FRONTEND=noninteractive

# locale
sudo locale-gen en_US.UTF-8

# /etc/hostname - /etc/hosts
sed -i "1 c\\127.0.0.1 $FQDN localhost" /etc/hosts
echo $FQDN > /etc/hostname
service hostname restart
sleep 5

# docker
curl -sSL https://get.docker.com/ | sh

usermod -aG docker ubuntu

# docker compose
curl -L https://github.com/docker/compose/releases/download/1.6.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

# packages
apt-get install -y git tree jq

# download/install upc
{0}

{{dinfo}}
'''.format(txt)

NODE = '''#!/bin/sh

FQDN="{fqdn}"

export DEBIAN_FRONTEND=noninteractive

# locale
sudo locale-gen en_US.UTF-8

# /etc/hostname - /etc/hosts
sed -i "1 c\\127.0.0.1 $FQDN localhost" /etc/hosts
echo $FQDN > /etc/hostname
service hostname restart
sleep 5

# docker
curl -sSL https://get.docker.com/ | sh

usermod -aG docker ubuntu

# docker compose
curl -L https://github.com/docker/compose/releases/download/1.6.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

# packages
apt-get install -y git tree jq

# download upc
docker run --name ucp --rm -v /var/run/docker.sock:/var/run/docker.sock docker/ucp images

{dinfo}
'''

AMIBUILD = '''#!/bin/sh
#
FQDN="{{fqdn}}"

# /etc/hostname - /etc/hosts
sed -i "1 c\\127.0.0.1 $FQDN localhost" /etc/hosts
echo $FQDN > /etc/hostname
service hostname restart
sleep 5

{{dinfo}}
reboot
'''

def pre_process():
    """Executed before launching instances in AWS"""
    pass

def post_process():
    """Executed after launching instances in AWS"""
    print "Instances Launched ...\n\nNOTE: If you selected the non-interactive install during launch the default user/pass is: admin/orca\n"
<commit_msg>Use --hostaddress in UCP<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from distutils.util import strtobool

def yn_prompt(query):
    """Generic Y/N Prompt"""

    sys.stdout.write('%s [y/n]: ' % query)
    val = raw_input()
    try:
        ret = strtobool(val)
    except ValueError:
        sys.stdout.write('Please answer with a y/n\n')
        return yn_prompt(query)
    return ret

# prompts
install = yn_prompt("\nInstall UCP using 'non-interactive' mode on the controller instance?")

if install:
    txt = 'docker run --rm --name ucp -v /var/run/docker.sock:/var/run/docker.sock docker/ucp install --host-address $(curl http://169.254.169.254/latest/meta-data/public-hostname)'
else:
    txt = 'docker run --name ucp --rm -v /var/run/docker.sock:/var/run/docker.sock docker/ucp images'

# scripts
PRIMARY_OS = 'Ubuntu-14.04'
CONTROLLER = '''#!/bin/sh

FQDN="{{fqdn}}"

export DEBIAN_FRONTEND=noninteractive

# locale
sudo locale-gen en_US.UTF-8

# /etc/hostname - /etc/hosts
sed -i "1 c\\127.0.0.1 $FQDN localhost" /etc/hosts
echo $FQDN > /etc/hostname
service hostname restart
sleep 5

# docker
curl -sSL https://get.docker.com/ | sh

usermod -aG docker ubuntu

# docker compose
curl -L https://github.com/docker/compose/releases/download/1.6.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

# packages
apt-get install -y git tree jq

# download/install upc
{0}

{{dinfo}}
'''.format(txt)

NODE = '''#!/bin/sh

FQDN="{fqdn}"

export DEBIAN_FRONTEND=noninteractive

# locale
sudo locale-gen en_US.UTF-8

# /etc/hostname - /etc/hosts
sed -i "1 c\\127.0.0.1 $FQDN localhost" /etc/hosts
echo $FQDN > /etc/hostname
service hostname restart
sleep 5

# docker
curl -sSL https://get.docker.com/ | sh

usermod -aG docker ubuntu

# docker compose
curl -L https://github.com/docker/compose/releases/download/1.6.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

# packages
apt-get install -y git tree jq

# download upc
docker run --name ucp --rm -v /var/run/docker.sock:/var/run/docker.sock docker/ucp images

{dinfo}
'''

AMIBUILD = '''#!/bin/sh
#
FQDN="{{fqdn}}"

# /etc/hostname - /etc/hosts
sed -i "1 c\\127.0.0.1 $FQDN localhost" /etc/hosts
echo $FQDN > /etc/hostname
service hostname restart
sleep 5

{{dinfo}}
reboot
'''

def pre_process():
    """Executed before launching instances in AWS"""
    pass

def post_process():
    """Executed after launching instances in AWS"""
    print "Instances Launched ...\n\nNOTE: If you selected the non-interactive install during launch the default user/pass is: admin/orca\n"
<|endoftext|>


<commit_before>import re

from twilio.exceptions import TwilioException
from .util import change_dict_key, transform_params
from .util import UNSET_TIMEOUT
from . import InstanceResource, ListResource

TYPES = {"local": "Local", "tollfree": "TollFree", "mobile": "Mobile"}

class AvailablePhoneNumber(InstanceResource):
    """ An available phone number resource

   .. attribute:: friendly_name

      A nicely-formatted version of the phone number.

   .. attribute:: phone_number

      The phone number, in E.164 (i.e. "+1") format.

   .. attribute:: lata

      The LATA of this phone number.

   .. attribute:: rate_center

      The rate center of this phone number.

   .. attribute:: latitude

      The latitude coordinate of this phone number.

   .. attribute:: longitude

      The longitude coordinate of this phone number.

   .. attribute:: region

      The two-letter state or province abbreviation of this phone number.

   .. attribute:: postal_code

      The postal (zip) code of this phone number.

   .. attribute:: iso_country

        The country for this number

   .. attribute:: address_requirements

        Whether the phone number requires you or your customer to have an
        Address registered with Twilio. Possible values are 'none', 'any',
        'local', or 'foreign'.

    """

    def __init__(self, parent):
        # Available Phone Numbers have no sid.
        super(AvailablePhoneNumber, self).__init__(parent, "")
        self.name = ""

    def purchase(self, **kwargs):
        return self.parent.purchase(phone_number=self.phone_number,
                                    **kwargs)

class AvailablePhoneNumbers(ListResource):

    name = "AvailablePhoneNumbers"
    key = "available_phone_numbers"
    instance = AvailablePhoneNumber

    def __init__(self, base_uri, auth, timeout, phone_numbers):
        super(AvailablePhoneNumbers, self).__init__(base_uri, auth, timeout)
        self.phone_numbers = phone_numbers

    def get(self, sid):
        raise TwilioException("Individual AvailablePhoneNumbers have no sid")

    def list(self, type="local", country="US", region=None, postal_code=None,
             lata=None, rate_center=None, **kwargs):
        """
        Search for phone numbers
        """
        kwargs["in_region"] = kwargs.get("in_region", region)
        kwargs["in_postal_code"] = kwargs.get("in_postal_code", postal_code)
        kwargs["in_lata"] = kwargs.get("in_lata", lata)
        kwargs["in_rate_center"] = kwargs.get("in_rate_center", rate_center)
        params = transform_params(kwargs)

        uri = "%s/%s/%s" % (self.uri, country, TYPES[type])
        resp, page = self.request("GET", uri, params=params)

        return [self.load_instance(i) for i in page[self.key]]

    def load_instance(self, data):
        instance = self.instance(self.phone_numbers)
        instance.load(data)
        instance.load_subresources()
        return instance

class PhoneNumber(InstanceResource):
    """ An IncomingPhoneNumber object

   .. attribute:: sid

      A 34 character string that uniquely identifies this resource.

   .. attribute:: date_created

      The date that this resource was created, given as GMT RFC 2822 format.

   .. attribute:: date_updated

      The date that this resource was last updated, in GMT RFC 2822 format.

   .. attribute:: friendly_name

      A human readable descriptive text for this resource, up to 64 characters
      long. By default, the FriendlyName is a nicely formatted version of
      the phone number.

   .. attribute:: account_sid

      The unique id of the Account responsible for this phone number.

   .. attribute:: phone_number

      The incoming phone number. e.g., +16175551212 (E.164 format)

   .. attribute:: api_version

      Calls to this phone number will start a new TwiML session with this
      API version.

   .. attribute:: voice_caller_id_lookup

      Look up the caller's caller-ID name from the CNAM database (additional
      charges apply). Either true or false.

   .. attribute:: voice_url

      The URL Twilio will request when this phone number receives a call.

   .. attribute:: voice_method

      The HTTP method Twilio will use when requesting the above Url.
      Either GET or POST.

   .. attribute:: voice_fallback_url

      The URL that Twilio will request if an error occurs retrieving or
      executing the TwiML requested by Url.

   .. attribute:: voice_fallback_method

      The HTTP method Twilio will use when requesting the VoiceFallbackUrl.
      Either GET or POST.

   .. attribute:: status_callback

      The URL that Twilio will request to pass status parameters (such as
      call ended) to your application.

   .. attribute:: status_callback_method

      The HTTP method Twilio will use to make requests to the
      StatusCallback URL. Either GET or POST.

   .. attribute:: sms_url

      The URL Twilio will request when receiving an incoming SMS message
      to this number.

   .. attribute:: sms_method

      The HTTP method Twilio will use when making requests to the SmsUrl.
      Either GET or POST.

   .. attribute:: sms_fallback_url

      The URL that Twilio will request if an error occurs retrieving or
      executing the TwiML from SmsUrl.

   .. attribute:: sms_fallback_method

      The HTTP method Twilio will use when requesting the above URL.
      Either GET or POST.

   .. attribute:: uri

      The URI for this resource, relative to https://api.twilio.com.
    """

    def load(self, entries):
        """ Set the proper Account owner of this phone number """

        # Only check if entries has a uri
        if "account_sid" in entries:
            # Parse the parent's uri to get the scheme and base
            uri = re.sub(r'AC(.*)', entries["account_sid"],
                         self.parent.base_uri)

            self.parent = PhoneNumbers(
                uri,
                self.parent.auth,
                self.parent.timeout
            )
            self.base_uri = self.parent.uri

        super(PhoneNumber, self).load(entries)

    def transfer(self, account_sid):
        """
        Transfer the phone number with sid from the current account to another
        identified by account_sid
        """
        a = self.parent.transfer(self.name, account_sid)
        self.load(a.__dict__)

    def update(self, **kwargs):
        """
        Update this phone number instance.
        """
        kwargs_copy = dict(kwargs)
        change_dict_key(kwargs_copy, from_key="status_callback_url",
                        to_key="status_callback")

        a = self.parent.update(self.name, **kwargs_copy)
        self.load(a.__dict__)

    def delete(self):
        """
        Release this phone number from your account. Twilio will no longer
        answer calls to this number, and you will stop being billed the monthly
        phone number fees. The phone number will eventually be recycled and
        potentially given to another customer, so use with care. If you make a
        mistake, contact us... we may be able to give you the number back.
        """
        return self.parent.delete(self.name)

class PhoneNumbers(ListResource):

    name = "IncomingPhoneNumbers"
    key = "incoming_phone_numbers"
    instance = PhoneNumber

    def __init__(self, base_uri, auth, timeout=UNSET_TIMEOUT):
        super(PhoneNumbers, self).__init__(base_uri, auth, timeout)
        self.available_phone_numbers = \
            AvailablePhoneNumbers(base_uri, auth, timeout, self)

    def delete(self, sid):
        """
        Release this phone number from your account. Twilio will no longer
        answer calls to this number, and you will stop being billed the
        monthly phone number fees. The phone number will eventually be
        recycled and potentially given to another customer, so use with care.
        If you make a mistake, contact us... we may be able to give you the
        number back.
        """
        return self.delete_instance(sid)

    def list(self, type=None, **kwargs):
        """
        :param phone_number: Show phone numbers that match this pattern.
        :param friendly_name: Show phone numbers with this friendly name
        :param type: Filter numbers by type. Available types are
            'local', 'mobile', or 'tollfree'

        You can specify partial numbers and use '*' as a wildcard.
        """

        uri = self.uri
        if type:
            uri = "%s/%s" % (self.uri, TYPES[type])

        params = transform_params(kwargs)
        resp, page = self.request("GET", uri, params=params)

        return [self.load_instance(i) for i in page[self.key]]

    def purchase(self, status_callback_url=None, **kwargs):
        """
        Attempt to purchase the specified number. The only required parameters
        are **either** phone_number or area_code

        :returns: Returns a :class:`PhoneNumber` instance on success,
                  :data:`False` on failure
        :raises: A :exc:`TypeError` if neither phone_number or area_code
        is specified.
        """
        kwargs["StatusCallback"] = kwargs.get("status_callback",
                                              status_callback_url)

        if 'phone_number' not in kwargs and 'area_code' not in kwargs:
            raise TypeError("phone_number or area_code is required")

        number_type = kwargs.pop('type', False)
        uri = self.uri
        if number_type:
            uri = "%s/%s" % (self.uri, TYPES[number_type])

        params = transform_params(kwargs)
        resp, instance = self.request('POST', uri, data=params)

        return self.load_instance(instance)

    def search(self, **kwargs):
        """
        :param type: The type of phone number to search for.
        :param str country: Only show numbers for this country (iso2)
        :param str region: When searching the US, show numbers in this state
        :param str postal_code: Only show numbers in this area code
        :param str rate_center: US only.
        :param tuple near_lat_long: Find close numbers within Distance miles.
        :param integer distance: Search radius for a Near- query in miles.
        """
        return self.available_phone_numbers.list(**kwargs)

    def transfer(self, sid, account_sid):
        """
        Transfer the phone number with sid from the current account to another
        identified by account_sid
        """
        return self.update(sid, account_sid=account_sid)

    def update(self, sid, **kwargs):
        """
        Update this phone number instance
        """
        kwargs_copy = dict(kwargs)
        change_dict_key(kwargs_copy, from_key="status_callback_url",
                        to_key="status_callback")

        if "application_sid" in kwargs_copy:
            for sid_type in ["voice_application_sid", "sms_application_sid"]:
                if sid_type not in kwargs_copy:
                    kwargs_copy[sid_type] = kwargs_copy["application_sid"]
            del kwargs_copy["application_sid"]
        return self.update_instance(sid, kwargs_copy)
<commit_msg>Add beta attribute/filter to phone numbers<commit_after>import re

from twilio.exceptions import TwilioException
from .util import change_dict_key, transform_params
from .util import UNSET_TIMEOUT
from . import InstanceResource, ListResource

TYPES = {"local": "Local", "tollfree": "TollFree", "mobile": "Mobile"}

class AvailablePhoneNumber(InstanceResource):
    """ An available phone number resource

   .. attribute:: friendly_name

      A nicely-formatted version of the phone number.

   .. attribute:: phone_number

      The phone number, in E.164 (i.e. "+1") format.

   .. attribute:: lata

      The LATA of this phone number.

   .. attribute:: rate_center

      The rate center of this phone number.

   .. attribute:: latitude

      The latitude coordinate of this phone number.

   .. attribute:: longitude

      The longitude coordinate of this phone number.

   .. attribute:: region

      The two-letter state or province abbreviation of this phone number.

   .. attribute:: postal_code

      The postal (zip) code of this phone number.

   .. attribute:: iso_country

        The country for this number

   .. attribute:: address_requirements

        Whether the phone number requires you or your customer to have an
        Address registered with Twilio. Possible values are 'none', 'any',
        'local', or 'foreign'.

   .. attribute:: beta

        (boolean) Phone numbers new to the Twilio platform are marked as beta.

    """

    def __init__(self, parent):
        # Available Phone Numbers have no sid.
        super(AvailablePhoneNumber, self).__init__(parent, "")
        self.name = ""

    def purchase(self, **kwargs):
        return self.parent.purchase(phone_number=self.phone_number,
                                    **kwargs)

class AvailablePhoneNumbers(ListResource):

    name = "AvailablePhoneNumbers"
    key = "available_phone_numbers"
    instance = AvailablePhoneNumber

    def __init__(self, base_uri, auth, timeout, phone_numbers):
        super(AvailablePhoneNumbers, self).__init__(base_uri, auth, timeout)
        self.phone_numbers = phone_numbers

    def get(self, sid):
        raise TwilioException("Individual AvailablePhoneNumbers have no sid")

    def list(self, type="local", country="US", region=None, postal_code=None,
             lata=None, rate_center=None, **kwargs):
        """
        Search for phone numbers
        """
        kwargs["in_region"] = kwargs.get("in_region", region)
        kwargs["in_postal_code"] = kwargs.get("in_postal_code", postal_code)
        kwargs["in_lata"] = kwargs.get("in_lata", lata)
        kwargs["in_rate_center"] = kwargs.get("in_rate_center", rate_center)
        params = transform_params(kwargs)

        uri = "%s/%s/%s" % (self.uri, country, TYPES[type])
        resp, page = self.request("GET", uri, params=params)

        return [self.load_instance(i) for i in page[self.key]]

    def load_instance(self, data):
        instance = self.instance(self.phone_numbers)
        instance.load(data)
        instance.load_subresources()
        return instance

class PhoneNumber(InstanceResource):
    """ An IncomingPhoneNumber object

   .. attribute:: sid

      A 34 character string that uniquely identifies this resource.

   .. attribute:: date_created

      The date that this resource was created, given as GMT RFC 2822 format.

   .. attribute:: date_updated

      The date that this resource was last updated, in GMT RFC 2822 format.

   .. attribute:: friendly_name

      A human readable descriptive text for this resource, up to 64 characters
      long. By default, the FriendlyName is a nicely formatted version of
      the phone number.

   .. attribute:: account_sid

      The unique id of the Account responsible for this phone number.

   .. attribute:: phone_number

      The incoming phone number. e.g., +16175551212 (E.164 format)

   .. attribute:: api_version

      Calls to this phone number will start a new TwiML session with this
      API version.

   .. attribute:: voice_caller_id_lookup

      Look up the caller's caller-ID name from the CNAM database (additional
      charges apply). Either true or false.

   .. attribute:: voice_url

      The URL Twilio will request when this phone number receives a call.

   .. attribute:: voice_method

      The HTTP method Twilio will use when requesting the above Url.
      Either GET or POST.

   .. attribute:: voice_fallback_url

      The URL that Twilio will request if an error occurs retrieving or
      executing the TwiML requested by Url.

   .. attribute:: voice_fallback_method

      The HTTP method Twilio will use when requesting the VoiceFallbackUrl.
      Either GET or POST.

   .. attribute:: status_callback

      The URL that Twilio will request to pass status parameters (such as
      call ended) to your application.

   .. attribute:: status_callback_method

      The HTTP method Twilio will use to make requests to the
      StatusCallback URL. Either GET or POST.

   .. attribute:: sms_url

      The URL Twilio will request when receiving an incoming SMS message
      to this number.

   .. attribute:: sms_method

      The HTTP method Twilio will use when making requests to the SmsUrl.
      Either GET or POST.

   .. attribute:: sms_fallback_url

      The URL that Twilio will request if an error occurs retrieving or
      executing the TwiML from SmsUrl.

   .. attribute:: sms_fallback_method

      The HTTP method Twilio will use when requesting the above URL.
      Either GET or POST.

   .. attribute:: uri

      The URI for this resource, relative to https://api.twilio.com.

   .. attribute:: beta

      (boolean) Phone numbers new to the Twilio platform are marked as beta.
    """

    def load(self, entries):
        """ Set the proper Account owner of this phone number """

        # Only check if entries has a uri
        if "account_sid" in entries:
            # Parse the parent's uri to get the scheme and base
            uri = re.sub(r'AC(.*)', entries["account_sid"],
                         self.parent.base_uri)

            self.parent = PhoneNumbers(
                uri,
                self.parent.auth,
                self.parent.timeout
            )
            self.base_uri = self.parent.uri

        super(PhoneNumber, self).load(entries)

    def transfer(self, account_sid):
        """
        Transfer the phone number with sid from the current account to another
        identified by account_sid
        """
        a = self.parent.transfer(self.name, account_sid)
        self.load(a.__dict__)

    def update(self, **kwargs):
        """
        Update this phone number instance.
        """
        kwargs_copy = dict(kwargs)
        change_dict_key(kwargs_copy, from_key="status_callback_url",
                        to_key="status_callback")

        a = self.parent.update(self.name, **kwargs_copy)
        self.load(a.__dict__)

    def delete(self):
        """
        Release this phone number from your account. Twilio will no longer
        answer calls to this number, and you will stop being billed the monthly
        phone number fees. The phone number will eventually be recycled and
        potentially given to another customer, so use with care. If you make a
        mistake, contact us... we may be able to give you the number back.
        """
        return self.parent.delete(self.name)

class PhoneNumbers(ListResource):

    name = "IncomingPhoneNumbers"
    key = "incoming_phone_numbers"
    instance = PhoneNumber

    def __init__(self, base_uri, auth, timeout=UNSET_TIMEOUT):
        super(PhoneNumbers, self).__init__(base_uri, auth, timeout)
        self.available_phone_numbers = \
            AvailablePhoneNumbers(base_uri, auth, timeout, self)

    def delete(self, sid):
        """
        Release this phone number from your account. Twilio will no longer
        answer calls to this number, and you will stop being billed the
        monthly phone number fees. The phone number will eventually be
        recycled and potentially given to another customer, so use with care.
        If you make a mistake, contact us... we may be able to give you the
        number back.
        """
        return self.delete_instance(sid)

    def list(self, type=None, **kwargs):
        """
        :param phone_number: Show phone numbers that match this pattern.
        :param friendly_name: Show phone numbers with this friendly name
        :param type: Filter numbers by type. Available types are
            'local', 'mobile', or 'tollfree'

        You can specify partial numbers and use '*' as a wildcard.
        """

        uri = self.uri
        if type:
            uri = "%s/%s" % (self.uri, TYPES[type])

        params = transform_params(kwargs)
        resp, page = self.request("GET", uri, params=params)

        return [self.load_instance(i) for i in page[self.key]]

    def purchase(self, status_callback_url=None, **kwargs):
        """
        Attempt to purchase the specified number. The only required parameters
        are **either** phone_number or area_code

        :returns: Returns a :class:`PhoneNumber` instance on success,
                  :data:`False` on failure
        :raises: A :exc:`TypeError` if neither phone_number or area_code
        is specified.
        """
        kwargs["StatusCallback"] = kwargs.get("status_callback",
                                              status_callback_url)

        if 'phone_number' not in kwargs and 'area_code' not in kwargs:
            raise TypeError("phone_number or area_code is required")

        number_type = kwargs.pop('type', False)
        uri = self.uri
        if number_type:
            uri = "%s/%s" % (self.uri, TYPES[number_type])

        params = transform_params(kwargs)
        resp, instance = self.request('POST', uri, data=params)

        return self.load_instance(instance)

    def search(self, **kwargs):
        """
        :param type: The type of phone number to search for.
        :param str country: Only show numbers for this country (iso2)
        :param str region: When searching the US, show numbers in this state
        :param str postal_code: Only show numbers in this area code
        :param str rate_center: US only.
        :param tuple near_lat_long: Find close numbers within Distance miles.
        :param integer distance: Search radius for a Near- query in miles.
        :param boolean beta: Whether to include numbers new to the Twilio
            platform.
        """
        return self.available_phone_numbers.list(**kwargs)

    def transfer(self, sid, account_sid):
        """
        Transfer the phone number with sid from the current account to another
        identified by account_sid
        """
        return self.update(sid, account_sid=account_sid)

    def update(self, sid, **kwargs):
        """
        Update this phone number instance
        """
        kwargs_copy = dict(kwargs)
        change_dict_key(kwargs_copy, from_key="status_callback_url",
                        to_key="status_callback")

        if "application_sid" in kwargs_copy:
            for sid_type in ["voice_application_sid", "sms_application_sid"]:
                if sid_type not in kwargs_copy:
                    kwargs_copy[sid_type] = kwargs_copy["application_sid"]
            del kwargs_copy["application_sid"]
        return self.update_instance(sid, kwargs_copy)
<|endoftext|>


<commit_before>from copy import copy
import hashlib
import re

from .. import cleaver

DEFAULT_DATA_TEMPLATE = {
    'tx_people.Person': {},
    'tx_people.Organization': {},
    'tx_people.Post': {},
    'tx_people.Membership': {},
    'tx_people.Race': {},
    'tx_people.Links': {},
    'compensations': [{
        'tx_salaries.CompensationType': {},
        'tx_salaries.Employee': {},
    }]
}

class BaseTransformedRecord(object):
    def __init__(self, data=None, **kwargs):
        self.data = data

    def get_mapped_value_key(self, key):
        return self.MAP[key[:-4]]

    def get_mapped_value(self, key):
        return self.data[self.MAP[key]]

    def is_mapped_value_key(self, key):
        return key[-4:] == '_key' and key[:-4] in self.MAP

    def is_mapped_value(self, key):
        return key in self.MAP and self.MAP[key] in self.data

    def __getattr__(self, key):
        if self.is_mapped_value_key(key):
            return self.get_mapped_value_key(key)
        elif self.is_mapped_value(key):
            return self.get_mapped_value(key)
        # Error if one of required as_dict attributes is not available
        raise AttributeError("{key} is unknown. Are all of its attributes "
                             "available?".format(key=key))

    # TODO: Test
    def get_raw_name(self):
        name_fields = [getattr(self, a) for a in self.NAME_FIELDS]
        return u' '.join(name_fields)

    # TODO: Test
    # Helper function for GenericPersonMixin
    def get_name(self):
        return self.get_cleavered_name().parse()

    # TODO: Test
    def get_cleavered_name(self):
        return self.get_name_cleaver()(self.get_raw_name())

    # TODO: Test
    def get_name_cleaver(self):
        return cleaver.EmployeeNameCleaver

    def as_dict(self):
        # Stop early if this isn't valid
        if not self.is_valid:
            return

        # Build the structured record with the required attributes
        d = copy(DEFAULT_DATA_TEMPLATE)
        d['original'] = self.data

        d['tx_people.Identifier'] = self.identifier
        d['tx_people.Person'] = self.person
        d['tx_people.Organization'] = self.organization
        d['tx_people.Post'] = self.post
        d['tx_people.Membership'] = self.membership
        d['tx_people.Race'] = self.race
        d['tx_people.Links'] = self.links
        d['compensations'] = self.compensations
        d['date_provided'] = self.DATE_PROVIDED
        return d

def create_hash_for_record(record, exclude=None):
    """
    Returns a hash for a record to be used as its identifier.

    This takes a dictionary called ``record`` and turns it into a SHA-1
    hash while excluding any fields that might vary (such as pay rate).
    Each data source is responsible for determining what fields are
    unique and immutable.

    This hash is used for tracking an employee from one import to the
    next.
    """

    data_for_hash = copy(record)
    if exclude:
        for key in exclude:
            del data_for_hash[key]

    hash_string = re.sub(u'[\s.,-]', u'', u"::".join(data_for_hash.values()))
    return hashlib.sha1(hash_string.encode('utf-8')).hexdigest()

def generic_transform(labels, source, record_class):
    """
    General purpose transform function that is provided the record_class

    To use this, provide a ``record_class`` for a given
    ``TransformedRecord``.  Note that this can not be used directly
    as a transform function as it takes three parameters, not two.  It
    is meant to be used to build a transform function and is normally
    used directly via ``transform_factory``.
    """
    data = []
    for raw_record in source:
        record = record_class(dict(zip(labels, raw_record)))
        if record.is_valid:
            data.append(record.as_dict())
    return data

def generic_merge_cell_transform(labels, source, record_class):
    """
    General purpose transform function for data sources with merge-cells

    Spreadsheets with merge cells, such as those provided by the Texas
    Tech System, require that data from the previous row be merged into
    the new row.  The CSV reader that we currently use can not handle
    these rows, so we must do it ourselves.
    """
    data = []
    last_row = None
    for raw_row in source:
        row = dict(zip(labels, raw_row))
        if not raw_row[0].strip() and last_row:
            for key, value in last_row.items():
                if not row[key]:
                    row[key] = last_row[key]

        record = record_class(row)
        if record.is_valid:
            data.append(record.as_dict())
        last_row = row
    return data

def transform_factory(record_class, transform_func=None):
    """
    Simple factory for building a generic transformmer

    The second argument is used as the actual transform function, if
    provided, otherwise this dispatches to ``generic_transform``.  The
    provided ``transform_func`` is supposed to take three arguments,
    the ``labels`` and ``source`` that a transform function is supposed
    to take, along with a ``record_class`` argument that specifies which
    class is supposed to be used.
    """
    if transform_func is None:
        transform_func = generic_transform

    def transform(labels, source):
        return transform_func(labels, source, record_class=record_class)
    return transform
<commit_msg>We do a check against a TransformedRecord's self defined is_valid property here, and if is_valid is False, we bail out and return None. None gets appended to the list of records to return which subsequently crashes import_file in import_salary_data when it is encountered.<commit_after>from copy import copy
import hashlib
import re

from .. import cleaver

DEFAULT_DATA_TEMPLATE = {
    'tx_people.Person': {},
    'tx_people.Organization': {},
    'tx_people.Post': {},
    'tx_people.Membership': {},
    'tx_people.Race': {},
    'tx_people.Links': {},
    'compensations': [{
        'tx_salaries.CompensationType': {},
        'tx_salaries.Employee': {},
    }]
}

class BaseTransformedRecord(object):
    def __init__(self, data=None, **kwargs):
        self.data = data

    def get_mapped_value_key(self, key):
        return self.MAP[key[:-4]]

    def get_mapped_value(self, key):
        return self.data[self.MAP[key]]

    def is_mapped_value_key(self, key):
        return key[-4:] == '_key' and key[:-4] in self.MAP

    def is_mapped_value(self, key):
        return key in self.MAP and self.MAP[key] in self.data

    def __getattr__(self, key):
        if self.is_mapped_value_key(key):
            return self.get_mapped_value_key(key)
        elif self.is_mapped_value(key):
            return self.get_mapped_value(key)
        # Error if one of required as_dict attributes is not available
        raise AttributeError("{key} is unknown. Are all of its attributes "
                             "available?".format(key=key))

    # TODO: Test
    def get_raw_name(self):
        name_fields = [getattr(self, a) for a in self.NAME_FIELDS]
        return u' '.join(name_fields)

    # TODO: Test
    # Helper function for GenericPersonMixin
    def get_name(self):
        return self.get_cleavered_name().parse()

    # TODO: Test
    def get_cleavered_name(self):
        return self.get_name_cleaver()(self.get_raw_name())

    # TODO: Test
    def get_name_cleaver(self):
        return cleaver.EmployeeNameCleaver

    def as_dict(self):

        # Build the structured record with the required attributes
        d = copy(DEFAULT_DATA_TEMPLATE)
        d['original'] = self.data

        d['tx_people.Identifier'] = self.identifier
        d['tx_people.Person'] = self.person
        d['tx_people.Organization'] = self.organization
        d['tx_people.Post'] = self.post
        d['tx_people.Membership'] = self.membership
        d['tx_people.Race'] = self.race
        d['tx_people.Links'] = self.links
        d['compensations'] = self.compensations
        d['date_provided'] = self.DATE_PROVIDED
        return d

def create_hash_for_record(record, exclude=None):
    """
    Returns a hash for a record to be used as its identifier.

    This takes a dictionary called ``record`` and turns it into a SHA-1
    hash while excluding any fields that might vary (such as pay rate).
    Each data source is responsible for determining what fields are
    unique and immutable.

    This hash is used for tracking an employee from one import to the
    next.
    """

    data_for_hash = copy(record)
    if exclude:
        for key in exclude:
            del data_for_hash[key]

    hash_string = re.sub(u'[\s.,-]', u'', u"::".join(data_for_hash.values()))
    return hashlib.sha1(hash_string.encode('utf-8')).hexdigest()

def generic_transform(labels, source, record_class):
    """
    General purpose transform function that is provided the record_class

    To use this, provide a ``record_class`` for a given
    ``TransformedRecord``.  Note that this can not be used directly
    as a transform function as it takes three parameters, not two.  It
    is meant to be used to build a transform function and is normally
    used directly via ``transform_factory``.
    """
    data = []
    for raw_record in source:
        record = record_class(dict(zip(labels, raw_record)))
        if record.is_valid:
            data.append(record.as_dict())
    return data

def generic_merge_cell_transform(labels, source, record_class):
    """
    General purpose transform function for data sources with merge-cells

    Spreadsheets with merge cells, such as those provided by the Texas
    Tech System, require that data from the previous row be merged into
    the new row.  The CSV reader that we currently use can not handle
    these rows, so we must do it ourselves.
    """
    data = []
    last_row = None
    for raw_row in source:
        row = dict(zip(labels, raw_row))
        if not raw_row[0].strip() and last_row:
            for key, value in last_row.items():
                if not row[key]:
                    row[key] = last_row[key]

        record = record_class(row)
        if record.is_valid:
            data.append(record.as_dict())
        last_row = row
    return data

def transform_factory(record_class, transform_func=None):
    """
    Simple factory for building a generic transformmer

    The second argument is used as the actual transform function, if
    provided, otherwise this dispatches to ``generic_transform``.  The
    provided ``transform_func`` is supposed to take three arguments,
    the ``labels`` and ``source`` that a transform function is supposed
    to take, along with a ``record_class`` argument that specifies which
    class is supposed to be used.
    """
    if transform_func is None:
        transform_func = generic_transform

    def transform(labels, source):
        return transform_func(labels, source, record_class=record_class)
    return transform
<|endoftext|>


<commit_before>"""Template for pulling training examples from API and training model on GPU"""
print("loading libraries...")
import json
import requests
import numpy as np
import tensorflow as tf
import tflearn
from tflearn.data_utils import to_categorical
import gc

# Fetching data from API #######################################################

API_URL = "http://127.0.0.1:5000" # Currently set to localhost
JOB_ID = 139
JOB_URL = API_URL + '/' + str(JOB_ID)

# Returns list of labeled_vectors from API, each training_example is (deflated_vector, label)
# Returned object is in format: [({5:1, 6:2, 5000:1}, 1), ...]
# TODO: Set up pagination using offset and limit here. Will pass as params in the request.
def get_labeled_vectors(offset, limit):
    payload = {'offset': offset, 'limit': limit, 'full_info': 0}
    r = requests.get(url=JOB_URL, params=payload)
    examples_json = r.json()['labeled_vector']
    return [(example['vector'], example['label']) for example in examples_json]

def get_model_info():
    payload = {'offset': 0, 'limit': 0, 'full_info': 1}
    r = requests.get(url=JOB_URL, params=payload)
    info_json = r.json()
    return info_json['input_vector_length'], info_json['num_classes'], info_json['num_examples']

# Given a deflated_vector (dictionary), return its vector (sparse np array)
def inflate(deflated_vec, vec_len):
    result = np.zeros(vec_len)
    for idx, count in deflated_vec.items():
        result[int(idx)] = count
    return result

# Building, training TF Model ##################################################

# Builds the model, given proper parameters
def build_model(input_vec_length, num_classes):
    tf.reset_default_graph() # This resets all parameters and variables, leave this here
    net = tflearn.input_data([None, input_vec_length])                # Input
    net = tflearn.fully_connected(net, 10, activation='ReLU')     # Hidden
    net = tflearn.fully_connected(net, num_classes, activation='softmax')   # Output
    net = tflearn.regression(net, optimizer='sgd', learning_rate=0.1, loss='categorical_crossentropy')
    model = tflearn.DNN(net)
    return model

# Trains model in successive slabs by pulling slabs of data from the API
def train_model(model, num_classes, slab_size, save_file):
    print("Training TF model...")
    _, _, num_examples = get_model_info()
    start_pos = 0
    while start_pos < num_examples:
        end_pos = min(start_pos + slab_size, num_examples)
        examples = get_labeled_vectors(start_pos, slab_size)
        print('Fitting model with start: {}, end: {}'.format(start_pos, end_pos))
        x_train = np.asarray([inflate(vec['indices'], vec['reductions']) for vec, _ in examples])
        y_train = to_categorical(np.asarray([lab for _, lab in examples]), num_classes)
        model.fit(x_train, y_train, validation_set=0.1, show_metric=True, batch_size=128, n_epoch=5)

        del examples
        gc.collect() # force Garbage Collector to release unreferenced memory

        start_pos = end_pos
        if (end_pos/slab_size) % 20 == 0: # save a copy of the model every 20 slabs
            print('Saving model in current state... still training.')
            model.save(save_file)

    print("Saving model...(final save)")
    model.save(save_file)
    print('-----')
    print('Success! Your model was built and saved.')
    return model

SAVE_FILE = 'test-model.tfl'
INPUT_VEC_LEN, NUM_CLASSES, _ = get_model_info()
print("Building Tensorflow model...")
model = build_model(input_vec_length=INPUT_VEC_LEN, num_classes=NUM_CLASSES)
model = train_model(model, NUM_CLASSES, slab_size=30000, save_file=SAVE_FILE)
<commit_msg>wizardry<commit_after>"""Template for pulling training examples from API and training model on GPU"""
print("loading libraries...")
import json
import requests
import numpy as np
import tensorflow as tf
import tflearn
from tflearn.data_utils import to_categorical
import gc

try:
    SECRET = os.environ['SECRET']
    JOB_ID = os.environ['JOB_ID']
    API_URL = os.environ['API_URL']
    JOB_URL = '{}/jobs/{}/vectors'.format(API_URL, JOB_ID)
    MODEL_NAME = os.environ.get('GENERATED_MODEL_NAME','{}.tfl'.format(JOB_ID))
except KeyError as e:
    print('critical environment variables were not set! exiting.')
    raise e

def get_labeled_vectors(offset, limit):
    '''Returns list of labeled_vectors from API, each training_example is
    (deflated_vector, label) Returned object is in format: [({5:1, 6:2, 5000:1},
        1), ...]'''

    payload = {'offset': offset, 'limit': limit, 'full_info': 0}
    r = requests.get(url=JOB_URL, params=payload)
    return r.json()['labeled_vectors']

def get_model_info():
    payload = {'offset': 0, 'limit': 0, 'full_info': 1}
    r = requests.get(url=JOB_URL, params=payload)
    info_json = r.json()
    return (info_json['vector_length'], info_json['num_classes'],
            info_json['num_labeled_vectors'])

def inflate(deflated_vec, vec_len):
    '''Given a deflated_vector (dictionary), return its vector (sparse np
    array)'''
    result = np.zeros(vec_len)
    for idx, count in deflated_vec.items():
        result[int(idx)] = count
    return result

def build_model(input_vec_length, num_classes):
    tf.reset_default_graph() # This resets all parameters and variables, leave this here
    net = tflearn.input_data([None, input_vec_length])                # Input
    net = tflearn.fully_connected(net, 10, activation='ReLU')     # Hidden
    net = tflearn.fully_connected(net, num_classes, activation='softmax')   # Output
    net = tflearn.regression(net, optimizer='sgd', learning_rate=0.1, loss='categorical_crossentropy')
    model = tflearn.DNN(net)
    return model

def train_model(model, num_classes, slab_size, save_file):
    print("Training TF model...")
    _, _, num_examples = get_model_info()
    start_pos = 0
    while start_pos < num_examples:
        end_pos = min(start_pos + slab_size, num_examples)
        examples = get_labeled_vectors(start_pos, slab_size)
        print('Fitting model with start: {}, end: {}'.format(start_pos, end_pos))
        x_train = np.asarray([inflate(e['vector']['indices'], e['vector']['reductions']) for e in examples])
        y_train = to_categorical(np.asarray([e['label'] for e in examples]), num_classes)
        model.fit(x_train, y_train, validation_set=0.1, show_metric=True, batch_size=128, n_epoch=5)

        del examples
        gc.collect() # force Garbage Collector to release unreferenced memory

        start_pos = end_pos
        if (end_pos/slab_size) % 20 == 0: # save a copy of the model every 20 slabs
            print('Saving model in current state... still training.')
            model.save(save_file)

    print("Saving model...(final save)")
    model.save(save_file)
    print('-----')
    print('Success! Your model was built and saved.')
    return model

if __name__ == '__main__':
    INPUT_VEC_LEN, NUM_CLASSES, _ = get_model_info()
    print("Building Tensorflow model...")
    model = build_model(input_vec_length=INPUT_VEC_LEN, num_classes=NUM_CLASSES)
    model = train_model(model, NUM_CLASSES, slab_size=30000,
            save_file=MODEL_NAME)
<|endoftext|>


<commit_before>class Piece(object):
    """
    Generalized piece class that contains attributes about whether it is an empty piece or if it is black
    or white. All pieces except empty have their own subclass. Contains a list of locations the piece can
    move to.
    """
    def __init__(self):
        self.empty = True
        self.color = "NA"
        self.double_step = False

    def __repr__(self):
        if self.empty:
            return u"\u25A1"
    def move_set(self, piece, board):
        print "Error: This is an empty space"

    def piece_at(self, at, color = None, en_passant = None):
        """
        If only at argument is filled, the function checks to see if there is a chess piece at the given
        coordinate.

        If the color argument is given as well, the function checks to see if the given piece matches
        the queried color.

        If the en passant argument is filled with the piece rank, the function checks if the target piece
        moved two forward initially and whether the attacking piece is on the right rank.
        """
        if color == None:
            if not at.empty:
                return True
            else:
                return False

        elif en_passant == None:   # If color is given but en passant is not
            if at.color == color:
                return True
            else:
                return False

        else:  # En passant
            if at.double_step and at.color == color:
                if at.color == "White" and en_passant == 3:
                    return True
                elif at.color == "Black" and en_passant == 4:
                    return True
                else:
                    return False
            else:
                return False

    def linear_set(self, piece, board, array, direction = None):
        """
        Checks pieces in array until it hits an ally piece or the end of the board.
        Returns the set of valid moves. Direction determines the value of the axis that is to remain
        constant, eg. to check horizontal moves of a rook, the rank remains constant.
        """
        lin_set = []
        piece_ob = board[piece[0]][piece[1]]

        for i in array:
            if direction == 'H':
                coor = (piece[0], i)
                target = board[piece[0]][i]
            elif direction == 'V':
                coor = (i, piece[1])
                target = board[i][piece[1]]
            elif direction == 'D':
                coor = (i[0], i[1])
                target = board[i[0]][i[1]]
            if self.piece_at(target):
                if target.color != piece_ob.color and not target.empty:
                    lin_set.append(coor)
                break
            else:
                lin_set.append(coor)

        return lin_set

class Pawn(Piece):
    """
    Contains attributes of a pawn. Unicode for all black and white pieces switched around since they
    are going to be displayed on a black background
    """
    def __init__(self, empty, color):
        self.empty = empty
        self.color = color
        self.moved = False  # To determine whether the pawn can move two spaces forward
        self.double_step = False  # Used for en passant

    def __repr__(self):
        if self.color == "White":
            return u"\u265f"

        else:
            return u"\u2659"

    def move_set(self, piece, board):
        """Consolidates all the movement set information and returns final list of valid moves"""
        total = []
        total.extend(self.standard_moves(piece, board))
        total.extend(self.capture_moves(piece, board))

        return total

    def standard_moves(self, piece, board):
        """
        Takes piece and calculates all the legal spaces the piece can move to, NOT including spaces
        where a piece can be captured. Has branches depending on whether the moving piece is white or
        black.
        """
        self.total = []
        if self.color == "White":
            if not self.piece_at(board[piece[0]][piece[1] + 1]):  # If there is not a piece there
                self.total.append((piece[0], piece[1] + 1))  # One square forward

            if not self.moved and not self.piece_at(board[piece[0]][piece[1] + 2]):
                self.total.append((piece[0], piece[1] + 2))  # Two squares forward

        else:   # If piece is black, the math is backwards
            if not self.piece_at(board[piece[0]][piece[1] - 1]):
                self.total.append((piece[0], piece[1] - 1))

            if not self.moved and not self.piece_at(board[piece[0]][piece[1] - 2]):
                self.total.append((piece[0], piece[1] - 2))

        return self.total

    def capture_moves(self, piece, board):
        """Creates a list of moves where a piece can be captured by the pawn, includes en passant."""
        self.cset = []
        if self.color == "White":
            if self.piece_at(board[piece[0] - 1][piece[1] + 1], "Black"):  # Regular capture
                self.cset.append((piece[0] - 1 , piece[1] + 1))
            if self.piece_at(board[piece[0] + 1][piece[1] + 1], "Black"):
                self.cset.append((piece[0] + 1 , piece[1] + 1))

            if self.piece_at(board[piece[0] - 1][piece[1]], "Black", piece[1]):  # En passant
                self.cset.append((piece[0] - 1, piece[1]))
            if self.piece_at(board[piece[0] + 1][piece[1]], "Black", piece[1]):
                self.cset.append((piece[0] + 1, piece[1]))

        else:
            if self.piece_at(board[piece[0] - 1][piece[1] - 1], "White"):  # Regular capture
                self.cset.append((piece[0] - 1 , piece[1] - 1))
            if self.piece_at(board[piece[0] + 1][piece[1] - 1], "White"):
                self.cset.append((piece[0] + 1 , piece[1] - 1))

            if self.piece_at(board[piece[0] - 1][piece[1]], "White", piece[1]):  # En passant
                self.cset.append((piece[0] - 1, piece[1]))
            if self.piece_at(board[piece[0] + 1][piece[1]], "White", piece[1]):
                self.cset.append((piece[0] + 1, piece[1]))

        return self.cset

class Rook(Piece):
    """Contains attributes of a rook"""
    def __init__(self, empty, color):
        self.empty = empty
        self.color = color

    def __repr__(self):
        if self.color == "White":
            return u"\u265C"

        else:
            return u"\u2656"

    def move_set(self, piece, board):
        """Consolidates all the movement set information and returns final list of valid moves"""
        total = self.axial_set(piece, board)
        return total

    def axial_set(self, piece, board):
        """Returns moves that are legal and are vertical and horizontal to the piece"""
        axial = []
        axial.extend(self.horizontal_set(piece, board))
        axial.extend(self.vertical_set(piece, board))
        return axial

    def horizontal_set(self, piece, board):
        """
        Finds set of moves that are to the horizontal. Note: due to the layout of the board in this
        program, horizontal means squares in a rank, ie. A1,A2,etc.
        """
        hor_set = []
        col = range(8)
        left = col[:piece[1]]
        left.reverse()              # Reversed so the loop evaluates the square next to the piece first
        right = col[piece[1] + 1:]

        hor_set.extend(self.linear_set(piece, board, left, 'H'))
        hor_set.extend(self.linear_set(piece, board, right, 'H'))

        return hor_set

    def vertical_set(self, piece, board):
        """
        Finds set of moves that are to the vertical of the piece. Note: due to the layout of the board in
        this program, vertical means squares in a file, ie. A1,B1,etc.
        """
        ver_set = []
        row = range(8)
        upper = row[:piece[0]]
        upper.reverse()
        lower = row[piece[0] + 1:]

        ver_set.extend(self.linear_set(piece, board, upper, 'V'))
        ver_set.extend(self.linear_set(piece, board, lower, 'V'))

        return ver_set

class Knight(Piece):
    """Contains attributes of a knight"""
    displacement = [(-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2, 1)]

    def __init__(self, empty, color):
        self.empty = empty
        self.color = color

    def __repr__(self):
        if self.color == "White":
            return u"\u265E"

        else:
            return u"\u2658"

    def move_set(self, piece, board):
        """Returns complete set of legal moves"""
        total = self.standard_set(piece, board)
        return total

    def standard_set(self, piece, board):
        """
        Takes a knight and calculates all the legal spaces the piece can move to, including spaces
        where a piece can be captured.
        """
        std_set = []
        for i in self.displacement:   # List of tuples that have the displacement values from the knight
            try:
                coor = (piece[0] + i[0], piece[1] + i[1])
                target = board[coor[0]][coor[1]]
                piece_ob = board[piece[0]][piece[1]]
                if not self.piece_at(target) or (target.color != piece_ob.color and not target.empty):
                    if coor[0] >= 0 and coor[1] >= 0:   # negative numbers cause weirdness
                        std_set.append(coor)

            except IndexError:
                pass

        return std_set

class Bishop(Piece):
    """Contains attributes of a bishop"""
    def __init__(self, empty, color):
        self.empty = empty
        self.color = color

    def __repr__(self):
        if self.color == "White":
            return u"\u265D"

        else:
            return u"\u2657"

    def move_set(self, piece, board):
        """Consolidates all the movement set information and returns final list of valid moves"""
        final = self.diagonal_set(piece, board)
        return final

    def diagonal_set(self, piece, board):
        """Calculates moves from the piece in each diagonal direction until they encounter a piece"""
        diag_set = []

        upper_left = [(piece[0] - x - 1, piece[1] - x - 1) for x in range(min(piece[0], piece[1]))]
        upper_right = [(piece[0] - x - 1, piece[1] + x + 1) for x in range(min(piece[0], 7 - piece[1]))]
        lower_left = [(piece[0] + x + 1, piece[1] - x - 1) for x in range(min(7 - piece[0], piece[1]))]
        lower_right = [(piece[0] + x + 1, piece[1] + x + 1) for x in range(min(7-piece[0], 7-piece[1]))]

        diag_set.extend(self.linear_set(piece, board, upper_left, 'D'))
        diag_set.extend(self.linear_set(piece, board, upper_right, 'D'))
        diag_set.extend(self.linear_set(piece, board, lower_left, 'D'))
        diag_set.extend(self.linear_set(piece, board, lower_right, 'D'))

        return diag_set

class Queen(Rook, Bishop):
    """
    Contains attributes of a queen. Queen inherits from Rook and Bishop because effectively, a queen is
    a combination of the movement of rooks and bishops.
    """
    def __init__(self, empty, color):
        self.empty = empty
        self.color = color

    def __repr__(self):
        if self.color == "White":
            return u"\u265B"

        else:
            return u"\u2655"

    def move_set(self, piece, board):
        """Combines axial_set() from rook and diagonal_set() from bishop."""
        total = []
        total.extend(self.axial_set(piece, board))
        total.extend(self.diagonal_set(piece, board))
        return total

class King(Piece):
    """Contains attributes of a king"""
    displacement = [(0,1), (0, -1), (1, 0), (-1, 0), (1, 1), (1, -1), (-1, 1), (-1, -1)]

    def __init__(self, empty, color):
        self.empty = empty
        self.color = color

    def __repr__(self):
        if self.color == "White":
            return u"\u265A"

        else:
            return u"\u2654"

    def move_set(self, piece, board):
        """Creates the moveset for the king"""
        total = self.standard_set(piece, board)
        return total

    def standard_set(self, piece, board):
        """Calculates the valid moves for a king"""
        std_set = []

        for i in self.displacement:   # List of tuples that have the displacement values from the knight
            try:
                coor = (piece[0] + i[0], piece[1] + i[1])
                target = board[coor[0]][coor[1]]
                piece_ob = board[piece[0]][piece[1]]
                if not self.piece_at(target) or (target.color != piece_ob.color and not target.empty):
                    if coor[0] >= 0 and coor[1] >= 0:   # negative numbers cause weirdness
                        std_set.append(coor)

            except IndexError:
                pass

        return std_set
<commit_msg>Moved standard_set() from King and Knight classes to Piece class since both the class called an identical standard_set() method. Added self.displacement argument to the King and Knight classes' move_set() method<commit_after>class Piece(object):
    """
    Generalized piece class that contains attributes about whether it is an empty piece or if it is black
    or white. All pieces except empty have their own subclass. Contains a list of locations the piece can
    move to.
    """
    def __init__(self):
        self.empty = True
        self.color = "NA"
        self.double_step = False

    def __repr__(self):
        if self.empty:
            return u"\u25A1"
    def move_set(self, piece, board):
        print "Error: This is an empty space"

    def piece_at(self, at, color = None, en_passant = None):
        """
        If only at argument is filled, the function checks to see if there is a chess piece at the given
        coordinate.

        If the color argument is given as well, the function checks to see if the given piece matches
        the queried color.

        If the en passant argument is filled with the piece rank, the function checks if the target piece
        moved two forward initially and whether the attacking piece is on the right rank.
        """
        if color == None:
            if not at.empty:
                return True
            else:
                return False

        elif en_passant == None:   # If color is given but en passant is not
            if at.color == color:
                return True
            else:
                return False

        else:  # En passant
            if at.double_step and at.color == color:
                if at.color == "White" and en_passant == 3:
                    return True
                elif at.color == "Black" and en_passant == 4:
                    return True
                else:
                    return False
            else:
                return False

    def linear_set(self, piece, board, array, direction = None):
        """
        Checks pieces in array until it hits an ally piece or the end of the board.
        Returns the set of valid moves. Direction determines the value of the axis that is to remain
        constant, eg. to check horizontal moves of a rook, the rank remains constant.
        """
        lin_set = []
        piece_ob = board[piece[0]][piece[1]]

        for i in array:
            if direction == 'H':
                coor = (piece[0], i)
                target = board[piece[0]][i]
            elif direction == 'V':
                coor = (i, piece[1])
                target = board[i][piece[1]]
            elif direction == 'D':
                coor = (i[0], i[1])
                target = board[i[0]][i[1]]
            if self.piece_at(target):
                if target.color != piece_ob.color and not target.empty:
                    lin_set.append(coor)
                break
            else:
                lin_set.append(coor)

        return lin_set

    def standard_set(self, piece, board, displacement):
        """Calculates valid moves given a list of displacement tuples"""
        std_set = []
        piece_ob = board[piece[0]][piece[1]]

        for i in displacement:
            try:
                coor = (piece[0] + i[0], piece[1] + i[1])
                target = board[coor[0]][coor[1]]
                if not self.piece_at(target) or (target.color != piece_ob.color and not target.empty):
                    if coor[0] >= 0 and coor[1] >= 0:   # negative numbers cause weirdness
                        std_set.append(coor)

            except IndexError:
                pass

        return std_set

class Pawn(Piece):
    """
    Contains attributes of a pawn. Unicode for all black and white pieces switched around since they
    are going to be displayed on a black background
    """
    def __init__(self, empty, color):
        self.empty = empty
        self.color = color
        self.moved = False  # To determine whether the pawn can move two spaces forward
        self.double_step = False  # Used for en passant

    def __repr__(self):
        if self.color == "White":
            return u"\u265f"

        else:
            return u"\u2659"

    def move_set(self, piece, board):
        """Consolidates all the movement set information and returns final list of valid moves"""
        total = []
        total.extend(self.standard_moves(piece, board))
        total.extend(self.capture_moves(piece, board))

        return total

    def standard_moves(self, piece, board):
        """
        Takes piece and calculates all the legal spaces the piece can move to, NOT including spaces
        where a piece can be captured. Has branches depending on whether the moving piece is white or
        black.
        """
        self.total = []
        if self.color == "White":
            if not self.piece_at(board[piece[0]][piece[1] + 1]):  # If there is not a piece there
                self.total.append((piece[0], piece[1] + 1))  # One square forward

            if not self.moved and not self.piece_at(board[piece[0]][piece[1] + 2]):
                self.total.append((piece[0], piece[1] + 2))  # Two squares forward

        else:   # If piece is black, the math is backwards
            if not self.piece_at(board[piece[0]][piece[1] - 1]):
                self.total.append((piece[0], piece[1] - 1))

            if not self.moved and not self.piece_at(board[piece[0]][piece[1] - 2]):
                self.total.append((piece[0], piece[1] - 2))

        return self.total

    def capture_moves(self, piece, board):
        """Creates a list of moves where a piece can be captured by the pawn, includes en passant."""
        self.cset = []
        if self.color == "White":
            if self.piece_at(board[piece[0] - 1][piece[1] + 1], "Black"):  # Regular capture
                self.cset.append((piece[0] - 1 , piece[1] + 1))
            if self.piece_at(board[piece[0] + 1][piece[1] + 1], "Black"):
                self.cset.append((piece[0] + 1 , piece[1] + 1))

            if self.piece_at(board[piece[0] - 1][piece[1]], "Black", piece[1]):  # En passant
                self.cset.append((piece[0] - 1, piece[1]))
            if self.piece_at(board[piece[0] + 1][piece[1]], "Black", piece[1]):
                self.cset.append((piece[0] + 1, piece[1]))

        else:
            if self.piece_at(board[piece[0] - 1][piece[1] - 1], "White"):  # Regular capture
                self.cset.append((piece[0] - 1 , piece[1] - 1))
            if self.piece_at(board[piece[0] + 1][piece[1] - 1], "White"):
                self.cset.append((piece[0] + 1 , piece[1] - 1))

            if self.piece_at(board[piece[0] - 1][piece[1]], "White", piece[1]):  # En passant
                self.cset.append((piece[0] - 1, piece[1]))
            if self.piece_at(board[piece[0] + 1][piece[1]], "White", piece[1]):
                self.cset.append((piece[0] + 1, piece[1]))

        return self.cset

class Rook(Piece):
    """Contains attributes of a rook"""
    def __init__(self, empty, color):
        self.empty = empty
        self.color = color

    def __repr__(self):
        if self.color == "White":
            return u"\u265C"

        else:
            return u"\u2656"

    def move_set(self, piece, board):
        """Consolidates all the movement set information and returns final list of valid moves"""
        total = self.axial_set(piece, board)
        return total

    def axial_set(self, piece, board):
        """Returns moves that are legal and are vertical and horizontal to the piece"""
        axial = []
        axial.extend(self.horizontal_set(piece, board))
        axial.extend(self.vertical_set(piece, board))
        return axial

    def horizontal_set(self, piece, board):
        """
        Finds set of moves that are to the horizontal. Note: due to the layout of the board in this
        program, horizontal means squares in a rank, ie. A1,A2,etc.
        """
        hor_set = []
        col = range(8)
        left = col[:piece[1]]
        left.reverse()              # Reversed so the loop evaluates the square next to the piece first
        right = col[piece[1] + 1:]

        hor_set.extend(self.linear_set(piece, board, left, 'H'))
        hor_set.extend(self.linear_set(piece, board, right, 'H'))

        return hor_set

    def vertical_set(self, piece, board):
        """
        Finds set of moves that are to the vertical of the piece. Note: due to the layout of the board in
        this program, vertical means squares in a file, ie. A1,B1,etc.
        """
        ver_set = []
        row = range(8)
        upper = row[:piece[0]]
        upper.reverse()
        lower = row[piece[0] + 1:]

        ver_set.extend(self.linear_set(piece, board, upper, 'V'))
        ver_set.extend(self.linear_set(piece, board, lower, 'V'))

        return ver_set

class Knight(Piece):
    """Contains attributes of a knight"""
    displacement = [(-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2, 1)]

    def __init__(self, empty, color):
        self.empty = empty
        self.color = color

    def __repr__(self):
        if self.color == "White":
            return u"\u265E"

        else:
            return u"\u2658"

    def move_set(self, piece, board):
        """Returns complete set of legal moves"""
        total = self.standard_set(piece, board, self.displacement)
        return total

class Bishop(Piece):
    """Contains attributes of a bishop"""
    def __init__(self, empty, color):
        self.empty = empty
        self.color = color

    def __repr__(self):
        if self.color == "White":
            return u"\u265D"

        else:
            return u"\u2657"

    def move_set(self, piece, board):
        """Consolidates all the movement set information and returns final list of valid moves"""
        final = self.diagonal_set(piece, board)
        return final

    def diagonal_set(self, piece, board):
        """Calculates moves from the piece in each diagonal direction until they encounter a piece"""
        diag_set = []

        upper_left = [(piece[0] - x - 1, piece[1] - x - 1) for x in range(min(piece[0], piece[1]))]
        upper_right = [(piece[0] - x - 1, piece[1] + x + 1) for x in range(min(piece[0], 7 - piece[1]))]
        lower_left = [(piece[0] + x + 1, piece[1] - x - 1) for x in range(min(7 - piece[0], piece[1]))]
        lower_right = [(piece[0] + x + 1, piece[1] + x + 1) for x in range(min(7-piece[0], 7-piece[1]))]

        diag_set.extend(self.linear_set(piece, board, upper_left, 'D'))
        diag_set.extend(self.linear_set(piece, board, upper_right, 'D'))
        diag_set.extend(self.linear_set(piece, board, lower_left, 'D'))
        diag_set.extend(self.linear_set(piece, board, lower_right, 'D'))

        return diag_set

class Queen(Rook, Bishop):
    """
    Contains attributes of a queen. Queen inherits from Rook and Bishop because effectively, a queen is
    a combination of the movement of rooks and bishops.
    """
    def __init__(self, empty, color):
        self.empty = empty
        self.color = color

    def __repr__(self):
        if self.color == "White":
            return u"\u265B"

        else:
            return u"\u2655"

    def move_set(self, piece, board):
        """Combines axial_set() from rook and diagonal_set() from bishop."""
        total = []
        total.extend(self.axial_set(piece, board))
        total.extend(self.diagonal_set(piece, board))
        return total

class King(Piece):
    """Contains attributes of a king"""
    displacement = [(0,1), (0, -1), (1, 0), (-1, 0), (1, 1), (1, -1), (-1, 1), (-1, -1)]

    def __init__(self, empty, color):
        self.empty = empty
        self.color = color

    def __repr__(self):
        if self.color == "White":
            return u"\u265A"

        else:
            return u"\u2654"

    def move_set(self, piece, board):
        """Creates the moveset for the king"""
        total = self.standard_set(piece, board, self.displacement)
        return total

<|endoftext|>


<commit_before>"""A Simple Wildfire-inspired MDP model"""

import random, math, numpy

def simulate(timesteps, policy=[0,0,0], SILENT=False):

    basic_state_value = 2

    event_max = 100
    event_min = 0

    #cost of suppression in a low-severity fire
    action_1_cost_sev_low = 1

    #cost of suppresion in a high-severity fire
    action_1_cost_sev_high = 4

    #cost of a severe fire on the next timestep
    burn_cost = 6

    severity_switchpoint_after_suppression = 80
    severity_switchpoint_after_low = 80
    severity_switchpoint_after_high = 80

    states = [None] * timesteps

    previous_burn_cost = 0
    previous_burn = 'none'

    for i in range(timesteps):

        #event value is the single "feature" of events in this MDP
        ev = random.uniform(event_min, event_max)

        #severity is meant to be a hidden, "black box" variable inside the MDP
        sev = 'low'
        if previous_burn == 'none':
            if ev > severity_switchpoint_after_suppression: sev = 'high'
        elif previous_burn == "low":
            if ev > severity_switchpoint_after_low: sev = 'high'
        elif previous_burn == 'high':
            if ev > severity_switchpoint_after_high: sev = 'high'

        #logistic function for the policy choice
        #policy_crossproduct = policy[0] + policy[1]*ev
        #modified logistic policy function
        #                     CONSTANT       COEFFICIENT       SHIFT
        policy_crossproduct = policy[0] + ( policy[1] * (ev + policy[2]) )
        if policy_crossproduct > 100: policy_crossproduct = 100
        if policy_crossproduct < -100: policy_crossproduct = -100

        policy_value = 1 / (1 + math.exp(-1*(policy_crossproduct)))

        choice_roll = random.uniform(0,1)
        choice = False
        choice_prob = 1 - policy_value
        if choice_roll < policy_value:
            choice = True
            choice_prob = policy_value

        #now check the choice vs severity combinations, and update things for the next state
        if sev == 'low':
            if choice:
                #low severity, with suppression
                previous_burn_cost = 0
                previous_burn = 'none'
            else:
                #low severity, without suppression
                previous_burn_cost = 0
                previous_burn = 'low'

        else: #sev == 'high'
            if choice:
                #high severity, with suppression
                previous_burn_cost = 0
                previous_burn = 'none'
            else:
                #high severity, without suppression
                previous_burn_cost = burn_cost
                previous_burn = 'high'

        this_state_value = basic_state_value - previous_burn_cost
        if choice:
            if sev == 'high':
                this_state_value -= action_1_cost_sev_high
            else: #sev == 'low'
                this_state_value -= action_1_cost_sev_low

        states[i] = [ev, choice, choice_prob, this_state_value]

    #finished simulations, report some values
    vals = []
    suppressions = 0
    joint_prob = 1
    prob_sum = 0
    for i in range(timesteps):
        if states[i][1]: suppressions += 1
        joint_prob *= states[i][2]
        prob_sum += states[i][2]
        vals.append(states[i][3])
    ave_prob = prob_sum / timesteps

    summary = {
                "Average State Value": round(numpy.mean(vals),1),
                "STD State Value": round(numpy.std(vals),1),
                "Suppressions": suppressions,
                "Suppression Rate": round((float(suppressions)/timesteps),2),
                "Joint Probability": joint_prob,
                "Average Probability": round(ave_prob, 3)
              }

    if not SILENT:
        print("")
        print("Simulation Complete")
        print("Average State Value: " + str(round(numpy.mean(vals),1)) + "   STD: " + str(round(numpy.std(vals),1)))
        print("Suppressions: " + str(suppressions))
        print("Suppression Rate: " + str(round((float(suppressions)/timesteps),2)))
        print("Joint Probability:" + str(joint_prob))
        print("Average Probability: " + str(round(ave_prob, 3)))
        print("")

    summary["States"] = states

    return summary

def simulate_all_policies(timesteps=10000):
    result_CT =    simulate(timesteps, policy=[  0,  0,  0], SILENT=True)
    result_LB =    simulate(timesteps, policy=[-20,  0,  0], SILENT=True)
    result_SA =    simulate(timesteps, policy=[ 20,  0,  0], SILENT=True)
    result_KNOWN = simulate(timesteps, policy=[  0, 20,-80], SILENT=True)

    result_CT["Name"] = "Coin-Toss:    "
    result_SA["Name"] = "Suppress-All: "
    result_LB["Name"] = "Let-burn:     "
    result_KNOWN["Name"] = "Known:        "

    results = [result_CT, result_SA, result_LB, result_KNOWN]
    print("Policy            Ave    STD    SupRate  AveProb  JointProb")
    for r in results:
        print(r["Name"] + "   "),
        print(str(r["Average State Value"]) + "   "),
        print(str(r["STD State Value"]) + "   "),
        print(str(r["Suppression Rate"]) + "      "),
        print(str(r["Average Probability"]) + "    "),
        print(str(r["Joint Probability"]))

<commit_msg>added seed values for trial replication<commit_after>"""A Simple Wildfire-inspired MDP model"""

import random, math, numpy

def simulate(timesteps, policy=[0,0,0], random_seed=0, SILENT=False):

    random.seed(random_seed)

    basic_state_value = 2

    #range of the randomly drawn, uniformally distributed "event"
    #this is the only so-called state "feature" in this MDP and
    #is comparable to a wildfire
    event_max = 100
    event_min = 0

    #cost of suppression in a low-severity fire
    action_1_cost_sev_low = 1

    #cost of suppresion in a high-severity fire
    action_1_cost_sev_high = 4

    #cost of a severe fire on the next timestep
    burn_cost = 6

    severity_switchpoint_after_suppression = 80
    severity_switchpoint_after_low = 80
    severity_switchpoint_after_high = 80

    states = [None] * timesteps

    previous_burn_cost = 0
    previous_burn = 'none'

    for i in range(timesteps):

        #event value is the single "feature" of events in this MDP
        ev = random.uniform(event_min, event_max)

        #severity is meant to be a hidden, "black box" variable inside the MDP
        sev = 'low'
        if previous_burn == 'none':
            if ev > severity_switchpoint_after_suppression: sev = 'high'
        elif previous_burn == "low":
            if ev > severity_switchpoint_after_low: sev = 'high'
        elif previous_burn == 'high':
            if ev > severity_switchpoint_after_high: sev = 'high'

        #logistic function for the policy choice
        #policy_crossproduct = policy[0] + policy[1]*ev
        #modified logistic policy function
        #                     CONSTANT       COEFFICIENT       SHIFT
        policy_crossproduct = policy[0] + ( policy[1] * (ev + policy[2]) )
        if policy_crossproduct > 100: policy_crossproduct = 100
        if policy_crossproduct < -100: policy_crossproduct = -100

        policy_value = 1 / (1 + math.exp(-1*(policy_crossproduct)))

        choice_roll = random.uniform(0,1)
        choice = False
        choice_prob = 1 - policy_value
        if choice_roll < policy_value:
            choice = True
            choice_prob = policy_value

        #now check the choice vs severity combinations, and update things for the next state
        if sev == 'low':
            if choice:
                #low severity, with suppression
                previous_burn_cost = 0
                previous_burn = 'none'
            else:
                #low severity, without suppression
                previous_burn_cost = 0
                previous_burn = 'low'

        else: #sev == 'high'
            if choice:
                #high severity, with suppression
                previous_burn_cost = 0
                previous_burn = 'none'
            else:
                #high severity, without suppression
                previous_burn_cost = burn_cost
                previous_burn = 'high'

        this_state_value = basic_state_value - previous_burn_cost
        if choice:
            if sev == 'high':
                this_state_value -= action_1_cost_sev_high
            else: #sev == 'low'
                this_state_value -= action_1_cost_sev_low

        states[i] = [ev, choice, choice_prob, this_state_value]

    #finished simulations, report some values
    vals = []
    suppressions = 0
    joint_prob = 1
    prob_sum = 0
    for i in range(timesteps):
        if states[i][1]: suppressions += 1
        joint_prob *= states[i][2]
        prob_sum += states[i][2]
        vals.append(states[i][3])
    ave_prob = prob_sum / timesteps

    summary = {
                "Average State Value": round(numpy.mean(vals),1),
                "STD State Value": round(numpy.std(vals),1),
                "Suppressions": suppressions,
                "Suppression Rate": round((float(suppressions)/timesteps),2),
                "Joint Probability": joint_prob,
                "Average Probability": round(ave_prob, 3)
              }

    if not SILENT:
        print("")
        print("Simulation Complete")
        print("Average State Value: " + str(round(numpy.mean(vals),1)) + "   STD: " + str(round(numpy.std(vals),1)))
        print("Suppressions: " + str(suppressions))
        print("Suppression Rate: " + str(round((float(suppressions)/timesteps),2)))
        print("Joint Probability:" + str(joint_prob))
        print("Average Probability: " + str(round(ave_prob, 3)))
        print("")

    summary["States"] = states

    return summary

def simulate_all_policies(timesteps=10000, start_seed=0):

    result_CT =    simulate(timesteps, policy=[  0,  0,  0], start_seed, SILENT=True)
    result_LB =    simulate(timesteps, policy=[-20,  0,  0], start_seed, SILENT=True)
    result_SA =    simulate(timesteps, policy=[ 20,  0,  0], start_seed, SILENT=True)
    result_KNOWN = simulate(timesteps, policy=[  0, 20,-80], start_seed, SILENT=True)

    result_CT["Name"] = "Coin-Toss:    "
    result_SA["Name"] = "Suppress-All: "
    result_LB["Name"] = "Let-burn:     "
    result_KNOWN["Name"] = "Known:        "

    results = [result_CT, result_SA, result_LB, result_KNOWN]
    print("Policy            Ave    STD    SupRate  AveProb  JointProb")
    for r in results:
        print(r["Name"] + "   "),
        print(str(r["Average State Value"]) + "   "),
        print(str(r["STD State Value"]) + "   "),
        print(str(r["Suppression Rate"]) + "      "),
        print(str(r["Average Probability"]) + "    "),
        print(str(r["Joint Probability"]))

<|endoftext|>


<commit_before>#!/usr/bin/env python
import subprocess
import glob
import logging
import os

def main(Ngrid, config):
#====================================================================
#	Setup Geotop simulations
#====================================================================
	#ncells = dims.main(wd, wd + "/spatial/eraExtent.tif")
	print "[INFO]: Setup Geotop simulations"

	# set up sim directoroes #and write metfiles
	#for Ngrid in range(1,int(ncells)+1):
		#gridpath = wd +"/grid"+ Ngrid

	#for Ngrid in grid_dirs:
	gridpath = str(Ngrid)

	import os
	if os.path.exists(gridpath):
		print "[INFO]: Setting up geotop inputs " + str(Ngrid)

	 	print "[INFO]: Creating met files...."
	 	from gtop_setup import prepMet as met
		met.main(gridpath, config["toposcale"]["svfCompute"],str(config["da"]["tscale"]),str(config["da"]["pscale"]),str(config["da"]["swscale"]),str(config["da"]["lwscale"]))

		print "[INFO]: extract surface properties"
		from gtop_setup import pointsSurface as psurf
		psurf.main(gridpath)

		print "[INFO]: making inputs file"
		from gtop_setup import makeGeotopInputs as gInput
		gInput.main(gridpath, config["geotop"]["geotopInputsPath"], config["main"]["startDate"], config["main"]["endDate"])

	else:
		print "[INFO]: " + str(Ngrid) + " has been removed because it contained no points. Now processing grid" + str(Ngrid) + "+1"

#====================================================================
#	Run LSM
#====================================================================
	print "[INFO]: Running LSM"

	# set up sim directoroes #and write metfiles

	gridpath = Ngrid

	if os.path.exists(gridpath):

	 	print "[INFO]: Simulations grid " + str(Ngrid) + " running (parallel model runs)"

		# batchfile="batch.sh"
		# sim_entries=gridpath +"/S*"
		# f = open(batchfile, "w+")
		# f.write("#!/bin/bash"+ "\n")
		# f.write("cd " + config["geotop"]["lsmPath"] + "\n")
		# # max 8 jobs set here
		# f.write("parallel -j 8 " + "./" + config["geotop"]["lsmExe"] + " ::: " + sim_entries + "\n")
		# f.close()
		# import os, sys, stat
		# os.chmod(batchfile, stat.S_IRWXU)
		# cmd     = ["./" + batchfile]
		# subprocess.check_output( "./" + batchfile )

		# ====== joblib spawning too many processes =====
		import subprocess
		from joblib import Parallel, delayed
		import multiprocessing
		jobs = glob.glob(gridpath +"/S*")
		logging.info( "Running "+str(len(jobs))+ " multiprocessing jobs " )
		num_cores= config['geotop']['num_cores'] #multiprocessing.cpu_count()
		Parallel(n_jobs=int(num_cores))(delayed(subprocess.call)([config['geotop']['lsmPath'] + '/' + config['geotop']['lsmExe'], i ]) for i in jobs)
		# ===============================================

	else:
		print "[INFO]: " + str(Ngrid) + " has been removed because it contained no points. Now processing grid" + str(Ngrid) + "+1"

#====================================================================
#	Calling MAIN
#====================================================================
if __name__ == '__main__':
	import sys
	Ngrid      = sys.argv[1]
	config      = sys.argv[2]
	main(Ngrid, config)<commit_msg>add RUNSUCCESS file in TMsim.py<commit_after>#!/usr/bin/env python
import subprocess
import glob
import logging
import os

def main(Ngrid, config):
#====================================================================
#	Setup Geotop simulations
#====================================================================
	#ncells = dims.main(wd, wd + "/spatial/eraExtent.tif")
	print "[INFO]: Setup Geotop simulations"

	# set up sim directoroes #and write metfiles
	#for Ngrid in range(1,int(ncells)+1):
		#gridpath = wd +"/grid"+ Ngrid

	#for Ngrid in grid_dirs:
	gridpath = str(Ngrid)

	import os
	if os.path.exists(gridpath):
		print "[INFO]: Setting up geotop inputs " + str(Ngrid)

	 	print "[INFO]: Creating met files...."
	 	from gtop_setup import prepMet as met
		met.main(gridpath, config["toposcale"]["svfCompute"],str(config["da"]["tscale"]),str(config["da"]["pscale"]),str(config["da"]["swscale"]),str(config["da"]["lwscale"]))

		print "[INFO]: extract surface properties"
		from gtop_setup import pointsSurface as psurf
		psurf.main(gridpath)

		print "[INFO]: making inputs file"
		from gtop_setup import makeGeotopInputs as gInput
		gInput.main(gridpath, config["geotop"]["geotopInputsPath"], config["main"]["startDate"], config["main"]["endDate"])

	else:
		print "[INFO]: " + str(Ngrid) + " has been removed because it contained no points. Now processing grid" + str(Ngrid) + "+1"

#====================================================================
#	Run LSM
#====================================================================
	print "[INFO]: Running LSM"

	# set up sim directoroes #and write metfiles

	gridpath = Ngrid

	if os.path.exists(gridpath):

	 	print "[INFO]: Simulations grid " + str(Ngrid) + " running (parallel model runs)"

		# batchfile="batch.sh"
		# sim_entries=gridpath +"/S*"
		# f = open(batchfile, "w+")
		# f.write("#!/bin/bash"+ "\n")
		# f.write("cd " + config["geotop"]["lsmPath"] + "\n")
		# # max 8 jobs set here
		# f.write("parallel -j 8 " + "./" + config["geotop"]["lsmExe"] + " ::: " + sim_entries + "\n")
		# f.close()
		# import os, sys, stat
		# os.chmod(batchfile, stat.S_IRWXU)
		# cmd     = ["./" + batchfile]
		# subprocess.check_output( "./" + batchfile )

		# ====== joblib spawning too many processes =====
		import subprocess
		from joblib import Parallel, delayed
		import multiprocessing
		jobs = glob.glob(gridpath +"/S*")
		logging.info( "Running "+str(len(jobs))+ " multiprocessing jobs " )
		num_cores= config['geotop']['num_cores'] #multiprocessing.cpu_count()
		Parallel(n_jobs=int(num_cores))(delayed(subprocess.call)([config['geotop']['lsmPath'] + '/' + config['geotop']['lsmExe'], i ]) for i in jobs)
		# ===============================================

	else:
		print "[INFO]: " + str(Ngrid) + " has been removed because it contained no points. Now processing grid" + str(Ngrid) + "+1"

	# count sim dirs produce SUCCES file if complete
	sim_dirs = glob.glob(gridpath +"/S*")
	nsims = len(sim_dirs)
	if nsims = config["toposub"]["samples"]:
		file = open(gridpath + “RUNSUCCESS”,”w”)
		file.close()

#====================================================================
#	Calling MAIN
#====================================================================
if __name__ == '__main__':
	import sys
	Ngrid      = sys.argv[1]
	config      = sys.argv[2]
	main(Ngrid, config)<|endoftext|>