<commit_before>"""
Sync Media to S3
================

Django command that scans all files in your settings.STATIC_ROOT + settings.COMPRESS_OUTPUT_DIRNAME + [git commit]  folder and uploads them to S3 with the same directory structure.

This command also does the following
* gzip compress any CSS and Javascript files it finds and adds the appropriate
  'Content-Encoding' header.
* set a far future 'Expires' header for optimal caching.

Note: This script requires the Python boto library and valid Amazon Web
Services API keys.

Required settings.py variables:
AWS_ACCESS_KEY_ID = ''
AWS_SECRET_ACCESS_KEY = ''
AWS_BUCKET_NAME = ''

For example it wil sync anything in
STATIC_ROOT/static-cache/0234dsd/*

"""
import datetime
import email
import mimetypes
import optparse
import os
import sys
import time
import re

from django.core.management.base import BaseCommand, CommandError

# Make sure boto is available
try:
    import boto
    import boto.exception
except ImportError:
    raise ImportError, "The boto Python library is not installed."

from apps.unisubs_compressor.management.commands.compile_media import get_cache_dir
from deploy.git_helpers import get_current_commit_hash
from compile_media import NO_UNIQUE_URL

def add_far_future_expires(headers, verbose=False):
    # HTTP/1.0
    headers['Expires'] = '%s GMT' % (email.Utils.formatdate(
            time.mktime((datetime.datetime.now() +
                         datetime.timedelta(days=365*2)).timetuple())))
    # HTTP/1.1
    headers['Cache-Control'] = 'max-age %d' % (3600 * 24 * 365 * 2)
    if verbose:
        print "\texpires: %s" % (headers['Expires'])
        print "\tcache-control: %s" % (headers['Cache-Control'])

def add_no_cache(headers, verbose=False):
    headers['Cache-Control'] = 'no-cache'
    headers['Expires'] = '%s GMT' % (email.Utils.formatdate(
            time.mktime((datetime.datetime.now() +
                         datetime.timedelta(days=-30*365)).timetuple())))
    if verbose:
        print "\texpires: %s" % (headers['Expires'])
        print "\tcache-control: %s" % (headers['Cache-Control'])

class Command(BaseCommand):

    # Extra variables to avoid passing these around
    AWS_ACCESS_KEY_ID = ''
    AWS_SECRET_ACCESS_KEY = ''
    AWS_BUCKET_NAME = ''
    DIRECTORY = ''
    FILTER_LIST = [re.compile(x) for x in ['\.DS_Store', "^videos.+","^js\/closure-lib" , "^teams", "^test", "^videos"]]

    GZIP_CONTENT_TYPES = (
        'text/css',
        'application/javascript',
        'application/x-javascript'
    )

    upload_count = 0
    skip_count = 0

    option_list = BaseCommand.option_list + (
        optparse.make_option('-p', '--prefix',
            dest='prefix', default='',
            help="The prefix to prepend to the path on S3."),
        optparse.make_option('--gzip',
            action='store_true', dest='gzip', default=True,
            help="Enables gzipping CSS and Javascript files."),
        optparse.make_option('--expires',
            action='store_true', dest='expires', default=True,
            help="Enables setting a far future expires header."),
        optparse.make_option('--force',
            action='store_true', dest='force', default=True,
            help="Skip the file mtime check to force upload of all files.")
    )

    help = 'Syncs the complete STATIC_ROOT structure and files to S3 into the given bucket name.'
    args = 'bucket_name'

    can_import_settings = True

    def handle(self, *args, **options):
        from django.conf import settings

        if not hasattr(settings, 'STATIC_ROOT'):
            raise CommandError('STATIC_ROOT must be set in your settings.')
        else:
            if not settings.STATIC_ROOT:
                raise CommandError('STATIC_ROOT must be set in your settings.')
        self.DIRECTORY = get_cache_dir()
        # Check for AWS keys in settings
        if not hasattr(settings, 'AWS_ACCESS_KEY_ID') or \
           not hasattr(settings, 'AWS_SECRET_ACCESS_KEY'):
           raise CommandError('Missing AWS keys from settings file.  Please' +
                     'supply both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.')
        else:
            self.AWS_ACCESS_KEY_ID = settings.AWS_ACCESS_KEY_ID
            self.AWS_SECRET_ACCESS_KEY = settings.AWS_SECRET_ACCESS_KEY

        if not hasattr(settings, 'AWS_BUCKET_NAME'):
            raise CommandError('Missing bucket name from settings file. Please' +
                ' add the AWS_BUCKET_NAME to your settings file.')
        else:
            if not settings.AWS_BUCKET_NAME:
                raise CommandError('AWS_BUCKET_NAME cannot be empty.')
        self.AWS_BUCKET_NAME = settings.AWS_BUCKET_NAME
        self.verbosity = int(options.get('verbosity'))
        self.prefix = options.get('prefix')
        if bool(self.prefix) is False:
            self.prefix = os.path.join(settings.COMPRESS_OUTPUT_DIRNAME, get_current_commit_hash())
        self.do_gzip = options.get('gzip')
        self.do_expires = options.get('expires')
        self.do_force = options.get('force')

        # Now call the syncing method to walk the STATIC_ROOT directory and
        # upload all files found.
        self.sync_s3()

        print
        print "%d files uploaded." % (self.upload_count)
        print "%d files skipped." % (self.skip_count)

    def sync_s3(self):
        """
        Walks the media directory and syncs files to S3
        """
        bucket, key = self.open_s3()
#        os.path.walk(self.DIRECTORY, self.upload_s3,
#            (bucket, key, self.AWS_BUCKET_NAME, self.DIRECTORY))

        old_prefix = self.prefix
        self.prefix = ""

        self.sync_no_unique_url_items(bucket, key)

        self.prefix = old_prefix

    def sync_no_unique_url_items(self, bucket, key):
        from django.conf import settings
        outside_dir = os.path.dirname(self.DIRECTORY)

        def upload_no_unique_url_item(file_name):
            fname = os.path.basename(file_name)
            base_dir = os.path.join(settings.STATIC_ROOT, os.path.dirname(file_name))
            full_path = os.path.join(settings.STATIC_ROOT, file_name)
            self.upload_one(
                bucket, key, self.AWS_BUCKET_NAME, outside_dir, full_path, file_name,
                add_no_cache if item['no-cache'] else None)

        # these are not to be prefixed by commit, e.g. outside systems link to them
        no_unique_url_items = NO_UNIQUE_URL
        # embed.js is a special case :(
        no_unique_url_items += ({ "name": "embed.js", "no-cache": True },)
        for item in no_unique_url_items:
            file_name = item['name']
            upload_no_unique_url_item(file_name)
            # for backwards compatibility with old mirosubs names
            mirosubs_filename = re.sub(r'unisubs\-', 'mirosubs-', file_name)
            if file_name != mirosubs_filename:
                upload_no_unique_url_item(mirosubs_filename)

    def compress_string(self, s):
        """Gzip a given string."""
        import cStringIO, gzip
        zbuf = cStringIO.StringIO()
        zfile = gzip.GzipFile(mode='wb', compresslevel=6, fileobj=zbuf)
        zfile.write(s)
        zfile.close()
        return zbuf.getvalue()

    def open_s3(self):
        """
        Opens connection to S3 returning bucket and key
        """
        conn = boto.connect_s3(self.AWS_ACCESS_KEY_ID, self.AWS_SECRET_ACCESS_KEY)
        try:
            bucket = conn.get_bucket(self.AWS_BUCKET_NAME)
        except boto.exception.S3ResponseError:
            bucket = conn.create_bucket(self.AWS_BUCKET_NAME)
        return bucket, boto.s3.key.Key(bucket)

    def upload_s3(self, arg, dirname, names):
        """
        This is the callback to os.path.walk and where much of the work happens
        """
        bucket, key, bucket_name, root_dir = arg # expand arg tuple

        if root_dir == dirname:
            return # We're in the root media folder

        # Later we assume the STATIC_ROOT ends with a trailing slash
        # TODO: Check if we should check os.path.sep for Windows
        if not root_dir.endswith('/'):
            root_dir = root_dir + '/'

        for file in names:
            filename = os.path.join(dirname, file)
            for p in self.FILTER_LIST:
                if p.match(file) or p.match(filename):
                    print "not uplodaing! filtering ", file
                    continue # Skip files we don't want to sync

            if os.path.isdir(filename):
                continue # Don't try to upload directories

            file_key = filename[len(root_dir):]
            if self.prefix:
                file_key = '%s/%s' % (self.prefix, file_key)

            cache_strategy = None
            if self.do_expires:
                cache_strategy = add_far_future_expires
            self.upload_one(bucket, key, bucket_name, root_dir, filename, file_key, cache_strategy)

    def upload_one(self, bucket, key, bucket_name, root_dir, filename,
                   file_key, cache_strategy=None):
        if self.verbosity > 0:
            print "Uploading %s..." % (file_key)
        headers = {}
        content_type = mimetypes.guess_type(filename)[0]
        if content_type:
            headers['Content-Type'] = content_type
        file_obj = open(filename, 'rb')
        file_size = os.fstat(file_obj.fileno()).st_size
        filedata = file_obj.read()
        if self.do_gzip:
            # Gzipping only if file is large enough (>1K is recommended)
            # and only if file is a common text type (not a binary file)
            if file_size > 1024 and content_type in self.GZIP_CONTENT_TYPES:
                filedata = self.compress_string(filedata)
                headers['Content-Encoding'] = 'gzip'
                if self.verbosity > 1:
                    print "\tgzipped: %dk to %dk" % \
                        (file_size/1024, len(filedata)/1024)
        if cache_strategy is not None:
            cache_strategy(headers, self.verbosity > 1)

        try:
            key.name = file_key
            key.set_contents_from_string(filedata, headers, replace=True)
            key.make_public()
        except boto.s3.connection.BotoClientError, e:
            print "Failed: %s" % e
        except Exception, e:
            print e
            raise
        else:
            self.upload_count += 1

        file_obj.close()

# Backwards compatibility for Django r9110
if not [opt for opt in Command.option_list if opt.dest=='verbosity']:
    Command.option_list += (
        optparse.make_option('-v', '--verbosity',
            dest='verbosity', default=1, action='count',
            help="Verbose mode. Multiple -v options increase the verbosity."),
    )
<commit_msg>Uncommented lines that were commented for testing<commit_after>"""
Sync Media to S3
================

Django command that scans all files in your settings.STATIC_ROOT + settings.COMPRESS_OUTPUT_DIRNAME + [git commit]  folder and uploads them to S3 with the same directory structure.

This command also does the following
* gzip compress any CSS and Javascript files it finds and adds the appropriate
  'Content-Encoding' header.
* set a far future 'Expires' header for optimal caching.

Note: This script requires the Python boto library and valid Amazon Web
Services API keys.

Required settings.py variables:
AWS_ACCESS_KEY_ID = ''
AWS_SECRET_ACCESS_KEY = ''
AWS_BUCKET_NAME = ''

For example it wil sync anything in
STATIC_ROOT/static-cache/0234dsd/*

"""
import datetime
import email
import mimetypes
import optparse
import os
import sys
import time
import re

from django.core.management.base import BaseCommand, CommandError

# Make sure boto is available
try:
    import boto
    import boto.exception
except ImportError:
    raise ImportError, "The boto Python library is not installed."

from apps.unisubs_compressor.management.commands.compile_media import get_cache_dir
from deploy.git_helpers import get_current_commit_hash
from compile_media import NO_UNIQUE_URL

def add_far_future_expires(headers, verbose=False):
    # HTTP/1.0
    headers['Expires'] = '%s GMT' % (email.Utils.formatdate(
            time.mktime((datetime.datetime.now() +
                         datetime.timedelta(days=365*2)).timetuple())))
    # HTTP/1.1
    headers['Cache-Control'] = 'max-age %d' % (3600 * 24 * 365 * 2)
    if verbose:
        print "\texpires: %s" % (headers['Expires'])
        print "\tcache-control: %s" % (headers['Cache-Control'])

def add_no_cache(headers, verbose=False):
    headers['Cache-Control'] = 'no-cache'
    headers['Expires'] = '%s GMT' % (email.Utils.formatdate(
            time.mktime((datetime.datetime.now() +
                         datetime.timedelta(days=-30*365)).timetuple())))
    if verbose:
        print "\texpires: %s" % (headers['Expires'])
        print "\tcache-control: %s" % (headers['Cache-Control'])

class Command(BaseCommand):

    # Extra variables to avoid passing these around
    AWS_ACCESS_KEY_ID = ''
    AWS_SECRET_ACCESS_KEY = ''
    AWS_BUCKET_NAME = ''
    DIRECTORY = ''
    FILTER_LIST = [re.compile(x) for x in ['\.DS_Store', "^videos.+","^js\/closure-lib" , "^teams", "^test", "^videos"]]

    GZIP_CONTENT_TYPES = (
        'text/css',
        'application/javascript',
        'application/x-javascript'
    )

    upload_count = 0
    skip_count = 0

    option_list = BaseCommand.option_list + (
        optparse.make_option('-p', '--prefix',
            dest='prefix', default='',
            help="The prefix to prepend to the path on S3."),
        optparse.make_option('--gzip',
            action='store_true', dest='gzip', default=True,
            help="Enables gzipping CSS and Javascript files."),
        optparse.make_option('--expires',
            action='store_true', dest='expires', default=True,
            help="Enables setting a far future expires header."),
        optparse.make_option('--force',
            action='store_true', dest='force', default=True,
            help="Skip the file mtime check to force upload of all files.")
    )

    help = 'Syncs the complete STATIC_ROOT structure and files to S3 into the given bucket name.'
    args = 'bucket_name'

    can_import_settings = True

    def handle(self, *args, **options):
        from django.conf import settings

        if not hasattr(settings, 'STATIC_ROOT'):
            raise CommandError('STATIC_ROOT must be set in your settings.')
        else:
            if not settings.STATIC_ROOT:
                raise CommandError('STATIC_ROOT must be set in your settings.')
        self.DIRECTORY = get_cache_dir()
        # Check for AWS keys in settings
        if not hasattr(settings, 'AWS_ACCESS_KEY_ID') or \
           not hasattr(settings, 'AWS_SECRET_ACCESS_KEY'):
           raise CommandError('Missing AWS keys from settings file.  Please' +
                     'supply both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.')
        else:
            self.AWS_ACCESS_KEY_ID = settings.AWS_ACCESS_KEY_ID
            self.AWS_SECRET_ACCESS_KEY = settings.AWS_SECRET_ACCESS_KEY

        if not hasattr(settings, 'AWS_BUCKET_NAME'):
            raise CommandError('Missing bucket name from settings file. Please' +
                ' add the AWS_BUCKET_NAME to your settings file.')
        else:
            if not settings.AWS_BUCKET_NAME:
                raise CommandError('AWS_BUCKET_NAME cannot be empty.')
        self.AWS_BUCKET_NAME = settings.AWS_BUCKET_NAME
        self.verbosity = int(options.get('verbosity'))
        self.prefix = options.get('prefix')
        if bool(self.prefix) is False:
            self.prefix = os.path.join(settings.COMPRESS_OUTPUT_DIRNAME, get_current_commit_hash())
        self.do_gzip = options.get('gzip')
        self.do_expires = options.get('expires')
        self.do_force = options.get('force')

        # Now call the syncing method to walk the STATIC_ROOT directory and
        # upload all files found.
        self.sync_s3()

        print
        print "%d files uploaded." % (self.upload_count)
        print "%d files skipped." % (self.skip_count)

    def sync_s3(self):
        """
        Walks the media directory and syncs files to S3
        """
        bucket, key = self.open_s3()
        os.path.walk(self.DIRECTORY, self.upload_s3,
            (bucket, key, self.AWS_BUCKET_NAME, self.DIRECTORY))

        old_prefix = self.prefix
        self.prefix = ""

        self.sync_no_unique_url_items(bucket, key)

        self.prefix = old_prefix

    def sync_no_unique_url_items(self, bucket, key):
        from django.conf import settings
        outside_dir = os.path.dirname(self.DIRECTORY)

        def upload_no_unique_url_item(file_name):
            fname = os.path.basename(file_name)
            base_dir = os.path.join(settings.STATIC_ROOT, os.path.dirname(file_name))
            full_path = os.path.join(settings.STATIC_ROOT, file_name)
            self.upload_one(
                bucket, key, self.AWS_BUCKET_NAME, outside_dir, full_path, file_name,
                add_no_cache if item['no-cache'] else None)

        # these are not to be prefixed by commit, e.g. outside systems link to them
        no_unique_url_items = NO_UNIQUE_URL
        # embed.js is a special case :(
        no_unique_url_items += ({ "name": "embed.js", "no-cache": True },)
        for item in no_unique_url_items:
            file_name = item['name']
            upload_no_unique_url_item(file_name)
            # for backwards compatibility with old mirosubs names
            mirosubs_filename = re.sub(r'unisubs\-', 'mirosubs-', file_name)
            if file_name != mirosubs_filename:
                upload_no_unique_url_item(mirosubs_filename)

    def compress_string(self, s):
        """Gzip a given string."""
        import cStringIO, gzip
        zbuf = cStringIO.StringIO()
        zfile = gzip.GzipFile(mode='wb', compresslevel=6, fileobj=zbuf)
        zfile.write(s)
        zfile.close()
        return zbuf.getvalue()

    def open_s3(self):
        """
        Opens connection to S3 returning bucket and key
        """
        conn = boto.connect_s3(self.AWS_ACCESS_KEY_ID, self.AWS_SECRET_ACCESS_KEY)
        try:
            bucket = conn.get_bucket(self.AWS_BUCKET_NAME)
        except boto.exception.S3ResponseError:
            bucket = conn.create_bucket(self.AWS_BUCKET_NAME)
        return bucket, boto.s3.key.Key(bucket)

    def upload_s3(self, arg, dirname, names):
        """
        This is the callback to os.path.walk and where much of the work happens
        """
        bucket, key, bucket_name, root_dir = arg # expand arg tuple

        if root_dir == dirname:
            return # We're in the root media folder

        # Later we assume the STATIC_ROOT ends with a trailing slash
        # TODO: Check if we should check os.path.sep for Windows
        if not root_dir.endswith('/'):
            root_dir = root_dir + '/'

        for file in names:
            filename = os.path.join(dirname, file)
            for p in self.FILTER_LIST:
                if p.match(file) or p.match(filename):
                    print "not uplodaing! filtering ", file
                    continue # Skip files we don't want to sync

            if os.path.isdir(filename):
                continue # Don't try to upload directories

            file_key = filename[len(root_dir):]
            if self.prefix:
                file_key = '%s/%s' % (self.prefix, file_key)

            cache_strategy = None
            if self.do_expires:
                cache_strategy = add_far_future_expires
            self.upload_one(bucket, key, bucket_name, root_dir, filename, file_key, cache_strategy)

    def upload_one(self, bucket, key, bucket_name, root_dir, filename,
                   file_key, cache_strategy=None):
        if self.verbosity > 0:
            print "Uploading %s..." % (file_key)
        headers = {}
        content_type = mimetypes.guess_type(filename)[0]
        if content_type:
            headers['Content-Type'] = content_type
        file_obj = open(filename, 'rb')
        file_size = os.fstat(file_obj.fileno()).st_size
        filedata = file_obj.read()
        if self.do_gzip:
            # Gzipping only if file is large enough (>1K is recommended)
            # and only if file is a common text type (not a binary file)
            if file_size > 1024 and content_type in self.GZIP_CONTENT_TYPES:
                filedata = self.compress_string(filedata)
                headers['Content-Encoding'] = 'gzip'
                if self.verbosity > 1:
                    print "\tgzipped: %dk to %dk" % \
                        (file_size/1024, len(filedata)/1024)
        if cache_strategy is not None:
            cache_strategy(headers, self.verbosity > 1)

        try:
            key.name = file_key
            key.set_contents_from_string(filedata, headers, replace=True)
            key.make_public()
        except boto.s3.connection.BotoClientError, e:
            print "Failed: %s" % e
        except Exception, e:
            print e
            raise
        else:
            self.upload_count += 1

        file_obj.close()

# Backwards compatibility for Django r9110
if not [opt for opt in Command.option_list if opt.dest=='verbosity']:
    Command.option_list += (
        optparse.make_option('-v', '--verbosity',
            dest='verbosity', default=1, action='count',
            help="Verbose mode. Multiple -v options increase the verbosity."),
    )
<|endoftext|>


<commit_before>"""config module."""
import os

basedir = os.path.abspath(os.path.dirname(__file__))

class Config(object):

    CACHE_TYPE = "SimpleCache"
    CACHE_DEFAULT_TIMEOUT = 300
    PORT = os.environ.get('PORT') or '5555'
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard to guess string'
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SQLALCHEMY_ECHO = False

class DevelopmentConfig(Config):

    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
        'sqlite:///' + os.path.join(basedir, '../tmp/dev.db')

class TestingConfig(Config):

    TESTING = True
    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + \
        os.path.join(basedir, '../tmp/test.db')

class ProductionConfig(Config):

    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
        'sqlite:///' + os.path.join(basedir, '../tmp/data.db')

config = {
    'development': DevelopmentConfig,
    'testing': TestingConfig,
    'production': ProductionConfig,
    'default': DevelopmentConfig,
}
<commit_msg>Forced to config db on production<commit_after>"""config module."""
import os

basedir = os.path.abspath(os.path.dirname(__file__))

class Config(object):

    CACHE_TYPE = "SimpleCache"
    CACHE_DEFAULT_TIMEOUT = 300
    PORT = os.environ.get('PORT') or '5555'
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard to guess string'
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SQLALCHEMY_ECHO = False

class DevelopmentConfig(Config):

    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
        'sqlite:///' + os.path.join(basedir, '../tmp/dev.db')

class TestingConfig(Config):

    TESTING = True
    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + \
        os.path.join(basedir, '../tmp/test.db')

class ProductionConfig(Config):

    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', None)

config = {
    'development': DevelopmentConfig,
    'testing': TestingConfig,
    'production': ProductionConfig,
    'default': DevelopmentConfig,
}
<|endoftext|>


<commit_before>"""
Sudoku solver.
"""

from itertools import product

in_fname = "/home/raca/Downloads/p096_sudoku.txt"

class SudokuSolver(object):
    """docstring for SudokuSolver"""

    def __init__(self):
        self.table = {}
        self.fixed = {}
        for x,y in product(range(9), repeat=2):
            self.table[(x,y)] = range(1,10)
            self.fixed[(x,y)] = False

    def add_observation(self, x, y, val):
        self.table[(x,y)] = [val]
        self.fixed[(x,y)] = True
        # line information
        for runner in xrange(9):
            try:
                if not self.fixed[(x,runner)]:
                    self.table[(x, runner)].remove(val)
            except ValueError:
                pass
            try:
                if not self.fixed[(runner, y)]:
                    self.table[(runner, y)].remove(val)
            except:
                pass
        # quadrant
        x_range_start = x - (x % 3)
        y_range_start = y - (y % 3)
        for x1,y1 in product(range(x_range_start, x_range_start+3), range(y_range_start, y_range_start+3)):
            try:
                if not self.fixed[(x1,y1)]:
                    self.table[(x1,y1)].remove(val)
            except KeyError:
                pass
            except ValueError:
                pass

    def insert_original_table(self,lines):
        x = 0
        for line in lines:
            for y in xrange(9):
                if line[y] != '0':
                    self.add_observation(x,y,int(line[y]))
            x += 1

    def run(self):
        new_information = True
        while new_information:
            new_information = False
            for x,y in product(range(9), repeat=2):
                if self.fixed[(x,y)] == False and len(self.table[(x,y)]) == 1:
                    print("New automatic observation at (%d, %d) = %d" % (x+1,y+1, self.table[(x,y)][0]))
                    self.add_observation(x,y,self.table[(x,y)][0])
                    new_information = True
                    # self.disp() # debug!
                    break
        # final check
        print("No new information")
        for x,y in product(range(9), repeat=2):
            if self.fixed[(x,y)] == False:
                print("Unfinished business")
                return False # inconsistant state - not enough information for clear solving
        print("Done.")
        return True # success!

    def disp(self):
        print("-" * 21)
        for x,y in product(range(9), repeat=2):
            if self.fixed[(x,y)]:
                print(self.table[(x,y)][0]),
            else:
                print("_"),
            if y in (2, 5):
                print("|"),
            if y == 8:
                print("\n")
            if y == 8 and x in (2, 5):
                print("-" * 21)
        print("-" * 21)

    def disp_dillemas(self):
        for x,y in product(range(9), repeat=2):
            if not self.fixed[(x,y)]:
                print("(%d, %d) = " % (x+1, y+1)),
                print(self.table[(x,y)])

    def get_sum(self):
        tmpsum = 0
        for i in xrange(3):
            tmpsum += self.table[(0,i)][0]
        return tmpsum

in_hnd = open(in_fname)
all_lines = in_hnd.readlines()
total_solved = 0
for sid in xrange(50):
    print("Solving #%02d" % (sid+1))
    solver = SudokuSolver()
    solver.insert_original_table(all_lines[sid*10+1:(sid+1)*10])
    print("Initial state:")
    solver.disp()
    if not solver.run():
        solver.disp_dillemas()
    else:
        total_solved += 1
    solver.disp()

print("Simple stuff solves: %d" % total_solved)<commit_msg>96, ctnd<commit_after>"""
Sudoku solver.
"""

from itertools import product
from copy import deepcopy
from collections import deque

in_fname = "/home/raca/Downloads/p096_sudoku.txt"

class SudokuSolver(object):
    """docstring for SudokuSolver"""

    def __init__(self):
        self.table = {}
        self.fixed = {}
        self.checkpoints_table = deque() # table state before branching
        self.checkpoints_fixed = deque() # fixed state before branching
        self.checkpoints_bad_decision = deque() # bad decision in the current branch
        self.checkpoints_decision = deque() # branching decision
        self.checkpoints_checkpoints_decision = deque() # ha, so meta of me...
        self.bad_decisions = []
        self.guess_threshold = 2 # how many combinations we need to have to make a guess, initially just 2-uncertainty are considered
        for x,y in product(range(9), repeat=2):
            self.table[(x,y)] = range(1,10)
            self.fixed[(x,y)] = False

    def add_observation(self, x, y, val):
        self.table[(x,y)] = [val]
        self.fixed[(x,y)] = True
        # line information
        for runner in xrange(9):
            try:
                if not self.fixed[(x,runner)]:
                    self.table[(x, runner)].remove(val)
            except ValueError:
                pass
            try:
                if not self.fixed[(runner, y)]:
                    self.table[(runner, y)].remove(val)
            except:
                pass
        # quadrant
        x_range_start = x - (x % 3)
        y_range_start = y - (y % 3)
        for x1,y1 in product(range(x_range_start, x_range_start+3), range(y_range_start, y_range_start+3)):
            try:
                if not self.fixed[(x1,y1)]:
                    self.table[(x1,y1)].remove(val)
            except KeyError:
                pass
            except ValueError:
                pass
        self.check_inconsistent()

    def check_inconsistent(self):
        for x,y in product(range(9), repeat=2):
            if len(self.table[(x,y)]) == 0:
                print("\tDetected inconsistant state!")
                self.pop_state()

    def insert_original_table(self,lines):
        x = 0
        for line in lines:
            for y in xrange(9):
                if line[y] != '0':
                    self.add_observation(x,y,int(line[y]))
            x += 1

    def run(self, max_guesses=1000):
        guess_no = 0
        while guess_no < max_guesses: # just to avoid infinite loops and waiting
            new_information = True
            while new_information:
                new_information = False
                for x,y in product(range(9), repeat=2):
                    if self.fixed[(x,y)] == False and len(self.table[(x,y)]) == 1:
                        print("New automatic observation at (%d, %d) = %d" % (x+1,y+1, self.table[(x,y)][0]))
                        self.add_observation(x,y,self.table[(x,y)][0])
                        new_information = True
                        # self.disp() # debug!
                        break
            # final check
            print("No new information")
            table_cleared = True
            for x,y in product(range(9), repeat=2):
                if self.fixed[(x,y)] == False:
                    print("Unfinished business"),
                    table_cleared = False # inconsistant state - not enough information for clear solving
                    break
            if table_cleared:
                print("Done.")
                return True # success!
            else:
                try:
                    self.make_a_guess()
                except RuntimeError:
                    return False
            guess_no += 1

    def push_state(self, decision):
        self.checkpoints_decision.append(decision)
        self.checkpoints_checkpoints_decision.append(deepcopy(self.checkpoints_decision))
        self.checkpoints_fixed.append(deepcopy(self.fixed))
        self.checkpoints_table.append(deepcopy(self.table))
        self.checkpoints_bad_decision.append(deepcopy(self.bad_decisions))

    def pop_state(self):
        self.table = self.checkpoints_table.pop()
        self.fixed = self.checkpoints_fixed.pop()
        self.checkpoints_decision = self.checkpoints_checkpoints_decision.pop()
        self.bad_decisions = self.checkpoints_bad_decision.pop()
        self.bad_decisions.append(self.checkpoints_decision.pop())
        self.guess_threshold = 2

    def make_a_guess(self):
        found_guess = False
        while not found_guess:
            for x,y in product(range(9), repeat=2):
                if self.fixed[(x,y)] == False and len(self.table[(x,y)]) == self.guess_threshold:
                    # find a guess we didn't have
                    for val in self.table[(x,y)]:
                        comb_key = (x,y,val)
                        if comb_key not in self.bad_decisions:
                            print("Guessing (%d,%d) = %d" % (x+1, y+1, val))
                            self.push_state(comb_key)
                            self.add_observation(x,y,val)
                            # self.disp()
                            return
            self.guess_threshold += 1
            if self.guess_threshold > 9:
                raise RuntimeError("Guess level went too high")

    def disp(self):
        print("-" * 21)
        for x,y in product(range(9), repeat=2):
            if self.fixed[(x,y)]:
                print(self.table[(x,y)][0]),
            else:
                print("_"),
            if y in (2, 5):
                print("|"),
            if y == 8:
                print("\n")
            if y == 8 and x in (2, 5):
                print("-" * 21)
        print("-" * 21)

    def disp_dillemas(self):
        for x,y in product(range(9), repeat=2):
            if not self.fixed[(x,y)]:
                print("(%d, %d) = " % (x+1, y+1)),
                print(self.table[(x,y)])

    def get_sum(self):
        tmpsum = 0
        for i in xrange(3):
            tmpsum += self.table[(0,i)][0]
        return tmpsum

in_hnd = open(in_fname)
all_lines = in_hnd.readlines()
total_solved = 0
not_solved = []
for sid in xrange(50):
    print("Solving #%02d" % (sid+1))
    solver = SudokuSolver()
    solver.insert_original_table(all_lines[sid*10+1:(sid+1)*10])
    print("Initial state:")
    solver.disp()
    if not solver.run():
        solver.disp_dillemas()
        not_solved.append(sid)
    else:
        total_solved += 1
    solver.disp()

print("With guessing, solves: %d" % total_solved) # 26
print("Problems: "),
print(not_solved) # [2, 5, 8, 9, 12, 13, 17, 21, 24, 25, 28, 29, 30, 32, 36, 40, 41, 42, 43, 44, 45, 47, 48, 49]<|endoftext|>


<commit_before># You are given the following information, but you may prefer to do some research for yourself.
#
#  - 1 Jan 1900 was a Monday.
#  - Thirty days has September,
#    April, June and November.
#    All the rest have thirty-one,
#    Saving February alone,
#    Which has twenty-eight, rain or shine.
#    And on leap years, twenty-nine.
#  - A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
#
# How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

#########################################################
days_in_month = [31,  28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] #0 - 11
days_per_year = 365 #sum(days_in_month)

# defines
SUNDAY = 0
TUESDAY = 2
DAYS_IN_WEEK = 7
FEB = 1

# counts the sundays
ans_count = 0

# counts monthes (year is 1900 + (month_count % 12))
month_count = 0

#########################################################
def get_month():
    return (month_count % 12) + 1

#########################################################
def get_year():
    return 1901 + (month_count / 12)

# check if a given year is a "leap year"
# if so, Feb will have one more day in it.
#########################################################
def is_leap_year():
    year = get_year()
    if(year % 4 == 0):
        if(year % 100 == 0):
            if(year % 400 == 0):
                return True
            else:
                return False
        else:
            return True
    else:
        return False

#########################################################
def get_days_in_month():
    month_id = month_count % 12
    if(month_id == FEB):
        if(is_leap_year()):
            return days_in_month[month_id] + 1
        else:
            return days_in_month[month_id]
    else:
        return days_in_month[month_id]

#########################################################
def euler_problem_19():
    global month_count
    global ans_count

    # initial data
    today = TUESDAY # Jan 1st, 1901
    while(get_year() < 2001):
        print("checking date: %d/%d/%d" % (1, get_month(), get_year()))

        if(today == SUNDAY):
            ans_count += 1
            print "\tThis is a Sunday"

        days = get_days_in_month()
        today  = (today + days) % DAYS_IN_WEEK
        month_count += 1

    print("ans: %d" %(ans_count))
    return

euler_problem_19();
<commit_msg>Minor refactoring<commit_after># You are given the following information, but you may prefer to do some research for yourself.
#
#  - 1 Jan 1900 was a Monday.
#  - Thirty days has September,
#    April, June and November.
#    All the rest have thirty-one,
#    Saving February alone,
#    Which has twenty-eight, rain or shine.
#    And on leap years, twenty-nine.
#  - A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
#
# How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

#########################################################
days_in_month = [31,  28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] #0 - 11
days_per_year = 365 #sum(days_in_month)

# defines
SUNDAY = 0
TUESDAY = 2
DAYS_IN_WEEK = 7
FEB = 1
FIRST_YEAR = 1901
LAST_YEAR = 2000

# counts the sundays
ans_count = 0

month_count = 0

#########################################################
def get_month():
    return (month_count % 12) + 1

#########################################################
def get_year():
    return FIRST_YEAR + (month_count / 12)

# check if a given year is a "leap year"
# if so, Feb will have one more day in it.
#########################################################
def is_leap_year():
    year = get_year()
    if(year % 4 == 0):
        if(year % 100 == 0):
            if(year % 400 == 0):
                return True
            else:
                return False
        else:
            return True
    else:
        return False

#########################################################
def get_days_in_month():
    month_id = month_count % 12
    if(month_id == FEB):
        if(is_leap_year()):
            return days_in_month[month_id] + 1
        else:
            return days_in_month[month_id]
    else:
        return days_in_month[month_id]

#########################################################
def euler_problem_19():
    global month_count
    global ans_count

    # initial data
    today = TUESDAY # Jan 1st, 1901
    while(get_year() <= LAST_YEAR):
        print("checking date: %d/%d/%d" % (1, get_month(), get_year()))

        if(today == SUNDAY):
            ans_count += 1
            print "\tThis is a Sunday"

        days = get_days_in_month()
        today  = (today + days) % DAYS_IN_WEEK
        month_count += 1

    print("ans: %d" %(ans_count))
    return

euler_problem_19();
<|endoftext|>


<commit_before>#!/usr/bin/python3
import sys
import time
from md01 import *
import curses

def curses_loop(tels, target):
    stdscr = curses.initscr()
    loop = True
    cw = 12 # column width
    stdscr.nodelay(True) # Don't wait for user input
    while loop:
        # Sleep 0.5s between reading and sending commands
        time.sleep(0.5)
        # Display info on screen...
        stdscr.clear()
        stdscr.addstr(0, 0, "UTC now   | ", curses.A_BOLD)
        stdscr.addstr(1, 0, "TELESCOPE | ", curses.A_BOLD)
        stdscr.addstr(2, 0, "Cur. Alt. | ", curses.A_BOLD)
        stdscr.addstr(3, 0, "Cur. Az.  | ", curses.A_BOLD)
        stdscr.addstr(4, 0, "Tar. Alt. | ", curses.A_BOLD)
        stdscr.addstr(5, 0, "Tar. Az.  | ", curses.A_BOLD)
        stdscr.addstr(6, 0, "TRACKING: | ", curses.A_BOLD)
        ## Some space
        stdscr.addstr(10, 0, "Available commands: ", curses.A_BOLD)
        stdscr.addstr(11, 0, "s - stop telescopes")
        stdscr.addstr(12, 0, "q - stop telescopes and quit program")
        stdscr.addstr(13, 0, "g - Track new Galactic (GLON/GLAT) position")
        stdscr.addstr(14, 0, "h - Track new Horizontal (ALT/AZ) direction ")
        stdscr.addstr(15, 0, "i - Track the Sun")
        # Set datetime info
        utcnow = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
        stdscr.addstr(0, cw, utcnow)
        # Print tel names and current position
        for i, tel in enumerate(tels):
            stdscr.addstr(1, cw * (1+i), tel.site.name, curses.A_UNDERLINE)
            (cal, caz) = tel.get_current_alaz()
            stdscr.addstr(2, cw * (1+i), "{}".format(cal))
            stdscr.addstr(3, cw * (1+i), "{}".format(caz))
        # Sleep 0.5s between reading and sending commands
        time.sleep(0.5)

        # Set target info
        if target[0]=="":
            stdscr.addstr(6, cw, "N/A")
            tal = ""
            taz = ""
            for i, tel in enumerate(tels):
                # Print target alt/az
                stdscr.addstr(4, cw * (1+i), "{}".format(tal))
                stdscr.addstr(5, cw * (1+i), "{}".format(taz))
        elif target[0]=="HOR":
            stdscr.addstr(6, cw, "HORIZONTAL")
            tal = target[1]
            taz = target[2]
            for i, tel in enumerate(tels):
                # Print target alt/az
                stdscr.addstr(4, cw * (1+i), "{}".format(tal))
                stdscr.addstr(5, cw * (1+i), "{}".format(taz))
        elif target[0]=="GAL":
            glon = target[1]
            glat = target[2]
            stdscr.addstr(6, cw, "GALACTIC LON={}, LAT={}".format(glon, glat))
            for i, tel in enumerate(tels):
                # Don't get current pos, instead get desired
                tal,taz = tel.get_desired_alaz(target)
                # Move all telescopes
                tel.move(tal, taz)
                # Print target alt/az from now or last loop
                stdscr.addstr(4, cw * (1+i), "{}".format(tal))
                stdscr.addstr(5, cw * (1+i), "{}".format(taz))
        elif target[0]=="SUN":
            stdscr.addstr(6, cw, "The Sun")
            for i, tel in enumerate(tels):
                # Don't get current pos, instead get desired
                tal,taz = tel.get_desired_alaz(target)
                # Move all telescopes
                tel.move(tal, taz)
                # Print target alt/az from now or last loop
                stdscr.addstr(4, cw * (1+i), "{}".format(tal))
                stdscr.addstr(5, cw * (1+i), "{}".format(taz))

        # Handle user input
        try:
            key = stdscr.getkey().lower()
            if key=="s":
                # Stop all tels
                for i, tel in enumerate(tels):
                    tel.stop()
                target = ["", "", ""]
            elif key=="q":
                # Stop all tels
                for i, tel in enumerate(tels):
                    tel.stop()
                stdscr.clear()
                stdscr.refresh()
                loop = False
            elif key=="g" or key=="h" or key=="i":
                # Quit this loop to get new target from user
                stdscr.clear()
                stdscr.refresh()
                loop = False
        except:
            pass
        stdscr.refresh()
    curses.endwin()

    # Return user input to control loop
    return key

def control_loop(tels):
    # Enable curses loop
    cloop = True
    # Initialize target to empty string
    target = ["","",""]
    while cloop:
        # Run curses loop awaiting user input
        ans = curses_loop(tels, target)
        # We got user input, deal with it...
        if ans == "g":
            glon = float(input("Please enter target galactic longitude in decimal degrees e.g. 80.5 :"))
            glat = float(input("Please enter target galactic latitude in decimal degrees e.g. 0.0 :"))
            conf = input("Are you sure you want to track glon={} glat={} deg ? [Yes/No]".format(glon,glat))
            if conf.lower()=="yes":
                target = ["GAL", glon, glat]
                # Stop all tels
                for i, tel in enumerate(tels):
                    tel.stop()
                time.sleep(1.0)
                # Movement done by curses_loop in this case
        if ans == "h":
            az = float(input("Please enter target azimuth in decimal degrees e.g. 148.5 :"))
            al = float(input("Please enter target altitude in decimal degrees e.g. 43.5 :"))
            conf = input("Are you sure you want to track alt={} az={} deg ? [Yes/No]".format(al, az))
            if conf.lower()=="yes":
                target = ["HOR", al,az]
                # Stop all tels
                for i, tel in enumerate(tels):
                    tel.stop()
                time.sleep(1.0)
                # Move all telescopes, started here to simplify code (but yes, ugly place)
                for i, tel in enumerate(tels):
                    tel.move(al, az)
        if ans == "i":
            conf = input("Are you sure you want to track the Sun ? [Yes/No]")
            if conf.lower()=="yes":
                target = ["SUN", "", ""]
                # Stop all tels
                for i, tel in enumerate(tels):
                    tel.stop()
                time.sleep(1.0)
                # Movement done by curses_loop in this case
        elif ans == "q":
            # Quit program
            cloop = False

if __name__ == '__main__':
    # Assume list of config files given as script arguments on command line,
    # so we run "python3 script.py tel1.conf tel2.conf ..."
    # Each config file reflects a telescope to be controlled
    configs = sys.argv[1:]
    tels = []

    # Create one MD01 object for each config file (each telescope)
    for cf in configs:
        tels.append(MD01(cf))
    # Start control loop
    control_loop(tels)
<commit_msg>Update main.py<commit_after>#!/usr/bin/python3
import sys
import time
from md01 import *
import curses

def curses_loop(tels, target):
    stdscr = curses.initscr()
    loop = True
    cw = 12 # column width
    stdscr.nodelay(True) # Don't wait for user input
    while loop:
        # Sleep 0.5s between reading and sending commands
        time.sleep(0.5)
        # Display info on screen...
        stdscr.clear()
        stdscr.addstr(0, 0, "UTC now   | ", curses.A_BOLD)
        stdscr.addstr(1, 0, "TELESCOPE | ", curses.A_BOLD)
        stdscr.addstr(2, 0, "Cur. Alt. | ", curses.A_BOLD)
        stdscr.addstr(3, 0, "Cur. Az.  | ", curses.A_BOLD)
        stdscr.addstr(4, 0, "Tar. Alt. | ", curses.A_BOLD)
        stdscr.addstr(5, 0, "Tar. Az.  | ", curses.A_BOLD)
        stdscr.addstr(6, 0, "TRACKING: | ", curses.A_BOLD)
        ## Some space before command list
        stdscr.addstr(10, 0, "Available commands: ", curses.A_BOLD)
        stdscr.addstr(11, 0, "s - stop telescopes")
        stdscr.addstr(12, 0, "q - stop telescopes and quit program")
        stdscr.addstr(13, 0, "g - Track new Galactic (GLON/GLAT) position")
        stdscr.addstr(14, 0, "h - Track new Horizontal (ALT/AZ) direction ")
        stdscr.addstr(15, 0, "i - Track the Sun")
        # Set datetime info
        utcnow = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
        stdscr.addstr(0, cw, utcnow)
        # Print tel names and current position
        for i, tel in enumerate(tels):
            stdscr.addstr(1, cw * (1+i), tel.site.name, curses.A_UNDERLINE)
            (cal, caz) = tel.get_current_alaz()
            stdscr.addstr(2, cw * (1+i), "{}".format(cal))
            stdscr.addstr(3, cw * (1+i), "{}".format(caz))
        # Sleep 0.5s between reading and sending commands
        time.sleep(0.5)

        # Set target info
        if target[0]=="":
            stdscr.addstr(6, cw, "N/A")
            tal = ""
            taz = ""
            for i, tel in enumerate(tels):
                # Print target alt/az
                stdscr.addstr(4, cw * (1+i), "{}".format(tal))
                stdscr.addstr(5, cw * (1+i), "{}".format(taz))
        elif target[0]=="HOR":
            stdscr.addstr(6, cw, "HORIZONTAL")
            tal = target[1]
            taz = target[2]
            for i, tel in enumerate(tels):
                # Print target alt/az
                stdscr.addstr(4, cw * (1+i), "{}".format(tal))
                stdscr.addstr(5, cw * (1+i), "{}".format(taz))
        elif target[0]=="GAL":
            glon = target[1]
            glat = target[2]
            stdscr.addstr(6, cw, "GALACTIC LON={}, LAT={}".format(glon, glat))
            for i, tel in enumerate(tels):
                # Calculate desired al/az from LON,LAT
                tal,taz = tel.get_desired_alaz(target)
                # Move telescope
                tel.move(tal, taz)
                # Show target alt/az
                stdscr.addstr(4, cw * (1+i), "{}".format(tal))
                stdscr.addstr(5, cw * (1+i), "{}".format(taz))
        elif target[0]=="SUN":
            stdscr.addstr(6, cw, "The Sun")
            for i, tel in enumerate(tels):
                # Calculate desired al/az for the Sun
                tal,taz = tel.get_desired_alaz(target)
                # Move telescope
                tel.move(tal, taz)
                # Show target alt/az
                stdscr.addstr(4, cw * (1+i), "{}".format(tal))
                stdscr.addstr(5, cw * (1+i), "{}".format(taz))

        # Handle user input
        try:
            key = stdscr.getkey().lower()
            if key=="s":
                # Stop all tels
                for i, tel in enumerate(tels):
                    tel.stop()
                target = ["", "", ""]
            elif key=="q":
                # Stop all tels
                for i, tel in enumerate(tels):
                    tel.stop()
                stdscr.clear()
                stdscr.refresh()
                loop = False
            elif key=="g" or key=="h" or key=="i":
                # Quit this loop to get new target from user
                stdscr.clear()
                stdscr.refresh()
                loop = False
        except:
            pass
        stdscr.refresh()
    curses.endwin()

    # Return user input to control loop
    return key

def control_loop(tels):
    # Enable curses loop
    cloop = True
    # Initialize target to empty string
    target = ["","",""]
    while cloop:
        # Run curses loop awaiting user input
        ans = curses_loop(tels, target)
        # We got user input, deal with it...
        if ans == "g":
            glon = float(input("Please enter target galactic longitude in decimal degrees e.g. 80.5 :"))
            glat = float(input("Please enter target galactic latitude in decimal degrees e.g. 0.0 :"))
            conf = input("Are you sure you want to track glon={} glat={} deg ? [Yes/No]".format(glon,glat))
            if conf.lower()=="yes":
                target = ["GAL", glon, glat]
                # Stop all tels
                for i, tel in enumerate(tels):
                    tel.stop()
                time.sleep(1.0)
                # Movement done by curses_loop in this case
        if ans == "h":
            az = float(input("Please enter target azimuth in decimal degrees e.g. 148.5 :"))
            al = float(input("Please enter target altitude in decimal degrees e.g. 43.5 :"))
            conf = input("Are you sure you want to track alt={} az={} deg ? [Yes/No]".format(al, az))
            if conf.lower()=="yes":
                target = ["HOR", al,az]
                # Stop all tels
                for i, tel in enumerate(tels):
                    tel.stop()
                time.sleep(1.0)
                # Move all telescopes, started here to simplify code (but yes, ugly place)
                for i, tel in enumerate(tels):
                    tel.move(al, az)
        if ans == "i":
            conf = input("Are you sure you want to track the Sun ? [Yes/No]")
            if conf.lower()=="yes":
                target = ["SUN", "", ""]
                # Stop all tels
                for i, tel in enumerate(tels):
                    tel.stop()
                time.sleep(1.0)
                # Movement done by curses_loop in this case
        elif ans == "q":
            # Quit program
            cloop = False

if __name__ == '__main__':
    # Assume list of config files given as script arguments on command line,
    # so we run "python3 script.py tel1.conf tel2.conf ..."
    # Each config file reflects a telescope to be controlled
    configs = sys.argv[1:]
    tels = []

    # Create one MD01 object for each config file (each telescope)
    for cf in configs:
        tels.append(MD01(cf))
    # Start control loop
    control_loop(tels)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    Copyright (C) 2019 Compassion CH (http://www.compassion.ch)
#    Releasing children from poverty in Jesus' name
#    @author: Nicolas Badoux <n.badoux@hotmail.com>
#
#    The licence is in the file __manifest__.py
#
##############################################################################
import logging
from openupgradelib import openupgrade

_logger = logging.getLogger(__name__)

@openupgrade.migrate(use_env=True)
def migrate(env, version):
    if not version:
        return

    partners = env['res.partner'].search_count(
            [('global_id', '!=', False),
             ('title.gender', '!=', False),
             ('title.name', 'not in', [
                 'Madam', 'Mister', 'Misters', 'Ladies'])])
    _logger.warning("Found %s partners to migrate gender on GMC. Don't forget "
                    "to call upsert_constituent method on those.", partners)
    # partners.upsert_constituent()
<commit_msg>FIX flake8<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    Copyright (C) 2019 Compassion CH (http://www.compassion.ch)
#    Releasing children from poverty in Jesus' name
#    @author: Nicolas Badoux <n.badoux@hotmail.com>
#
#    The licence is in the file __manifest__.py
#
##############################################################################
import logging
from openupgradelib import openupgrade

_logger = logging.getLogger(__name__)

@openupgrade.migrate(use_env=True)
def migrate(env, version):
    if not version:
        return

    partners = env['res.partner'].search_count([
        ('global_id', '!=', False),
        ('title.gender', '!=', False),
        ('title.name', 'not in', ['Madam', 'Mister', 'Misters', 'Ladies'])
    ])
    _logger.warning("Found %s partners to migrate gender on GMC. Don't forget "
                    "to call upsert_constituent method on those.", partners)
    # partners.upsert_constituent()
<|endoftext|>


<commit_before>import threading
from multiprocessing.connection import Client
try:
    import Queue as queue
except ImportError:
    import queue

__all__ = ["Adafruit_DotStar", ]

# // Method names are silly and inconsistent, but following NeoPixel
# // and prior libraries, which formed through centuries of accretion.

HOST = '127.0.0.1'
PORT = 6555

class DataThread(threading.Thread):
    def __init__(self):
        """
        Thread that manages multiproccessing Client to send data to the emulator app

        :return:
        """

        super(DataThread, self).__init__()
        self.host = HOST
        self.port = PORT

        self.running = True

        self.queue = queue.Queue()
        self.daemon = True

        self.connection = None

    def open_connection(self):
        """
        Open a connection to the specified port.

        :return: None
        """
        try:
            self.connection = Client((self.host, self.port))
        except:
            self.connection = None

    def run(self):
        while self.running:
            try:
                data = self.queue.get(timeout=0.01)
            except Queue.Empty:
                data = None

            if data:
                if not self.connection:
                    self.open_connection()

                if self.connection:
                    try:
                        self.connection.send(data)
                    except:
                        self.connection.close()
                        self.connection = None
                else:
                    # Don't let the queue buildup when a connection is not available. Just empty the
                    # queue
                    while not self.queue.empty():
                        self.queue.get(False)

    def stop(self):
        self.running = False

class Adafruit_DotStar(object):
    """
    // Allocate new DotStar object.  There's a few ways this can be called:
    // x = Adafruit_DotStar(nleds, datapin, clockpin)       Bitbang output
    // x = Adafruit_DotStar(nleds, bitrate)   Use hardware SPI @ bitrate
    // x = Adafruit_DotStar(nleds)            Hardware SPI @ default rate
    // x = Adafruit_DotStar()                 0 LEDs, HW SPI, default rate
    // 0 LEDs is valid, but one must then pass a properly-sized and -rendered
    // bytearray to the show() method.
    """

    # def __del__(self):
    #     print("Deleting")

    def __init__(self, *args):

        self._data_thread = DataThread()
        self._data_thread.start()

        self.numLEDs = None
        self.pixels = None
        self.brightness = 0

        # -------------------------------------
        # DotStar new
        args_count = len(args)

        # Argument count from dotstar.c DotStar_new object initialization

        # args_count == 3: Pixel count, data pin, clock pin
        # args_count == 2: Pixel count, hardware SPI bitrate
        # args_count == 1: Pixel count (hardware SPI w/default bitrate
        if args_count == 3 or args_count == 2 or args_count == 1:
            # disregard data_pin and clock pin, not needed in spoofer
            self.numLEDs = args[0]

        # args_count == 0: No LED bugger (raw writes only), default SPI bitrate
        elif args_count == 0:
            self.numLEDs = 0

        # args_count ERROR
        else:
            raise AttributeError("unexpected number of arguments")

        # Allocate buffer for pixels
        if self.numLEDs:
            self.pixels = bytearray(self.numLEDs * 4)

        # -------------------------------------
        # DotStar init
        for i in range(0, self.numLEDs * 4, 4):
            self.pixels[i] = 0xFF

    @staticmethod
    def begin():
        """
        // Initialize pins/SPI for output
        """

        # No need to do anything here, as we are not setting up and actual SPI information.

    def clear(self):
        """
        // Set strip data to 'off' (just clears buffer, does not write to strip)
        """
        for i in range(0, len(self.pixels), 4):
            self.pixels[i + 1] = 0x00
            self.pixels[i + 2] = 0x00
            self.pixels[i + 3] = 0x00

    def setBrightness(self, brightness):
        """
        // Set global strip brightness.  This does not have an immediate effect;
        // must be followed by a call to show().  Not a fan of this...for various
        // reasons I think it's better handled in one's application, but it's here
        // for parity with the Arduino NeoPixel library.
        """

        assert type(brightness) is int
        assert 0 <= brightness <= 255

        # // Stored brightness value is different than what's passed.  This
        # // optimizes the actual scaling math later, allowing a fast multiply
        # // and taking the MSB.  'brightness' is a uint8_t, adding 1 here may
        # // (intentionally) roll over...so 0 = max brightness (color values
        # // are interpreted literally; no scaling), 1 = min brightness (off),
        # // 255 = just below max brightness.
        self.brightness = brightness

    def setPixelColor(self, *args):
        """
        // Valid syntaxes:
        // x.setPixelColor(index, red, green, blue)
        // x.setPixelColor(index, 0x00RRGGBB)
        """

        args_count = len(args)

        # args_count == 4: Index, r, g, b
        if args_count == 4:
            i, r, g, b = args

        # args_count == 2: Index, value
        elif args_count == 2:
            i, v = args
            r = (v & 0x00FF0000) >> 16
            g = (v & 0x0000FF00) >> 8
            b = (v & 0x000000FF)

        # args_count ERROR
        else:
            raise AttributeError("unexpected number of arguments")

        if i < self.numLEDs:
            index = i * 4
            self.pixels[index + 1] = b
            self.pixels[index + 2] = g
            self.pixels[index + 3] = r

    def _raw_write(self, data):
        """
        // Private method.  Writes pixel data without brightness scaling.
        """
        out_buffer = bytearray()
        out_buffer += bytearray((0x00, 0x00, 0x00, 0x00))
        out_buffer += data

        if self.numLEDs:
            footerLen = (self.numLEDs + 15) / 16
        else:
            footerLen = ((len(data) / 4) + 15) / 16
        fBuf = bytearray()
        for i in range(footerLen):
            # This is different than AdaFruit library, which uses zero's in the xfer[2] spi_ioc_transfer struct.
            out_buffer.append(0xFF)

        self._data_thread.queue.put_nowait(out_buffer)
        # print(out_buffer)

    def X_raw_write(self, data):
        """
        // Private method.  Writes pixel data without brightness scaling.
        """

        self._data_thread.queue.put_nowait(bytearray((0x00, 0x00, 0x00, 0x00)))
        self._data_thread.queue.put_nowait(data)

        # self._data_thread.queue.put_nowait(bytearray((0xFF, 0xFF, 0xFF, 0xFF)))
        # if(self->numLEDs) xfer[2].len = (self->numLEDs + 15) / 16;
        # else              xfer[2].len = ((len / 4) + 15) / 16;

        if self.numLEDs:
            footerLen = (self.numLEDs + 15) / 16
        else:
            footerLen = ((len(data) / 4) + 15) / 16
        fBuf = bytearray()
        for i in range(footerLen):
            # This is different than AdaFruit library, which uses zero's in the xfer[2] spi_ioc_transfer struct.
            fBuf.append(0xFF)
        self._data_thread.queue.put_nowait(fBuf)
        # print(len(data), len(fBuf))

    def show(self, *args):
        """
        // Issue data to strip.  Optional arg = raw bytearray to issue to strip
        // (else object's pixel buffer is used).  If passing raw data, it must
        // be in strip-ready format (4 bytes/pixel, 0xFF/B/G/R) and no brightness
        // scaling is performed...it's all about speed (for POV, etc.)
        """
        if len(args) == 1:
            buf = args[0]
            self._raw_write(buf)
        else:
            scale = self.brightness

            if self.brightness == 0:  # // Send raw (no scaling)
                self._raw_write(bytearray(self.pixels))
            else:
                # // Scale from 'pixels' buffer into
                # // 'pBuf' (if available) and then
                # // use a single efficient write
                # // operation (thx Eric Bayer).
                pBuf = bytearray()
                for i in range(self.numLEDs):
                    index = i * 4
                    b = (self.pixels[index + 1] * scale) >> 8
                    g = (self.pixels[index + 2] * scale) >> 8
                    r = (self.pixels[index + 3] * scale) >> 8
                    pBuf.append(self.pixels[index])
                    pBuf.append(b)
                    pBuf.append(g)
                    pBuf.append(r)

                self._raw_write(pBuf)

    @staticmethod
    def Color(r, g, b):
        """
        // Given separate R, G, B, return a packed 32-bit color.
        // Meh, mostly here for parity w/Arduino library.
        """
        assert type(r) is int
        assert type(g) is int
        assert type(b) is int

        assert 0 <= r <= 255
        assert 0 <= g <= 255
        assert 0 <= b <= 255

        return r << 16 | g << 8 | b

    def getPixelColor(self, i):
        """
        // Return color of previously-set pixel (as packed 32-bit value)
        """
        if i < self.numLEDs:
            index = i * 4
            b = index + 1
            g = index + 2
            r = index + 3
            return self.Color(r, g, b)

    def numPixels(self):
        """
        // Return strip length
        """
        return self.numLEDs

    def getBrightness(self):
        """
        // Return strip brightness
        """
        # TODO I am not sure what the AdaFruit DotStar method is doing
        # Can't find documenation for "H". Need to see behaviour on RaspberryPi to fix
        # PyObject *result = Py_BuildValue("H", (uint8_t)(self->brightness - 1));
        return self.brightness

    def close(self):
        pass
<commit_msg>removed old method and cleaned up a commented out print statement<commit_after>import threading
from multiprocessing.connection import Client
try:
    import Queue as queue
except ImportError:
    import queue

__all__ = ["Adafruit_DotStar", ]

# // Method names are silly and inconsistent, but following NeoPixel
# // and prior libraries, which formed through centuries of accretion.

HOST = '127.0.0.1'
PORT = 6555

class DataThread(threading.Thread):
    def __init__(self):
        """
        Thread that manages multiproccessing Client to send data to the emulator app

        :return:
        """

        super(DataThread, self).__init__()
        self.host = HOST
        self.port = PORT

        self.running = True

        self.queue = queue.Queue()
        self.daemon = True

        self.connection = None

    def open_connection(self):
        """
        Open a connection to the specified port.

        :return: None
        """
        try:
            self.connection = Client((self.host, self.port))
        except:
            self.connection = None

    def run(self):
        while self.running:
            try:
                data = self.queue.get(timeout=0.01)
            except Queue.Empty:
                data = None

            if data:
                if not self.connection:
                    self.open_connection()

                if self.connection:
                    try:
                        self.connection.send(data)
                    except:
                        self.connection.close()
                        self.connection = None
                else:
                    # Don't let the queue buildup when a connection is not available. Just empty the
                    # queue
                    while not self.queue.empty():
                        self.queue.get(False)

    def stop(self):
        self.running = False

class Adafruit_DotStar(object):
    """
    // Allocate new DotStar object.  There's a few ways this can be called:
    // x = Adafruit_DotStar(nleds, datapin, clockpin)       Bitbang output
    // x = Adafruit_DotStar(nleds, bitrate)   Use hardware SPI @ bitrate
    // x = Adafruit_DotStar(nleds)            Hardware SPI @ default rate
    // x = Adafruit_DotStar()                 0 LEDs, HW SPI, default rate
    // 0 LEDs is valid, but one must then pass a properly-sized and -rendered
    // bytearray to the show() method.
    """

    # def __del__(self):
    #     print("Deleting")

    def __init__(self, *args):

        self._data_thread = DataThread()
        self._data_thread.start()

        self.numLEDs = None
        self.pixels = None
        self.brightness = 0

        # -------------------------------------
        # DotStar new
        args_count = len(args)

        # Argument count from dotstar.c DotStar_new object initialization

        # args_count == 3: Pixel count, data pin, clock pin
        # args_count == 2: Pixel count, hardware SPI bitrate
        # args_count == 1: Pixel count (hardware SPI w/default bitrate
        if args_count == 3 or args_count == 2 or args_count == 1:
            # disregard data_pin and clock pin, not needed in spoofer
            self.numLEDs = args[0]

        # args_count == 0: No LED bugger (raw writes only), default SPI bitrate
        elif args_count == 0:
            self.numLEDs = 0

        # args_count ERROR
        else:
            raise AttributeError("unexpected number of arguments")

        # Allocate buffer for pixels
        if self.numLEDs:
            self.pixels = bytearray(self.numLEDs * 4)

        # -------------------------------------
        # DotStar init
        for i in range(0, self.numLEDs * 4, 4):
            self.pixels[i] = 0xFF

    @staticmethod
    def begin():
        """
        // Initialize pins/SPI for output
        """

        # No need to do anything here, as we are not setting up and actual SPI information.

    def clear(self):
        """
        // Set strip data to 'off' (just clears buffer, does not write to strip)
        """
        for i in range(0, len(self.pixels), 4):
            self.pixels[i + 1] = 0x00
            self.pixels[i + 2] = 0x00
            self.pixels[i + 3] = 0x00

    def setBrightness(self, brightness):
        """
        // Set global strip brightness.  This does not have an immediate effect;
        // must be followed by a call to show().  Not a fan of this...for various
        // reasons I think it's better handled in one's application, but it's here
        // for parity with the Arduino NeoPixel library.
        """

        assert type(brightness) is int
        assert 0 <= brightness <= 255

        # // Stored brightness value is different than what's passed.  This
        # // optimizes the actual scaling math later, allowing a fast multiply
        # // and taking the MSB.  'brightness' is a uint8_t, adding 1 here may
        # // (intentionally) roll over...so 0 = max brightness (color values
        # // are interpreted literally; no scaling), 1 = min brightness (off),
        # // 255 = just below max brightness.
        self.brightness = brightness

    def setPixelColor(self, *args):
        """
        // Valid syntaxes:
        // x.setPixelColor(index, red, green, blue)
        // x.setPixelColor(index, 0x00RRGGBB)
        """

        args_count = len(args)

        # args_count == 4: Index, r, g, b
        if args_count == 4:
            i, r, g, b = args

        # args_count == 2: Index, value
        elif args_count == 2:
            i, v = args
            r = (v & 0x00FF0000) >> 16
            g = (v & 0x0000FF00) >> 8
            b = (v & 0x000000FF)

        # args_count ERROR
        else:
            raise AttributeError("unexpected number of arguments")

        if i < self.numLEDs:
            index = i * 4
            self.pixels[index + 1] = b
            self.pixels[index + 2] = g
            self.pixels[index + 3] = r

    def _raw_write(self, data):
        """
        // Private method.  Writes pixel data without brightness scaling.
        """
        out_buffer = bytearray()
        out_buffer += bytearray((0x00, 0x00, 0x00, 0x00))
        out_buffer += data

        if self.numLEDs:
            footerLen = (self.numLEDs + 15) / 16
        else:
            footerLen = ((len(data) / 4) + 15) / 16
        fBuf = bytearray()
        for i in range(footerLen):
            # This is different than AdaFruit library, which uses zero's in the xfer[2] spi_ioc_transfer struct.
            out_buffer.append(0xFF)

        self._data_thread.queue.put_nowait(out_buffer)

    def show(self, *args):
        """
        // Issue data to strip.  Optional arg = raw bytearray to issue to strip
        // (else object's pixel buffer is used).  If passing raw data, it must
        // be in strip-ready format (4 bytes/pixel, 0xFF/B/G/R) and no brightness
        // scaling is performed...it's all about speed (for POV, etc.)
        """
        if len(args) == 1:
            buf = args[0]
            self._raw_write(buf)
        else:
            scale = self.brightness

            if self.brightness == 0:  # // Send raw (no scaling)
                self._raw_write(bytearray(self.pixels))
            else:
                # // Scale from 'pixels' buffer into
                # // 'pBuf' (if available) and then
                # // use a single efficient write
                # // operation (thx Eric Bayer).
                pBuf = bytearray()
                for i in range(self.numLEDs):
                    index = i * 4
                    b = (self.pixels[index + 1] * scale) >> 8
                    g = (self.pixels[index + 2] * scale) >> 8
                    r = (self.pixels[index + 3] * scale) >> 8
                    pBuf.append(self.pixels[index])
                    pBuf.append(b)
                    pBuf.append(g)
                    pBuf.append(r)

                self._raw_write(pBuf)

    @staticmethod
    def Color(r, g, b):
        """
        // Given separate R, G, B, return a packed 32-bit color.
        // Meh, mostly here for parity w/Arduino library.
        """
        assert type(r) is int
        assert type(g) is int
        assert type(b) is int

        assert 0 <= r <= 255
        assert 0 <= g <= 255
        assert 0 <= b <= 255

        return r << 16 | g << 8 | b

    def getPixelColor(self, i):
        """
        // Return color of previously-set pixel (as packed 32-bit value)
        """
        if i < self.numLEDs:
            index = i * 4
            b = index + 1
            g = index + 2
            r = index + 3
            return self.Color(r, g, b)

    def numPixels(self):
        """
        // Return strip length
        """
        return self.numLEDs

    def getBrightness(self):
        """
        // Return strip brightness
        """
        # TODO I am not sure what the AdaFruit DotStar method is doing
        # Can't find documenation for "H". Need to see behaviour on RaspberryPi to fix
        # PyObject *result = Py_BuildValue("H", (uint8_t)(self->brightness - 1));
        return self.brightness

    def close(self):
        pass
<|endoftext|>


<commit_before># Copyright 2018 The TensorFlow Probability Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
"""Affine Scalar Tests."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

# Dependency imports
import numpy as np
import tensorflow as tf
import tensorflow_probability as tfp

from tensorflow_probability.python.bijectors import bijector_test_util

from tensorflow.python.framework import test_util  # pylint: disable=g-direct-tensorflow-import,g-import-not-at-top

tfb = tfp.bijectors

@test_util.run_all_in_graph_and_eager_modes
class AffineScalarBijectorTest(tf.test.TestCase):
  """Tests correctness of the Y = scale @ x + shift transformation."""

  def testProperties(self):
    mu = -1.
    # scale corresponds to 1.
    bijector = tfb.AffineScalar(shift=mu)
    self.assertStartsWith(bijector.name, "affine_scalar")

  def testNoBatchScalar(self):
    def static_run(fun, x, **kwargs):
      return self.evaluate(fun(x, **kwargs))

    def dynamic_run(fun, x_value, **kwargs):
      x_value = np.array(x_value, dtype=np.float32)
      x = tf.compat.v1.placeholder_with_default(x_value, shape=None)
      return self.evaluate(fun(x, **kwargs))

    for run in (static_run, dynamic_run):
      mu = -1.
      # Corresponds to scale = 2
      bijector = tfb.AffineScalar(shift=mu, scale=2.)
      x = [1., 2, 3]  # Three scalar samples (no batches).
      self.assertAllClose([1., 3, 5], run(bijector.forward, x))
      self.assertAllClose([1., 1.5, 2.], run(bijector.inverse, x))
      self.assertAllClose(
          -np.log(2.),
          run(bijector.inverse_log_det_jacobian, x, event_ndims=0))

  def testOneBatchScalarViaIdentityIn64BitUserProvidesShiftOnly(self):
    def static_run(fun, x, **kwargs):
      return self.evaluate(fun(x, **kwargs))

    def dynamic_run(fun, x_value, **kwargs):
      x_value = np.array(x_value, dtype=np.float64)
      x = tf.compat.v1.placeholder_with_default(x_value, shape=None)
      return self.evaluate(fun(x, **kwargs))

    for run in (static_run, dynamic_run):
      mu = np.float64([1.])
      # One batch, scalar.
      # Corresponds to scale = 1.
      bijector = tfb.AffineScalar(shift=mu)
      x = np.float64([1.])  # One sample from one batches.
      self.assertAllClose([2.], run(bijector.forward, x))
      self.assertAllClose([0.], run(bijector.inverse, x))
      self.assertAllClose(
          0.,
          run(bijector.inverse_log_det_jacobian, x, event_ndims=0))

  def testOneBatchScalarViaIdentityIn64BitUserProvidesScaleOnly(self):
    def static_run(fun, x, **kwargs):
      return self.evaluate(fun(x, **kwargs))

    def dynamic_run(fun, x_value, **kwargs):
      x_value = np.array(x_value)
      x = tf.compat.v1.placeholder_with_default(x_value, shape=None)
      return self.evaluate(fun(x, **kwargs))

    for run in (static_run, dynamic_run):
      multiplier = np.float64([2.])
      # One batch, scalar.
      # Corresponds to scale = 2, shift = 0.
      bijector = tfb.AffineScalar(scale=multiplier)
      x = np.float64([1.])  # One sample from one batches.
      self.assertAllClose([2.], run(bijector.forward, x))
      self.assertAllClose([0.5], run(bijector.inverse, x))
      self.assertAllClose(
          [np.log(0.5)],
          run(bijector.inverse_log_det_jacobian, x, event_ndims=0))

  def testTwoBatchScalarIdentityViaIdentity(self):
    def static_run(fun, x, **kwargs):
      return self.evaluate(fun(x, **kwargs))

    def dynamic_run(fun, x_value, **kwargs):
      x_value = np.array(x_value, dtype=np.float32)
      x = tf.compat.v1.placeholder_with_default(x_value, shape=None)
      return self.evaluate(fun(x, **kwargs))

    for run in (static_run, dynamic_run):
      mu = [1., -1]
      # Univariate, two batches.
      # Corresponds to scale = 1.
      bijector = tfb.AffineScalar(shift=mu)
      x = [1., 1]  # One sample from each of two batches.
      self.assertAllClose([2., 0], run(bijector.forward, x))
      self.assertAllClose([0., 2], run(bijector.inverse, x))
      self.assertAllClose(
          0.,
          run(bijector.inverse_log_det_jacobian, x, event_ndims=0))

  def testTwoBatchScalarIdentityViaScale(self):
    def static_run(fun, x, **kwargs):
      return self.evaluate(fun(x, **kwargs))

    def dynamic_run(fun, x_value, **kwargs):
      x_value = np.array(x_value, dtype=np.float32)
      x = tf.compat.v1.placeholder_with_default(x_value, shape=None)
      return self.evaluate(fun(x, **kwargs))

    for run in (static_run, dynamic_run):
      mu = [1., -1]
      # Univariate, two batches.
      # Corresponds to scale = 1.
      bijector = tfb.AffineScalar(shift=mu, scale=[2., 1])
      x = [1., 1]  # One sample from each of two batches.
      self.assertAllClose([3., 0], run(bijector.forward, x))
      self.assertAllClose([0., 2], run(bijector.inverse, x))
      self.assertAllClose(
          [-np.log(2), 0.],
          run(bijector.inverse_log_det_jacobian, x, event_ndims=0))

  def testScalarCongruency(self):
    bijector = tfb.AffineScalar(shift=3.6, scale=0.42)
    bijector_test_util.assert_scalar_congruency(
        bijector, lower_x=-2., upper_x=2., eval_func=self.evaluate)

if __name__ == "__main__":
  tf.test.main()
<commit_msg>Add explicit float32/float64 tests for AffineScalar bijector<commit_after># Copyright 2018 The TensorFlow Probability Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
"""Affine Scalar Tests."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

# Dependency imports
import numpy as np
import tensorflow as tf
import tensorflow_probability as tfp

from tensorflow_probability.python.bijectors import bijector_test_util

from tensorflow.python.framework import test_util  # pylint: disable=g-direct-tensorflow-import,g-import-not-at-top

tfb = tfp.bijectors

@test_util.run_all_in_graph_and_eager_modes
class _AffineScalarBijectorTest(object):
  """Tests correctness of the Y = scale @ x + shift transformation."""

  def testProperties(self):
    mu = -1.
    # scale corresponds to 1.
    bijector = tfb.AffineScalar(shift=mu)
    self.assertStartsWith(bijector.name, "affine_scalar")

  def testNoBatchScalar(self):
    def static_run(fun, x, **kwargs):
      return self.evaluate(fun(x, **kwargs))

    def dynamic_run(fun, x_value, **kwargs):
      x_value = np.array(x_value, dtype=self.dtype)
      x = tf.compat.v1.placeholder_with_default(x_value, shape=None)
      return self.evaluate(fun(x, **kwargs))

    for run in (static_run, dynamic_run):
      mu = -1.
      # Corresponds to scale = 2
      bijector = tfb.AffineScalar(shift=mu, scale=2.)
      x = [1., 2, 3]  # Three scalar samples (no batches).
      self.assertAllClose([1., 3, 5], run(bijector.forward, x))
      self.assertAllClose([1., 1.5, 2.], run(bijector.inverse, x))
      self.assertAllClose(
          -np.log(2.),
          run(bijector.inverse_log_det_jacobian, x, event_ndims=0))

  def testOneBatchScalarViaIdentityUserProvidesShiftOnly(self):
    def static_run(fun, x, **kwargs):
      return self.evaluate(fun(x, **kwargs))

    def dynamic_run(fun, x_value, **kwargs):
      x_value = np.array(x_value, dtype=self.dtype)
      x = tf.compat.v1.placeholder_with_default(x_value, shape=None)
      return self.evaluate(fun(x, **kwargs))

    for run in (static_run, dynamic_run):
      mu = self.dtype([1.])
      # One batch, scalar.
      # Corresponds to scale = 1.
      bijector = tfb.AffineScalar(shift=mu)
      x = self.dtype([1.])  # One sample from one batches.
      self.assertAllClose([2.], run(bijector.forward, x))
      self.assertAllClose([0.], run(bijector.inverse, x))
      self.assertAllClose(
          0.,
          run(bijector.inverse_log_det_jacobian, x, event_ndims=0))

  def testOneBatchScalarViaIdentityUserProvidesScaleOnly(self):
    def static_run(fun, x, **kwargs):
      return self.evaluate(fun(x, **kwargs))

    def dynamic_run(fun, x_value, **kwargs):
      x_value = np.array(x_value)
      x = tf.compat.v1.placeholder_with_default(x_value, shape=None)
      return self.evaluate(fun(x, **kwargs))

    for run in (static_run, dynamic_run):
      multiplier = self.dtype([2.])
      # One batch, scalar.
      # Corresponds to scale = 2, shift = 0.
      bijector = tfb.AffineScalar(scale=multiplier)
      x = self.dtype([1.])  # One sample from one batches.
      self.assertAllClose([2.], run(bijector.forward, x))
      self.assertAllClose([0.5], run(bijector.inverse, x))
      self.assertAllClose(
          [np.log(0.5)],
          run(bijector.inverse_log_det_jacobian, x, event_ndims=0))

  def testTwoBatchScalarIdentityViaIdentity(self):
    def static_run(fun, x, **kwargs):
      return self.evaluate(fun(x, **kwargs))

    def dynamic_run(fun, x_value, **kwargs):
      x_value = np.array(x_value, dtype=self.dtype)
      x = tf.compat.v1.placeholder_with_default(x_value, shape=None)
      return self.evaluate(fun(x, **kwargs))

    for run in (static_run, dynamic_run):
      mu = [1., -1]
      # Univariate, two batches.
      # Corresponds to scale = 1.
      bijector = tfb.AffineScalar(shift=mu)
      x = [1., 1]  # One sample from each of two batches.
      self.assertAllClose([2., 0], run(bijector.forward, x))
      self.assertAllClose([0., 2], run(bijector.inverse, x))
      self.assertAllClose(
          0.,
          run(bijector.inverse_log_det_jacobian, x, event_ndims=0))

  def testTwoBatchScalarIdentityViaScale(self):
    def static_run(fun, x, **kwargs):
      return self.evaluate(fun(x, **kwargs))

    def dynamic_run(fun, x_value, **kwargs):
      x_value = np.array(x_value, dtype=self.dtype)
      x = tf.compat.v1.placeholder_with_default(x_value, shape=None)
      return self.evaluate(fun(x, **kwargs))

    for run in (static_run, dynamic_run):
      mu = [1., -1]
      # Univariate, two batches.
      # Corresponds to scale = 1.
      bijector = tfb.AffineScalar(shift=mu, scale=[2., 1])
      x = [1., 1]  # One sample from each of two batches.
      self.assertAllClose([3., 0], run(bijector.forward, x))
      self.assertAllClose([0., 2], run(bijector.inverse, x))
      self.assertAllClose(
          [-np.log(2), 0.],
          run(bijector.inverse_log_det_jacobian, x, event_ndims=0))

  def testScalarCongruency(self):
    bijector = tfb.AffineScalar(shift=3.6, scale=0.42)
    bijector_test_util.assert_scalar_congruency(
        bijector, lower_x=-2., upper_x=2., eval_func=self.evaluate)

class AffineScalarBijectorTestFloat32(_AffineScalarBijectorTest):
  dtype = np.float32

class AffineScalarBijectorTestFloat64(_AffineScalarBijectorTest):
  dtype = np.float64

if __name__ == "__main__":
  tf.test.main()
<|endoftext|>