<commit_before>#!/usr/bin/env python
#-*- encoding: utf-8 -*-
#
# Copyright 2010-2012 Gerhard Lausser.
# This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

import sys
import os
import re
import inspect
import time
import logging
from jinja2 import FileSystemLoader, Environment, TemplateSyntaxError, TemplateNotFound
from jinja2_extensions import is_re_match, filter_re_sub, filter_re_escape, filter_service, filter_custom_macros
from item import Item
from application import Application
from hostgroup import Hostgroup
from monitoring_detail import MonitoringDetail
from datasource import Datasource, DatasourceCorrupt, DatasourceNotReady, DatasourceNotAvailable, DatasourceNotCurrent
from datarecipient import Datarecipient, DatarecipientCorrupt, DatarecipientNotReady, DatarecipientNotAvailable, DatarecipientNotCurrent
from util import compare_attr, substenv

logger = logging.getLogger('coshsh')

class EmptyObject(object):
    pass

class Recipe(object):

    def __del__(self):
        pass
        # sys.path is invisible here, so this will fail
        #self.unset_recipe_sys_path()

    def __init__(self, **kwargs):
        for key in kwargs.iterkeys():
            if isinstance(kwargs[key], basestring):
                kwargs[key] = re.sub('%.*?%', substenv, kwargs[key])
        self.name = kwargs["name"]
        self.force = kwargs.get("force")
        self.safe_output = kwargs.get("safe_output")
        logger.info("recipe %s init" % self.name)
        self.templates_dir = kwargs.get("templates_dir")
        self.classes_dir = kwargs.get("classes_dir")
        self.max_delta = kwargs.get("max_delta", ())
        if isinstance(self.max_delta, str):
            if ":" in self.max_delta:
                self.max_delta = tuple(map(int, self.max_delta.split(":")))
            else:
                self.max_delta = tuple(map(int, (self.max_delta, self.max_delta)))
        self.my_jinja2_extensions = kwargs.get("my_jinja2_extensions", None)

        self.classes_path = [os.path.join(os.path.dirname(__file__), '../recipes/default/classes')]
        if self.classes_dir:
            for path in reversed([p.strip() for p in self.classes_dir.split(',')]):
                self.classes_path.insert(0, path)
        self.set_recipe_sys_path()
        self.templates_path = [os.path.join(os.path.dirname(__file__), '../recipes/default/templates')]
        if self.templates_dir:
            for path in reversed([p.strip() for p in self.templates_dir.split(',')]):
                self.templates_path.insert(0, path)
            logger.debug("recipe.templates_path reloaded %s" % ':'.join(self.templates_path))
        logger.info("recipe %s classes_dir %s" % (self.name, ','.join([os.path.abspath(p) for p in self.classes_path])))
        logger.info("recipe %s templates_dir %s" % (self.name, ','.join([os.path.abspath(p) for p in self.templates_path])))

        self.jinja2 = EmptyObject()
        setattr(self.jinja2, 'loader', FileSystemLoader(self.templates_path))
        setattr(self.jinja2, 'env', Environment(loader=self.jinja2.loader))
        self.jinja2.env.trim_blocks = True
        self.jinja2.env.tests['re_match'] = is_re_match
        self.jinja2.env.filters['re_sub'] = filter_re_sub
        self.jinja2.env.filters['re_escape'] = filter_re_escape
        self.jinja2.env.filters['service'] = filter_service
        self.jinja2.env.filters['custom_macros'] = filter_custom_macros

        if self.my_jinja2_extensions:
            for extension in [e.strip() for e in self.my_jinja2_extensions.split(",")]:
                imported = getattr(__import__("my_jinja2_extensions", fromlist=[extension]), extension)
                if extension.startswith("is_"):
                    self.jinja2.env.tests[extension.replace("is_", "")] = imported
                elif extension.startswith("filter_"):
                    self.jinja2.env.filters[extension.replace("filter_", "")] = imported

        self.datasources = []
        self.datarecipients = []

        self.objects = {
            'hosts': {},
            'hostgroups': {},
            'applications': {},
            'appdetails': {},
            'contacts': {},
            'contactgroups': {},
            'commands': {},
            'timeperiods': {},
            'dependencies': {},
            'bps': {},
        }

        self.old_objects = (0, 0)
        self.new_objects = (0, 0)

        self.datasource_filters = {}
        self.filter = kwargs.get("filter")
        if kwargs.get("filter"):
            for rule in kwargs.get("filter").split(','):
                match = re.match(r'(\w+)\((.*)\)', rule)
                if match:
                    self.datasource_filters[match.groups()[0].lower()] = match.groups()[1]
        self.init_class_cache()

        if kwargs.get("datasources"):
            self.datasource_names = [ds.lower() for ds in kwargs.get("datasources").split(",")]
        else:
            self.datasource_names = []
        if kwargs.get("objects_dir") and not kwargs.get("datarecipients"):
            self.objects_dir = kwargs["objects_dir"]
            logger.info("recipe %s objects_dir %s" % (self.name, os.path.abspath(self.objects_dir)))
            self.datarecipient_names = ["datarecipient_coshsh_default"]
            self.add_datarecipient(**dict([('type', 'datarecipient_coshsh_default'), ('name', 'datarecipient_coshsh_default'), ('objects_dir', self.objects_dir), ('max_delta', self.max_delta), ('safe_output', self.safe_output)]))
        elif kwargs.get("objects_dir") and kwargs.get("datarecipients"):
            logger.warn("recipe %s delete parameter objects_dir (use datarecipients instead)" % (self.name, ))
            self.datarecipient_names = [ds.lower() for ds in kwargs.get("datarecipients").split(",")]
        else:
            self.datarecipient_names = [ds.lower() for ds in kwargs.get("datarecipients").split(",")]

    def set_recipe_sys_path(self):
        for p in [p for p in reversed(self.classes_path) if os.path.exists(p) and os.path.isdir(p)]:
            sys.path.insert(0, os.path.abspath(p))

    def unset_recipe_sys_path(self):
        for p in [p for p in self.classes_path if os.path.exists(p) and os.path.isdir(p)]:
            sys.path.pop(0)

    def collect(self):
        data_valid = True
        for ds in self.datasources:
            filter = self.datasource_filters.get(ds.name)
            try:
                ds.open()
                pre_count = dict([(key, len(self.objects[key].keys())) for key in self.objects.keys()])
                pre_detail_count = sum([(len(obj.monitoring_details) if hasattr(obj, 'monitoring_details') else 99) for objs in [self.objects[key].values() for key in self.objects.keys()] for obj in objs], 0)
                ds.read(filter=filter, objects=self.objects, force=self.force)
                post_count = dict([(key, len(self.objects[key].keys())) for key in self.objects.keys()])
                post_detail_count = sum([(len(obj.monitoring_details) if hasattr(obj, 'monitoring_details') else 99) for objs in [self.objects[key].values() for key in self.objects.keys()] for obj in objs], 0)
                pre_count['details'] = pre_detail_count
                post_count['details'] = post_detail_count
                pre_count.update(dict.fromkeys([k for k in post_count if not k in pre_count], 0))
                chg_keys = [(key, post_count[key] - pre_count[key]) for key in set(pre_count.keys() + post_count.keys()) if post_count[key] != pre_count[key]]
                logger.info("recipe %s read from datasource %s %s" % (self.name, ds.name, ", ".join(["%d %s" % (k[1], k[0]) for k in chg_keys])))

                ds.close()
            except DatasourceNotCurrent:
                data_valid = False
                logger.info("datasource %s is is not current" % ds.name)
            except DatasourceNotReady:
                data_valid = False
                logger.info("datasource %s is busy" % ds.name)
            except DatasourceNotAvailable:
                data_valid = False
                logger.info("datasource %s is not available" % ds.name)
            except Exception, exp:
                data_valid = False
                logger.critical("datasource %s returns bad data (%s)" % (ds.name, exp))
            if not data_valid:
                logger.info("aborting collection phase")
                return False

        for host in self.objects['hosts'].values():
            host.resolve_monitoring_details()
            host.create_templates()
            host.create_hostgroups()
            host.create_contacts()
            for hostgroup in host.hostgroups:
                try:
                    self.objects['hostgroups'][hostgroup].append(host.host_name)
                except Exception:
                    self.objects['hostgroups'][hostgroup] = []
                    self.objects['hostgroups'][hostgroup].append(host.host_name)

        orphaned_applications = []
        for app in self.objects['applications'].values():
            try:
                setattr(app, 'host', self.objects['hosts'][app.host_name])
                app.resolve_monitoring_details()
                app.create_templates()
                app.create_servicegroups()
                app.create_contacts()
            except KeyError:
                logger.info("application %s %s refers to non-existing host %s" % (app.name, app.type, app.host_name))
                orphaned_applications.append(app.fingerprint())
        for oa in orphaned_applications:
            del self.objects['applications'][oa]

        for (hostgroup_name, members) in self.objects['hostgroups'].items():
            logger.debug("creating hostgroup %s" % hostgroup_name)
            self.objects['hostgroups'][hostgroup_name] = Hostgroup({ "hostgroup_name" : hostgroup_name, "members" : members})
            self.objects['hostgroups'][hostgroup_name].create_templates()
            self.objects['hostgroups'][hostgroup_name].create_contacts()

        return True

    def render(self):
        template_cache = {}
        for host in self.objects['hosts'].values():
            host.render(template_cache, self.jinja2)
        for app in self.objects['applications'].values():
            # because of this __new__ construct the Item.searchpath is
            # not inherited. Needs to be done explicitely
            app.render(template_cache, self.jinja2)
        for cg in self.objects['contactgroups'].values():
            cg.render(template_cache, self.jinja2)
        for c in self.objects['contacts'].values():
            c.render(template_cache, self.jinja2)
        for hg in self.objects['hostgroups'].values():
            hg.render(template_cache, self.jinja2)

    def count_before_objects(self):
        for datarecipient in self.datarecipients:
            datarecipient.count_before_objects()
        self.old_objects = (sum([dr.old_objects[0] for dr in self.datarecipients], 0), sum([dr.old_objects[1] for dr in self.datarecipients], 0))

    def count_after_objects(self):
        for datarecipient in self.datarecipients:
            datarecipient.count_after_objects()
        self.new_objects = (sum(0, [dr.new_objects[0] for dr in self.datarecipients]), sum(0, [dr.new_objects[1] for dr in self.datarecipients]))

    def cleanup_target_dir(self):
        for datarecipient in self.datarecipients:
            datarecipient.cleanup_target_dir()

    def prepare_target_dir(self):
        for datarecipient in self.datarecipients:
            datarecipient.prepare_target_dir()

    def output(self):
        for datarecipient in self.datarecipients:
            datarecipient.count_before_objects()
            datarecipient.load(None, self.objects)
            datarecipient.cleanup_target_dir()
            datarecipient.prepare_target_dir()
            datarecipient.output()

    def read(self):
        return self.objects

    def init_class_cache(self):
        Datasource.init_classes(self.classes_path)
        logger.debug("init Datasource classes (%d)" % len(Datasource.class_factory))
        Datarecipient.init_classes(self.classes_path)
        logger.debug("init Datarecipient classes (%d)" % len(Datarecipient.class_factory))
        Application.init_classes(self.classes_path)
        logger.debug("init Application classes (%d)" % len(Application.class_factory))
        MonitoringDetail.init_classes(self.classes_path)
        logger.debug("init MonitoringDetail classes (%d)" % len(MonitoringDetail.class_factory))

    def add_datasource(self, **kwargs):
        for key in [k for k in kwargs.iterkeys() if isinstance(kwargs[k], str)]:
            kwargs[key] = re.sub('%.*?%', substenv, kwargs[key])
        newcls = Datasource.get_class(kwargs)
        if newcls:
            datasource = newcls(**kwargs)
            self.datasources.append(datasource)

    def add_datarecipient(self, **kwargs):
        for key in [k for k in kwargs.iterkeys() if isinstance(kwargs[k], str)]:
            kwargs[key] = re.sub('%.*?%', substenv, kwargs[key])
        newcls = Datarecipient.get_class(kwargs)
        if newcls:
            datarecipient = newcls(**kwargs)
            self.datarecipients.append(datarecipient)

<commit_msg>add do extension to jinja2<commit_after>#!/usr/bin/env python
#-*- encoding: utf-8 -*-
#
# Copyright 2010-2012 Gerhard Lausser.
# This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

import sys
import os
import re
import inspect
import time
import logging
from jinja2 import FileSystemLoader, Environment, TemplateSyntaxError, TemplateNotFound
from jinja2_extensions import is_re_match, filter_re_sub, filter_re_escape, filter_service, filter_custom_macros
from item import Item
from application import Application
from hostgroup import Hostgroup
from monitoring_detail import MonitoringDetail
from datasource import Datasource, DatasourceCorrupt, DatasourceNotReady, DatasourceNotAvailable, DatasourceNotCurrent
from datarecipient import Datarecipient, DatarecipientCorrupt, DatarecipientNotReady, DatarecipientNotAvailable, DatarecipientNotCurrent
from util import compare_attr, substenv

logger = logging.getLogger('coshsh')

class EmptyObject(object):
    pass

class Recipe(object):

    def __del__(self):
        pass
        # sys.path is invisible here, so this will fail
        #self.unset_recipe_sys_path()

    def __init__(self, **kwargs):
        for key in kwargs.iterkeys():
            if isinstance(kwargs[key], basestring):
                kwargs[key] = re.sub('%.*?%', substenv, kwargs[key])
        self.name = kwargs["name"]
        self.force = kwargs.get("force")
        self.safe_output = kwargs.get("safe_output")
        logger.info("recipe %s init" % self.name)
        self.templates_dir = kwargs.get("templates_dir")
        self.classes_dir = kwargs.get("classes_dir")
        self.max_delta = kwargs.get("max_delta", ())
        if isinstance(self.max_delta, str):
            if ":" in self.max_delta:
                self.max_delta = tuple(map(int, self.max_delta.split(":")))
            else:
                self.max_delta = tuple(map(int, (self.max_delta, self.max_delta)))
        self.my_jinja2_extensions = kwargs.get("my_jinja2_extensions", None)

        self.classes_path = [os.path.join(os.path.dirname(__file__), '../recipes/default/classes')]
        if self.classes_dir:
            for path in reversed([p.strip() for p in self.classes_dir.split(',')]):
                self.classes_path.insert(0, path)
        self.set_recipe_sys_path()
        self.templates_path = [os.path.join(os.path.dirname(__file__), '../recipes/default/templates')]
        if self.templates_dir:
            for path in reversed([p.strip() for p in self.templates_dir.split(',')]):
                self.templates_path.insert(0, path)
            logger.debug("recipe.templates_path reloaded %s" % ':'.join(self.templates_path))
        logger.info("recipe %s classes_dir %s" % (self.name, ','.join([os.path.abspath(p) for p in self.classes_path])))
        logger.info("recipe %s templates_dir %s" % (self.name, ','.join([os.path.abspath(p) for p in self.templates_path])))

        self.jinja2 = EmptyObject()
        setattr(self.jinja2, 'loader', FileSystemLoader(self.templates_path))
        setattr(self.jinja2, 'env', Environment(loader=self.jinja2.loader, extensions=['jinja2.ext.do']))
        self.jinja2.env.trim_blocks = True
        self.jinja2.env.tests['re_match'] = is_re_match
        self.jinja2.env.filters['re_sub'] = filter_re_sub
        self.jinja2.env.filters['re_escape'] = filter_re_escape
        self.jinja2.env.filters['service'] = filter_service
        self.jinja2.env.filters['custom_macros'] = filter_custom_macros

        if self.my_jinja2_extensions:
            for extension in [e.strip() for e in self.my_jinja2_extensions.split(",")]:
                imported = getattr(__import__("my_jinja2_extensions", fromlist=[extension]), extension)
                if extension.startswith("is_"):
                    self.jinja2.env.tests[extension.replace("is_", "")] = imported
                elif extension.startswith("filter_"):
                    self.jinja2.env.filters[extension.replace("filter_", "")] = imported

        self.datasources = []
        self.datarecipients = []

        self.objects = {
            'hosts': {},
            'hostgroups': {},
            'applications': {},
            'appdetails': {},
            'contacts': {},
            'contactgroups': {},
            'commands': {},
            'timeperiods': {},
            'dependencies': {},
            'bps': {},
        }

        self.old_objects = (0, 0)
        self.new_objects = (0, 0)

        self.datasource_filters = {}
        self.filter = kwargs.get("filter")
        if kwargs.get("filter"):
            for rule in kwargs.get("filter").split(','):
                match = re.match(r'(\w+)\((.*)\)', rule)
                if match:
                    self.datasource_filters[match.groups()[0].lower()] = match.groups()[1]
        self.init_class_cache()

        if kwargs.get("datasources"):
            self.datasource_names = [ds.lower() for ds in kwargs.get("datasources").split(",")]
        else:
            self.datasource_names = []
        if kwargs.get("objects_dir") and not kwargs.get("datarecipients"):
            self.objects_dir = kwargs["objects_dir"]
            logger.info("recipe %s objects_dir %s" % (self.name, os.path.abspath(self.objects_dir)))
            self.datarecipient_names = ["datarecipient_coshsh_default"]
            self.add_datarecipient(**dict([('type', 'datarecipient_coshsh_default'), ('name', 'datarecipient_coshsh_default'), ('objects_dir', self.objects_dir), ('max_delta', self.max_delta), ('safe_output', self.safe_output)]))
        elif kwargs.get("objects_dir") and kwargs.get("datarecipients"):
            logger.warn("recipe %s delete parameter objects_dir (use datarecipients instead)" % (self.name, ))
            self.datarecipient_names = [ds.lower() for ds in kwargs.get("datarecipients").split(",")]
        else:
            self.datarecipient_names = [ds.lower() for ds in kwargs.get("datarecipients").split(",")]

    def set_recipe_sys_path(self):
        for p in [p for p in reversed(self.classes_path) if os.path.exists(p) and os.path.isdir(p)]:
            sys.path.insert(0, os.path.abspath(p))

    def unset_recipe_sys_path(self):
        for p in [p for p in self.classes_path if os.path.exists(p) and os.path.isdir(p)]:
            sys.path.pop(0)

    def collect(self):
        data_valid = True
        for ds in self.datasources:
            filter = self.datasource_filters.get(ds.name)
            try:
                ds.open()
                pre_count = dict([(key, len(self.objects[key].keys())) for key in self.objects.keys()])
                pre_detail_count = sum([(len(obj.monitoring_details) if hasattr(obj, 'monitoring_details') else 99) for objs in [self.objects[key].values() for key in self.objects.keys()] for obj in objs], 0)
                ds.read(filter=filter, objects=self.objects, force=self.force)
                post_count = dict([(key, len(self.objects[key].keys())) for key in self.objects.keys()])
                post_detail_count = sum([(len(obj.monitoring_details) if hasattr(obj, 'monitoring_details') else 99) for objs in [self.objects[key].values() for key in self.objects.keys()] for obj in objs], 0)
                pre_count['details'] = pre_detail_count
                post_count['details'] = post_detail_count
                pre_count.update(dict.fromkeys([k for k in post_count if not k in pre_count], 0))
                chg_keys = [(key, post_count[key] - pre_count[key]) for key in set(pre_count.keys() + post_count.keys()) if post_count[key] != pre_count[key]]
                logger.info("recipe %s read from datasource %s %s" % (self.name, ds.name, ", ".join(["%d %s" % (k[1], k[0]) for k in chg_keys])))

                ds.close()
            except DatasourceNotCurrent:
                data_valid = False
                logger.info("datasource %s is is not current" % ds.name)
            except DatasourceNotReady:
                data_valid = False
                logger.info("datasource %s is busy" % ds.name)
            except DatasourceNotAvailable:
                data_valid = False
                logger.info("datasource %s is not available" % ds.name)
            except Exception, exp:
                data_valid = False
                logger.critical("datasource %s returns bad data (%s)" % (ds.name, exp))
            if not data_valid:
                logger.info("aborting collection phase")
                return False

        for host in self.objects['hosts'].values():
            host.resolve_monitoring_details()
            host.create_templates()
            host.create_hostgroups()
            host.create_contacts()
            for hostgroup in host.hostgroups:
                try:
                    self.objects['hostgroups'][hostgroup].append(host.host_name)
                except Exception:
                    self.objects['hostgroups'][hostgroup] = []
                    self.objects['hostgroups'][hostgroup].append(host.host_name)

        orphaned_applications = []
        for app in self.objects['applications'].values():
            try:
                setattr(app, 'host', self.objects['hosts'][app.host_name])
                app.resolve_monitoring_details()
                app.create_templates()
                app.create_servicegroups()
                app.create_contacts()
            except KeyError:
                logger.info("application %s %s refers to non-existing host %s" % (app.name, app.type, app.host_name))
                orphaned_applications.append(app.fingerprint())
        for oa in orphaned_applications:
            del self.objects['applications'][oa]

        for (hostgroup_name, members) in self.objects['hostgroups'].items():
            logger.debug("creating hostgroup %s" % hostgroup_name)
            self.objects['hostgroups'][hostgroup_name] = Hostgroup({ "hostgroup_name" : hostgroup_name, "members" : members})
            self.objects['hostgroups'][hostgroup_name].create_templates()
            self.objects['hostgroups'][hostgroup_name].create_contacts()

        return True

    def render(self):
        template_cache = {}
        for host in self.objects['hosts'].values():
            host.render(template_cache, self.jinja2)
        for app in self.objects['applications'].values():
            # because of this __new__ construct the Item.searchpath is
            # not inherited. Needs to be done explicitely
            app.render(template_cache, self.jinja2)
        for cg in self.objects['contactgroups'].values():
            cg.render(template_cache, self.jinja2)
        for c in self.objects['contacts'].values():
            c.render(template_cache, self.jinja2)
        for hg in self.objects['hostgroups'].values():
            hg.render(template_cache, self.jinja2)

    def count_before_objects(self):
        for datarecipient in self.datarecipients:
            datarecipient.count_before_objects()
        self.old_objects = (sum([dr.old_objects[0] for dr in self.datarecipients], 0), sum([dr.old_objects[1] for dr in self.datarecipients], 0))

    def count_after_objects(self):
        for datarecipient in self.datarecipients:
            datarecipient.count_after_objects()
        self.new_objects = (sum(0, [dr.new_objects[0] for dr in self.datarecipients]), sum(0, [dr.new_objects[1] for dr in self.datarecipients]))

    def cleanup_target_dir(self):
        for datarecipient in self.datarecipients:
            datarecipient.cleanup_target_dir()

    def prepare_target_dir(self):
        for datarecipient in self.datarecipients:
            datarecipient.prepare_target_dir()

    def output(self):
        for datarecipient in self.datarecipients:
            datarecipient.count_before_objects()
            datarecipient.load(None, self.objects)
            datarecipient.cleanup_target_dir()
            datarecipient.prepare_target_dir()
            datarecipient.output()

    def read(self):
        return self.objects

    def init_class_cache(self):
        Datasource.init_classes(self.classes_path)
        logger.debug("init Datasource classes (%d)" % len(Datasource.class_factory))
        Datarecipient.init_classes(self.classes_path)
        logger.debug("init Datarecipient classes (%d)" % len(Datarecipient.class_factory))
        Application.init_classes(self.classes_path)
        logger.debug("init Application classes (%d)" % len(Application.class_factory))
        MonitoringDetail.init_classes(self.classes_path)
        logger.debug("init MonitoringDetail classes (%d)" % len(MonitoringDetail.class_factory))

    def add_datasource(self, **kwargs):
        for key in [k for k in kwargs.iterkeys() if isinstance(kwargs[k], str)]:
            kwargs[key] = re.sub('%.*?%', substenv, kwargs[key])
        newcls = Datasource.get_class(kwargs)
        if newcls:
            datasource = newcls(**kwargs)
            self.datasources.append(datasource)

    def add_datarecipient(self, **kwargs):
        for key in [k for k in kwargs.iterkeys() if isinstance(kwargs[k], str)]:
            kwargs[key] = re.sub('%.*?%', substenv, kwargs[key])
        newcls = Datarecipient.get_class(kwargs)
        if newcls:
            datarecipient = newcls(**kwargs)
            self.datarecipients.append(datarecipient)

<|endoftext|>


<commit_before># Copyright (c) 2016-2018 Kirill 'Kolyat' Kiselnikov
# This file is the part of vpoker, released under modified MIT license
# See the file LICENSE.txt included in this distribution

"""Base engine for various poker types"""

# Card parameters
suit_list = ('S', 'C', 'H', 'D')
suits = {
    'S': '♠',  # Spades
    'C': '♣',  # Clubs
    'H': '♥',  # Hearts
    'D': '♦'   # Diamonds
}
ranks = ('2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A')

class RankOrBetter(object):
    """Abstract class that checks for winning combination in such poker type as
    'any rank or better' (e.g., 'Tens or Better')
    Method rank_or_better() is abstract and should be reimplemented
    """
    suits_flush = [['S']*5, ['C']*5, ['H']*5, ['D']*5]
    ranks_straight = [set(ranks[i:i+5]) for i in range(8)]

    def __init__(self):
        self.combo_analytical_functions = (
            self.royal_flush,
            self.straight_flush,
            self.four_of_a_kind,
            self.full_house,
            self.flush,
            self.straight,
            self.three_of_a_kind,
            self.two_pairs,
            self.rank_or_better
        )

    def __call__(self, card_suits, card_ranks):
        """Check for winning combination and return result if any

        :param card_suits: card suits
        :type card_suits: list
        :param card_ranks: card ranks
        :type card_ranks: list

        :return: winning combination
        :type: str

        :raise: TypeError: card_suit/card_rank is not a list
        :raise: ValueError: number of elements in a list is not equal to 5
        :raise: KeyError: current suit/rank does not exist
        """
        # Check for correct type
        if type(card_suits) != list:
            raise TypeError('Card suits must be a list')
        if type(card_ranks) != list:
            raise TypeError('Card ranks must be a list')
        # Check for list length
        if len(card_suits) != 5:
            raise ValueError('Number of elements in a list of card suits must'
                             'be equal to 5')
        if len(card_ranks) != 5:
            raise ValueError('Number of elements in a list of card ranks must'
                             'be equal to 5')
        # Check values in list
        for e in card_suits:
            if e not in suit_list:
                raise KeyError('Unknown card suit: ', e)
        for e in card_ranks:
            if e not in ranks:
                raise KeyError('Unknown card rank: ', e)
        # Init
        self.card_suits = card_suits
        self.card_ranks = card_ranks
        for fun in self.combo_analytical_functions:
            result = fun()
            if result:
                return result
        return ''

    def royal_flush(self):
        """Check for Royal Flush

        :return: 'Royal Flush'
        :type: str
        """
        if self.card_suits in self.suits_flush \
                and set(self.card_ranks) == {'10', 'J', 'Q', 'K', 'A'}:
            return 'Royal Flush'
        else:
            return ''

    def straight_flush(self):
        """Check for Straight Flush

        :return: 'Straight Flush'
        :type: str
        """
        if self.card_suits in self.suits_flush \
                and set(self.card_ranks) in self.ranks_straight:
            return 'Straight Flush'
        else:
            return ''

    def four_of_a_kind(self):
        """Check for Four of a Kind

        :return: 'Four of a Kind'
        :type: str
        """
        for rank in ranks:
            if self.card_ranks.count(rank) == 4:
                return 'Four of a Kind'
        return ''

    def full_house(self):
        """Check for Full House

        :return: 'Full House'
        :type: str
        """
        card_ranks_num = []
        for rank in ranks:
            card_ranks_num.append(self.card_ranks.count(rank))
        if {2, 3}.issubset(set(card_ranks_num)):
            return 'Full House'
        else:
            return ''

    def flush(self):
        """Check for Flush

        :return: 'Flush'
        :type: str
        """
        if self.card_suits in self.suits_flush:
            return 'Flush'
        else:
            return ''

    def straight(self):
        """Check for Straight

        :return: 'Straight'
        :type: str
        """
        if set(self.card_ranks) in self.ranks_straight:
            return 'Straight'
        else:
            return ''

    def three_of_a_kind(self):
        """Check for Three of a Kind

        :return: 'Three of a Kind'
        :type: str
        """
        for rank in ranks:
            if self.card_ranks.count(rank) == 3:
                return 'Three of a Kind'
        return ''

    def two_pairs(self):
        """Check for Two Pairs

        :return: 'Two Pairs'
        :type: str
        """
        card_ranks_num = []
        for rank in ranks:
            card_ranks_num.append(self.card_ranks.count(rank))
        card_ranks_num.sort()
        if card_ranks_num[-1] == 2 and card_ranks_num[-2] == 2:
            return 'Two Pairs'
        else:
            return ''

    def rank_or_better(self):
        """This method should be reimplemented and must return name of winning
        combo for pair of cards with the same rank
        """
        raise NotImplementedError('Method should be implemented')
<commit_msg>Minor change<commit_after># Copyright (c) 2016-2018 Kirill 'Kolyat' Kiselnikov
# This file is the part of vpoker, released under modified MIT license
# See the file LICENSE.txt included in this distribution

"""Base engine for various poker types"""

# Card parameters
suit_list = ('S', 'C', 'H', 'D')
suits = {
    'S': '♠',  # Spades
    'C': '♣',  # Clubs
    'H': '♥',  # Hearts
    'D': '♦'   # Diamonds
}
ranks = ('2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A')

class RankOrBetter(object):
    """Abstract class that checks for winning combination in such poker type as
    'any rank or better' (e.g., 'Tens or Better')
    Method rank_or_better() is abstract and should be reimplemented
    """
    suits_flush = [['S']*5, ['C']*5, ['H']*5, ['D']*5]
    ranks_straight = [set(ranks[i:i+5]) for i in range(8)]

    def __init__(self):
        self.analytical_sequence = (
            self.royal_flush,
            self.straight_flush,
            self.four_of_a_kind,
            self.full_house,
            self.flush,
            self.straight,
            self.three_of_a_kind,
            self.two_pairs,
            self.rank_or_better
        )

    def __call__(self, card_suits, card_ranks):
        """Check for winning combination and return result if any

        :param card_suits: card suits
        :type card_suits: list
        :param card_ranks: card ranks
        :type card_ranks: list

        :return: winning combination
        :type: str

        :raise: TypeError: card_suit/card_rank is not a list
        :raise: ValueError: number of elements in a list is not equal to 5
        :raise: KeyError: current suit/rank does not exist
        """
        # Check for correct type
        if type(card_suits) != list:
            raise TypeError('Card suits must be a list')
        if type(card_ranks) != list:
            raise TypeError('Card ranks must be a list')
        # Check for list length
        if len(card_suits) != 5:
            raise ValueError('Number of elements in a list of card suits must'
                             'be equal to 5')
        if len(card_ranks) != 5:
            raise ValueError('Number of elements in a list of card ranks must'
                             'be equal to 5')
        # Check values in list
        for e in card_suits:
            if e not in suit_list:
                raise KeyError('Unknown card suit: ', e)
        for e in card_ranks:
            if e not in ranks:
                raise KeyError('Unknown card rank: ', e)
        # Init
        self.card_suits = card_suits
        self.card_ranks = card_ranks
        for fun in self.analytical_sequence:
            result = fun()
            if result:
                return result
        return ''

    def royal_flush(self):
        """Check for Royal Flush

        :return: 'Royal Flush'
        :type: str
        """
        if self.card_suits in self.suits_flush \
                and set(self.card_ranks) == {'10', 'J', 'Q', 'K', 'A'}:
            return 'Royal Flush'
        else:
            return ''

    def straight_flush(self):
        """Check for Straight Flush

        :return: 'Straight Flush'
        :type: str
        """
        if self.card_suits in self.suits_flush \
                and set(self.card_ranks) in self.ranks_straight:
            return 'Straight Flush'
        else:
            return ''

    def four_of_a_kind(self):
        """Check for Four of a Kind

        :return: 'Four of a Kind'
        :type: str
        """
        for rank in ranks:
            if self.card_ranks.count(rank) == 4:
                return 'Four of a Kind'
        return ''

    def full_house(self):
        """Check for Full House

        :return: 'Full House'
        :type: str
        """
        card_ranks_num = []
        for rank in ranks:
            card_ranks_num.append(self.card_ranks.count(rank))
        if {2, 3}.issubset(set(card_ranks_num)):
            return 'Full House'
        else:
            return ''

    def flush(self):
        """Check for Flush

        :return: 'Flush'
        :type: str
        """
        if self.card_suits in self.suits_flush:
            return 'Flush'
        else:
            return ''

    def straight(self):
        """Check for Straight

        :return: 'Straight'
        :type: str
        """
        if set(self.card_ranks) in self.ranks_straight:
            return 'Straight'
        else:
            return ''

    def three_of_a_kind(self):
        """Check for Three of a Kind

        :return: 'Three of a Kind'
        :type: str
        """
        for rank in ranks:
            if self.card_ranks.count(rank) == 3:
                return 'Three of a Kind'
        return ''

    def two_pairs(self):
        """Check for Two Pairs

        :return: 'Two Pairs'
        :type: str
        """
        card_ranks_num = []
        for rank in ranks:
            card_ranks_num.append(self.card_ranks.count(rank))
        card_ranks_num.sort()
        if card_ranks_num[-1] == 2 and card_ranks_num[-2] == 2:
            return 'Two Pairs'
        else:
            return ''

    def rank_or_better(self):
        """This method should be reimplemented and must return name of winning
        combo for pair of cards with the same rank
        """
        raise NotImplementedError('Method should be implemented')
<|endoftext|>


<commit_before>Primality Test for ufunc.

 * Implement the while-loop

 * Use LLVM optimization passes?

    import math

    def is_prime(n):
        if n < 2:
            return False
        if n == 2:
            return True
        i = 2
        halfnum = int(math.ceil(math.sqrt(n)))
        while i <= halfnum:
            if n % i == 0:
                return False
            i += 1
        return True
<commit_msg>Removed unfinished example.<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env python

#--- selection of import based on the package ---
''' 1. with python3-serial'''
import serial
''' 2. without python3-serial'''
#from dummySerial import CDummySerial
#serial = CDummySerial()
#-----------------

'''

  - add read_fileModificationDate()
v0.12 2016 Mar. 7
  - impl proc_storage() to show storage usage
v0.11 2016 Mar. 7
  - impl proc_get()
      + return received strings to appened to [rcvd.txt]
      + get sender name
v0.10 2016 Mar. 3
  - add comm_get() in progress
  - update comm_hello() to take [mySrl(Serial)] parameter
  - update comm_check()
v0.9 2016 Mar. 2
  - add trim_mySerial()
  - add read_mySerial()
v0.8 2016 Mar. 1
  - add Test_extractCsvRow()
  - add extractCsvRow()
  - add comm_check()
  - add append_rcvdtext()
v0.7 2016 Feb. 29
  - add comm_bye()
  - add comm_hello()
v0.6 2016 Feb. 29
  - add comm_post()
  - add read_sendtext()
v0.5 2016 Feb. 29
  - add read_name()
  - add debug_outputDebugString()
v0.4 2016 Feb. 24
  - add contact by Vital
v0.3 2016 Feb. 24
  - group_run commands
      + hello
      + check
      + get
      + post
v0.2 2016 Feb. 24
  - add serial print
v0.1 2016 Feb. 24
  - just hello
'''

import time
import os.path
usleep = lambda x: time.sleep(x/1000000.0)

con1 = serial.Serial('/dev/ttyAMA0', 115200, timeout=0.1)

cmdlines = [
    "hello,1,7of9",
    "check",
    "get",
    "post,Vital,hello_Vital,0",
    "hello,2,Vital",
    "check",
    "get",
    "post,7of9,hello_7of9,0"
    ]

def debug_outputDebugString(prfx, msg):
    print "[DEBUG]" + prfx + "," + msg

def read_fileModificationDate_sendText():
    srcpath="/home/pi/BYOP/send.txt"
    mddt = time.ctime(os.path.getmtime(srcpath))
    parsed = time.strptime(mddt)
    yyyymmdd = time.strftime("%Y%m%d", parsed)
    return yyyymmdd

def read_sendtext():
#    debug_outputDebugString("read_sendtext","Line52 > start")
    srcpath="/home/pi/BYOP/send.txt"

    if os.path.isfile(srcpath) == False:
#        debug_outputDebugString("read_sendtext","Line55 > send.txt not found");
        return
    rdfd = open(srcpath)
    lines = rdfd.readlines()
    rdfd.close()

#    debug_outputDebugString("read_sendtext","Line80 > lines:" + str(lines))

    return lines

def read_name():
#    debug_outputDebugString("read_name","Line49 > start")
    srcpath="/home/pi/BYOP/name.txt"

    if os.path.isfile(srcpath) == False:
        debug_outputDebugString("read_name","Line53 > name.txt not found");
        return
    with open(srcpath,"r") as nmfd:
        mynm = nmfd.read()
#        debug_outputDebugString("read_name","Line63 > name:" + mynm)
    return mynm

def append_rcvdtext(appends):
#    debug_outputDebugString("append_rcvdtext","Line82 > start")
    srcpath="/home/pi/BYOP/rcvd.txt"

    debug_outputDebugString("append_rcvdtext","Line85 > " + appends)

    orglines = ""
    if os.path.isfile(srcpath):
        rdfd = open(srcpath)
        orglines = rdfd.readlines()
        rdfd.close()

    wrfd = open(srcpath, "w")
    wrfd.writelines(orglines)
    wrfd.writelines(appends)
    wrfd.close()

#    debug_outputDebugString("append_rcvdtext","Line101 > fin")

def read_mySerial():
#    debug_outputDebugString("read_mySerial","Line105 > start")
    srcpath="/proc/cpuinfo"
    if os.path.isfile(srcpath) == False:
        debug_outputDebugString("read_mySerial","Line107 > no cpuinfo")
        return
    rdfd = open(srcpath)
    lines = rdfd.readlines()
    rdfd.close()
    mySerial = ""
    for line in lines:
        if "Serial" in line:
            items = line.split(" ")
            mySerial = items[1]
#            print line
    return mySerial

def trim_mySerial(mySrl):
    # use only three in order not to disclose information related to security
    return mySrl[13:-1]

def comm_post(sends, dstcom):
    for line in sends:
        if "//" in line:
            continue
        msg="post," + line
        print msg,
        dstcom.write(msg)
        rcvd = dstcom.readline()
        time.sleep(5.0) # second

def comm_check(dstcom):
#    debug_outputDebugString("comm_check","Line112 > start")
    cmd="check\n"
    dstcom.write(cmd)
    rcvd = dstcom.readline()
    debug_outputDebugString("comm_check","Line119 >" + rcvd)
    if len(rcvd) == 0:
        return 0
    nummsg = extractCsvRow(rcvd, 1) # rcvd:[check,3\n]
    time.sleep(5.0) # second
    return int(nummsg)

def comm_storage(dstcom):
    cmd="storage\n"
    dstcom.write(cmd)
    rcvd = dstcom.readline()
    debug_outputDebugString("comm_storage","Line164 >" + rcvd)
    if len(rcvd) == 0:
        return

def comm_get(nummsg, dstcom):
#    debug_outputDebugString("comm_get","Line152 > start")
    retstr = ""
    for loop in range(nummsg):
        cmd = "get\n"
        dstcom.write(cmd)
        time.sleep(2.0) #second (for message station to show [sender] on LCD)

        rcvd = dstcom.readline()
        rcvd = rcvd.rstrip() # to remove <LF>
        if len(rcvd) == 0:
            continue
        sndr = extractCsvRow(rcvd, 1)
        msg = extractCsvRow(rcvd, 2)
        scrt = extractCsvRow(rcvd, 3)
#        debug_outputDebugString("comm_get","Line166 > sender:" + sndr)
#        debug_outputDebugString("comm_get","Line167 > message:" + msg)
#        debug_outputDebugString("comm_get","Line168 > secret:" + scrt)
        time.sleep(5.0) # second

        # TODO: 0c > add timestamp of the message post
        retstr = retstr + sndr + "," + msg + "," + scrt + "\n"
    return retstr

def comm_hello(name, mySrl, dstcom):
    msg="hello," + mySrl + "," + name
    debug_outputDebugString("comm_hello",msg)
    dstcom.write(msg)
    rcvd = dstcom.readline() # TODO: 0m > check when ESP8266 is not connected
    time.sleep(5.0) # second

def comm_bye(dstcom):
    msg="bye\n"
    debug_outputDebugString("comm_bye",msg)
    print msg
    dstcom.write(msg)
    rcvd = dstcom.readline()
    time.sleep(5.0) # second

def extractCsvRow(csvline, getIdx):
    lines = csvline.split(",")
    if getIdx >= len(lines):
        return ""
    return lines[getIdx]

def Test_extractCsvRow():
    csvline="AAA,BBB,CCC"
    print extractCsvRow(csvline, 0)
    print extractCsvRow(csvline, 2)
    print extractCsvRow(csvline, 4)

def main():
#    Test_extractCsvRow()

    # read serial
    mySerial = read_mySerial()
    mySerial = trim_mySerial(mySerial)
#    debug_outputDebugString("main","Line175 > Serial:" + mySerial)

    # hello
    myname = read_name()
    comm_hello(myname, mySerial, con1)

    # check number of messages to receive
    nummsg = comm_check(con1)
#    debug_outputDebugString("main","Line194 > check:" + str(nummsg))

    # get message
    tomsg = comm_get(nummsg, con1)
    debug_outputDebugString("main","Line225 > comm_get:" + tomsg)
    append_rcvdtext(tomsg)

    # post message
    sends = read_sendtext()
    modiDate = read_fileModificationDate_sendText()
    debug_outputDebugString("main","Line255 > modiDate:" + modiDate)
    comm_post(sends,con1)

    # if 1
    nummsg = comm_check(con1)

    # TODO: 0m > add proc_storage()

    # bye
    comm_bye(con1)

    # check storage
    comm_storage(con1)

'''
    for idx in range (8):
        msg = cmdlines[idx] + "\n"
        print msg,
        con1.write(msg)
        time.sleep(5.0); # second
'''

if __name__ == '__main__':
    main()
    con1.close()
<commit_msg>comm_post() takes [modiDate] arg<commit_after>#!/usr/bin/env python

#--- selection of import based on the package ---
''' 1. with python3-serial'''
import serial
''' 2. without python3-serial'''
#from dummySerial import CDummySerial
#serial = CDummySerial()
#-----------------

'''
v0.13 2016 Mar. 10
  - add string_removeCRLF()
  - comm_post() takes [modiDate] arg
  - add read_fileModificationDate()
v0.12 2016 Mar. 7
  - impl proc_storage() to show storage usage
v0.11 2016 Mar. 7
  - impl proc_get()
      + return received strings to appened to [rcvd.txt]
      + get sender name
v0.10 2016 Mar. 3
  - add comm_get() in progress
  - update comm_hello() to take [mySrl(Serial)] parameter
  - update comm_check()
v0.9 2016 Mar. 2
  - add trim_mySerial()
  - add read_mySerial()
v0.8 2016 Mar. 1
  - add Test_extractCsvRow()
  - add extractCsvRow()
  - add comm_check()
  - add append_rcvdtext()
v0.7 2016 Feb. 29
  - add comm_bye()
  - add comm_hello()
v0.6 2016 Feb. 29
  - add comm_post()
  - add read_sendtext()
v0.5 2016 Feb. 29
  - add read_name()
  - add debug_outputDebugString()
v0.4 2016 Feb. 24
  - add contact by Vital
v0.3 2016 Feb. 24
  - group_run commands
      + hello
      + check
      + get
      + post
v0.2 2016 Feb. 24
  - add serial print
v0.1 2016 Feb. 24
  - just hello
'''

import time
import os.path
usleep = lambda x: time.sleep(x/1000000.0)

con1 = serial.Serial('/dev/ttyAMA0', 115200, timeout=0.1)

cmdlines = [
    "hello,1,7of9",
    "check",
    "get",
    "post,Vital,hello_Vital,0",
    "hello,2,Vital",
    "check",
    "get",
    "post,7of9,hello_7of9,0"
    ]

def debug_outputDebugString(prfx, msg):
    print "[DEBUG]" + prfx + "," + msg

def string_removeCRLF(srcstr):
    return srcstr.rstrip()

def read_fileModificationDate_sendText():
    srcpath="/home/pi/BYOP/send.txt"
    mddt = time.ctime(os.path.getmtime(srcpath))
    parsed = time.strptime(mddt)
    yyyymmdd = time.strftime("%Y%m%d", parsed)
    return yyyymmdd

def read_sendtext():
#    debug_outputDebugString("read_sendtext","Line52 > start")
    srcpath="/home/pi/BYOP/send.txt"

    if os.path.isfile(srcpath) == False:
#        debug_outputDebugString("read_sendtext","Line55 > send.txt not found");
        return
    rdfd = open(srcpath)
    lines = rdfd.readlines()
    rdfd.close()

#    debug_outputDebugString("read_sendtext","Line80 > lines:" + str(lines))

    return lines

def read_name():
#    debug_outputDebugString("read_name","Line49 > start")
    srcpath="/home/pi/BYOP/name.txt"

    if os.path.isfile(srcpath) == False:
        debug_outputDebugString("read_name","Line53 > name.txt not found");
        return
    with open(srcpath,"r") as nmfd:
        mynm = nmfd.read()
#        debug_outputDebugString("read_name","Line63 > name:" + mynm)
    return mynm

def append_rcvdtext(appends):
#    debug_outputDebugString("append_rcvdtext","Line82 > start")
    srcpath="/home/pi/BYOP/rcvd.txt"

    debug_outputDebugString("append_rcvdtext","Line85 > " + appends)

    orglines = ""
    if os.path.isfile(srcpath):
        rdfd = open(srcpath)
        orglines = rdfd.readlines()
        rdfd.close()

    wrfd = open(srcpath, "w")
    wrfd.writelines(orglines)
    wrfd.writelines(appends)
    wrfd.close()

#    debug_outputDebugString("append_rcvdtext","Line101 > fin")

def read_mySerial():
#    debug_outputDebugString("read_mySerial","Line105 > start")
    srcpath="/proc/cpuinfo"
    if os.path.isfile(srcpath) == False:
        debug_outputDebugString("read_mySerial","Line107 > no cpuinfo")
        return
    rdfd = open(srcpath)
    lines = rdfd.readlines()
    rdfd.close()
    mySerial = ""
    for line in lines:
        if "Serial" in line:
            items = line.split(" ")
            mySerial = items[1]
#            print line
    return mySerial

def trim_mySerial(mySrl):
    # use only three in order not to disclose information related to security
    return mySrl[13:-1]

def comm_post(sends, modiDate, dstcom):
    for line in sends:
        if "//" in line:
            continue
        line = string_removeCRLF(line)
        msg = "post," + line
        msg = msg + "," + modiDate + "\n"
        print msg,
        dstcom.write(msg)
        rcvd = dstcom.readline()
        time.sleep(5.0) # second

def comm_check(dstcom):
#    debug_outputDebugString("comm_check","Line112 > start")
    cmd="check\n"
    dstcom.write(cmd)
    rcvd = dstcom.readline()
    debug_outputDebugString("comm_check","Line119 >" + rcvd)
    if len(rcvd) == 0:
        return 0
    nummsg = extractCsvRow(rcvd, 1) # rcvd:[check,3\n]
    time.sleep(5.0) # second
    return int(nummsg)

def comm_storage(dstcom):
    cmd="storage\n"
    dstcom.write(cmd)
    rcvd = dstcom.readline()
    debug_outputDebugString("comm_storage","Line164 >" + rcvd)
    if len(rcvd) == 0:
        return

def comm_get(nummsg, dstcom):
#    debug_outputDebugString("comm_get","Line152 > start")
    retstr = ""
    for loop in range(nummsg):
        cmd = "get\n"
        dstcom.write(cmd)
        time.sleep(2.0) #second (for message station to show [sender] on LCD)

        rcvd = dstcom.readline()
        rcvd = rcvd.rstrip() # to remove <LF>
        if len(rcvd) == 0:
            continue
        sndr = extractCsvRow(rcvd, 1)
        msg = extractCsvRow(rcvd, 2)
        scrt = extractCsvRow(rcvd, 3)
#        debug_outputDebugString("comm_get","Line166 > sender:" + sndr)
#        debug_outputDebugString("comm_get","Line167 > message:" + msg)
#        debug_outputDebugString("comm_get","Line168 > secret:" + scrt)
        time.sleep(5.0) # second

        # TODO: 0c > add timestamp of the message post
        retstr = retstr + sndr + "," + msg + "," + scrt + "\n"
    return retstr

def comm_hello(name, mySrl, dstcom):
    msg="hello," + mySrl + "," + name
    debug_outputDebugString("comm_hello",msg)
    dstcom.write(msg)
    rcvd = dstcom.readline() # TODO: 0m > check when ESP8266 is not connected
    time.sleep(5.0) # second

def comm_bye(dstcom):
    msg="bye\n"
    debug_outputDebugString("comm_bye",msg)
    print msg
    dstcom.write(msg)
    rcvd = dstcom.readline()
    time.sleep(5.0) # second

def extractCsvRow(csvline, getIdx):
    lines = csvline.split(",")
    if getIdx >= len(lines):
        return ""
    return lines[getIdx]

def Test_extractCsvRow():
    csvline="AAA,BBB,CCC"
    print extractCsvRow(csvline, 0)
    print extractCsvRow(csvline, 2)
    print extractCsvRow(csvline, 4)

def main():
#    Test_extractCsvRow()

    # read serial
    mySerial = read_mySerial()
    mySerial = trim_mySerial(mySerial)
#    debug_outputDebugString("main","Line175 > Serial:" + mySerial)

    # hello
    myname = read_name()
    comm_hello(myname, mySerial, con1)

    # check number of messages to receive
    nummsg = comm_check(con1)
#    debug_outputDebugString("main","Line194 > check:" + str(nummsg))

    # get message
    tomsg = comm_get(nummsg, con1)
    debug_outputDebugString("main","Line225 > comm_get:" + tomsg)
    append_rcvdtext(tomsg)

    # post message
    sends = read_sendtext()
    modiDate = read_fileModificationDate_sendText()
    debug_outputDebugString("main","Line255 > modiDate:" + modiDate)
    comm_post(sends, modiDate, con1)

    # if 1
    nummsg = comm_check(con1)

    # TODO: 0m > add proc_storage()

    # bye
    comm_bye(con1)

    # check storage
    comm_storage(con1)

'''
    for idx in range (8):
        msg = cmdlines[idx] + "\n"
        print msg,
        con1.write(msg)
        time.sleep(5.0); # second
'''

if __name__ == '__main__':
    main()
    con1.close()
<|endoftext|>


<commit_before>import csv
import numpy as np
import datetime
import matplotlib.pyplot as plt

metacols = 3
color_scheme = ['#00B2A5', '#D9661F', '#00B0DA', '#FDB515', '#ED4E33',
                '#2D637F', '#9DAD33', '#53626F', '#EE1F60', '#6C3302',
                '#C2B9A7', '#CFDD45', '#003262']
color_map = {'k40': 8, 'bi214': 5, 'tl208': 7, 'cs137': 10, 'cs134': 9}
isotope_key = ['k40', 'bi214', 'tl208', 'cs137', 'cs134']
color_scheme = np.asarray([color_scheme[color_map[key]]
                           for key in isotope_key])

def parse_time(date):
    """
    parse_time formats the date given into the format month-day-year.
    """
    if ('-' in date):
        return ''
    date_list = date.split('/')
    return_list = []
    for item in date_list:
        return_list.append(int(item))
    return datetime.datetime(year=2000+return_list[2], month=return_list[0],
                             day=return_list[1])

def unique_sample_names(sample_names):
    """
    unique_sample_names takes a given list of sample names and returns a list
    of all the unique names in the list
    """
    ret = []
    for name in sample_names:
        if name not in ret:
            ret.append(name)
    return ret

def combine_measurements(sample_array, sample_names,
                         sample_dates):
    """
    combine_measurements acquires all the samples with the same name and
    their corresponding information and combines it into one sample
    that's representative of the group. It returns sample information that
    contains the name of the sample group, the average of the group data and
    uncertainty, and the dates of the three most recent samples.
    """
    u_sample_names = unique_sample_names(sample_names)
    u_sample_array = []
    u_sample_names_ret = []
    for u_name in u_sample_names:
        lst = []
        row = 0
        u_sample_dates = []
        for name in sample_names:
            if(u_name == name):
                lst.append(sample_array[row, :])
                if sample_dates[row] == '':
                    continue
                u_sample_dates.append(sample_dates[row])
            row += 1

        u_sample_dates = np.sort(u_sample_dates)
        if len(u_sample_dates):
            u_sample_dates_ = ' ('+str(len(u_sample_dates))+')'
        else:
            u_sample_dates_ = ' ('+str(1)+')'

        for date in u_sample_dates[-3:]:
            u_sample_dates_ += "\n"+date.strftime('%m-%d-%y')
        lst = np.asarray(lst)
        # Perform sample group averaging with uncertainty standardization
        k40avg = []
        k40unc = []
        bi214avg = []
        bi214unc = []
        tl208avg = []
        tl208unc = []
        cs137avg = []
        cs137unc = []
        cs134avg = []
        cs134unc = []
        sample_summary = []
        for measure in lst:
            if measure[0] <= measure[1]:
                k40avg.append(0)
            else:
                k40avg.append(measure[0])
            k40unc.append(measure[1]**2)
            if measure[2] <= measure[3]:
                bi214avg.append(0)
            else:
                bi214avg.append(measure[2])
            bi214unc.append(measure[3]**2)
            if measure[4] <= measure[5]:
                tl208avg.append(0)
            else:
                tl208avg.append(measure[4])
            tl208unc.append(measure[5]**2)
            if measure[6] <= measure[7]:
                cs137avg.append(0)
            else:
                cs137avg.append(measure[6])
            cs137unc.append(measure[7]**2)
            if measure[8] <= measure[9]:
                cs134avg.append(0)
            else:
                cs134avg.append(measure[8])
            cs134unc.append(measure[9]**2)

        sample_summary.extend([np.mean(k40avg),
                               np.sqrt(sum(k40unc)) / len(k40unc)])
        sample_summary.extend([np.mean(bi214avg),
                               np.sqrt(sum(bi214unc)) / len(bi214unc)])
        sample_summary.extend([np.mean(tl208avg),
                               np.sqrt(sum(tl208unc)) / len(tl208unc)])
        sample_summary.extend([np.mean(cs137avg),
                               np.sqrt(sum(cs137unc)) / len(cs137unc)])
        sample_summary.extend([np.mean(cs134avg),
                               np.sqrt(sum(cs134unc)) / len(cs134unc)])
        u_sample_array.append(sample_summary)
        u_sample_names_ret.append(u_name + u_sample_dates_)

    return np.asarray(u_sample_array), u_sample_names_ret

def create_barerror_plot(csv_file, title, log=True):
    """
    create_barerror_plot reads a csv file and takes a title input and prepares
    the information from the csv file for generating a bar plot. This
    preparation includes cleaning the sample names of the UCB title and simply
    showing the sample type.
    """
    sample_list = []
    name_list = []
    date_list = []
    header = []
    with open(csv_file) as csvfile:
        parser = csv.reader(csvfile)
        header = parser.__next__()
        dictparser = csv.DictReader(csvfile, header)
        for row in dictparser:
            tmp_list = []
            if 'recal' in row[header[0]]:
                # Remove recal from name
                label = str(row[header[0]][7:-6])
            else:
                label = str(row[header[0]][7:])
            name_list.append(label)
            date_list.append(parse_time(row[header[1]]))
            for ind in range(metacols, 2 * len(isotope_key) + 2, 2):
                    tmp_list.extend([float(row[header[ind]]),
                                     float(row[header[ind+1]])])
            sample_list.append(tmp_list)
    sample_list = np.asarray(sample_list)
    legend_key = []
    sample_list, name_list = combine_measurements(sample_array=sample_list,
                                                  sample_names=name_list,
                                                  sample_dates=date_list)
    data = np.zeros((len(name_list), int(sample_list.shape[1] / 2.)))
    error = np.zeros((len(name_list), int(sample_list.shape[1] / 2.)))
    loop = 0
    # Create data and error lists for simple bar graph assembly
    for item in range(0, sample_list.shape[1], 2):
        legend_key.append(header[metacols + item])
        data[:, loop] = sample_list[:, item]
        error[:, loop] = sample_list[:, item + 1]
        loop += 1
    ax, fig = generate_barerror_logy(sample_names=name_list, data=data,
                                     error=error, legend_key=legend_key,
                                     title=title, log=log)

def generate_barerror_logy(sample_names, data, error, legend_key, title,
                           log=True):
    """
    generate_barerror_logy generates a bar graph with error bars. Bars are
    are generated on a log plot with arrows indicating a detection limit and
    bars representing a concentration value.
    """
    number_samples = len(sample_names)
    index = np.arange(0.5, number_samples, dtype=np.float64)
    width = float(0.15)
    fig, ax = plt.subplots()

    axis = []
    mins = np.amin(data[np.nonzero(data)])
    for sample in range(0, len(legend_key)):
        error_color = []
        for i in range(len(data[:, sample])):
            # Determine whether to present a bar or detection limit
            if data[:, sample][i] <= error[:, sample][i]:
                data[:, sample][i] = 0
                error_color.append(color_scheme[sample])
            else:
                error_color.append('black')
        args = np.zeros((0))
        left_edge = index + float(width) * float(sample)
        if np.amin(data[:, sample]) == 0:
            args = np.where(data[:, sample] == 0)
            data[args, sample] += 1E-4
            draw_arrows(axes=ax, xlocs=(left_edge + 0.5 * float(width))[args],
                        ylocs=error[args, sample], color=color_scheme[sample])
        for pos, val, err, color in zip(left_edge, data[:, sample],
                                        error[:, sample], error_color):
            ax.errorbar(pos + 0.075, val, err, color=color)
        axis.append(ax.bar(left=left_edge, height=tuple(data[:, sample]),
                    width=width, color=color_scheme[sample],
                    edgecolor="none", log=log))
    ylims = ax.get_ylim()
    upper_mult = 1
    if log:
        upper_mult = 10
    ax.set_ylim([mins / 10, upper_mult * ylims[1]])
    ax.set_xticks(index + float(len(legend_key)) / 2. * width)
    ax.set_xticklabels(sample_names)
    ax.tick_params(axis='x', color='w')
    ax.legend([a[0] for a in axis], legend_key, loc='upper left')
    ax.annotate('', xy=(0.88, 0.8999), xycoords='axes fraction',
                xytext=(0.88, 0.9), textcoords='axes fraction',
                arrowprops=dict(edgecolor='k', facecolor='k',
                arrowstyle='-|>'))
    ax.annotate('Detection Limit', xy=(0.888, 0.905), xytext=(0.888, 0.905),
                textcoords='axes fraction', ha='left', va='center')
    ax.set_title(title, fontsize=20)
    ax.set_ylabel('Specific Activity' + legend_key[0].split(' ')[1],
                  fontsize=20)
    plt.gcf().subplots_adjust(bottom=0.15, left=0.05, right=0.95)
    plt.show()
    return ax, fig

def draw_arrows(axes, xlocs, ylocs, color):
    """
    draw_arrows places arrow hats for measurement detection limits to
    distinguish them from regular error bars.
    """
    num_els = len(xlocs)
    if num_els == 0:
        return
    if len(ylocs.shape) > 1:
        ylocs = np.squeeze(ylocs, axis=(0,))
    for index in range(0, num_els):
        dy = 1e-10
        axes.annotate("", xy=(xlocs[index], ylocs[index] - dy),
                      xycoords='data', xytext=(xlocs[index], ylocs[index]),
                      textcoords='data', arrowprops=dict(edgecolor=color,
                      facecolor=color, arrowstyle="-|>"))
    return

create_barerror_plot('Sampling_Table.csv', 'Sample Summary')
<commit_msg>Adjusted Graph Font Sizes<commit_after>import csv
import numpy as np
import datetime
import matplotlib.pyplot as plt

metacols = 3
color_scheme = ['#00B2A5', '#D9661F', '#00B0DA', '#FDB515', '#ED4E33',
                '#2D637F', '#9DAD33', '#53626F', '#EE1F60', '#6C3302',
                '#C2B9A7', '#CFDD45', '#003262']
color_map = {'k40': 8, 'bi214': 5, 'tl208': 7, 'cs137': 10, 'cs134': 9}
isotope_key = ['k40', 'bi214', 'tl208', 'cs137', 'cs134']
color_scheme = np.asarray([color_scheme[color_map[key]]
                           for key in isotope_key])

def parse_time(date):
    """
    parse_time formats the date given into the format month-day-year.
    """
    if ('-' in date):
        return ''
    date_list = date.split('/')
    return_list = []
    for item in date_list:
        return_list.append(int(item))
    return datetime.datetime(year=2000+return_list[2], month=return_list[0],
                             day=return_list[1])

def unique_sample_names(sample_names):
    """
    unique_sample_names takes a given list of sample names and returns a list
    of all the unique names in the list
    """
    ret = []
    for name in sample_names:
        if name not in ret:
            ret.append(name)
    return ret

def combine_measurements(sample_array, sample_names,
                         sample_dates):
    """
    combine_measurements acquires all the samples with the same name and
    their corresponding information and combines it into one sample
    that's representative of the group. It returns sample information that
    contains the name of the sample group, the average of the group data and
    uncertainty, and the dates of the three most recent samples.
    """
    u_sample_names = unique_sample_names(sample_names)
    u_sample_array = []
    u_sample_names_ret = []
    for u_name in u_sample_names:
        lst = []
        row = 0
        u_sample_dates = []
        for name in sample_names:
            if(u_name == name):
                lst.append(sample_array[row, :])
                if sample_dates[row] == '':
                    continue
                u_sample_dates.append(sample_dates[row])
            row += 1

        u_sample_dates = np.sort(u_sample_dates)
        if len(u_sample_dates):
            u_sample_dates_ = ' ('+str(len(u_sample_dates))+')'
        else:
            u_sample_dates_ = ' ('+str(1)+')'

        for date in u_sample_dates[-3:]:
            u_sample_dates_ += "\n"+date.strftime('%m-%d-%y')
        lst = np.asarray(lst)
        # Perform sample group averaging with uncertainty standardization
        k40avg = []
        k40unc = []
        bi214avg = []
        bi214unc = []
        tl208avg = []
        tl208unc = []
        cs137avg = []
        cs137unc = []
        cs134avg = []
        cs134unc = []
        sample_summary = []
        for measure in lst:
            if measure[0] <= measure[1]:
                k40avg.append(0)
            else:
                k40avg.append(measure[0])
            k40unc.append(measure[1]**2)
            if measure[2] <= measure[3]:
                bi214avg.append(0)
            else:
                bi214avg.append(measure[2])
            bi214unc.append(measure[3]**2)
            if measure[4] <= measure[5]:
                tl208avg.append(0)
            else:
                tl208avg.append(measure[4])
            tl208unc.append(measure[5]**2)
            if measure[6] <= measure[7]:
                cs137avg.append(0)
            else:
                cs137avg.append(measure[6])
            cs137unc.append(measure[7]**2)
            if measure[8] <= measure[9]:
                cs134avg.append(0)
            else:
                cs134avg.append(measure[8])
            cs134unc.append(measure[9]**2)

        sample_summary.extend([np.mean(k40avg),
                               np.sqrt(sum(k40unc)) / len(k40unc)])
        sample_summary.extend([np.mean(bi214avg),
                               np.sqrt(sum(bi214unc)) / len(bi214unc)])
        sample_summary.extend([np.mean(tl208avg),
                               np.sqrt(sum(tl208unc)) / len(tl208unc)])
        sample_summary.extend([np.mean(cs137avg),
                               np.sqrt(sum(cs137unc)) / len(cs137unc)])
        sample_summary.extend([np.mean(cs134avg),
                               np.sqrt(sum(cs134unc)) / len(cs134unc)])
        u_sample_array.append(sample_summary)
        u_sample_names_ret.append(u_name + u_sample_dates_)

    return np.asarray(u_sample_array), u_sample_names_ret

def create_barerror_plot(csv_file, title, log=True):
    """
    create_barerror_plot reads a csv file and takes a title input and prepares
    the information from the csv file for generating a bar plot. This
    preparation includes cleaning the sample names of the UCB title and simply
    showing the sample type.
    """
    sample_list = []
    name_list = []
    date_list = []
    header = []
    with open(csv_file) as csvfile:
        parser = csv.reader(csvfile)
        header = parser.__next__()
        dictparser = csv.DictReader(csvfile, header)
        for row in dictparser:
            tmp_list = []
            if 'recal' in row[header[0]]:
                # Remove recal from name
                label = str(row[header[0]][7:-6])
            else:
                label = str(row[header[0]][7:])
            name_list.append(label)
            date_list.append(parse_time(row[header[1]]))
            for ind in range(metacols, 2 * len(isotope_key) + 2, 2):
                    tmp_list.extend([float(row[header[ind]]),
                                     float(row[header[ind+1]])])
            sample_list.append(tmp_list)
    sample_list = np.asarray(sample_list)
    legend_key = []
    sample_list, name_list = combine_measurements(sample_array=sample_list,
                                                  sample_names=name_list,
                                                  sample_dates=date_list)
    data = np.zeros((len(name_list), int(sample_list.shape[1] / 2.)))
    error = np.zeros((len(name_list), int(sample_list.shape[1] / 2.)))
    loop = 0
    # Create data and error lists for simple bar graph assembly
    for item in range(0, sample_list.shape[1], 2):
        legend_key.append(header[metacols + item])
        data[:, loop] = sample_list[:, item]
        error[:, loop] = sample_list[:, item + 1]
        loop += 1
    ax, fig = generate_barerror_logy(sample_names=name_list, data=data,
                                     error=error, legend_key=legend_key,
                                     title=title, log=log)

def generate_barerror_logy(sample_names, data, error, legend_key, title,
                           log=True):
    """
    generate_barerror_logy generates a bar graph with error bars. Bars are
    are generated on a log plot with arrows indicating a detection limit and
    bars representing a concentration value.
    """
    number_samples = len(sample_names)
    index = np.arange(0.5, number_samples, dtype=np.float64)
    width = float(0.15)
    fig, ax = plt.subplots()

    axis = []
    mins = np.amin(data[np.nonzero(data)])
    for sample in range(0, len(legend_key)):
        error_color = []
        for i in range(len(data[:, sample])):
            # Determine whether to present a bar or detection limit
            if data[:, sample][i] <= error[:, sample][i]:
                data[:, sample][i] = 0
                error_color.append(color_scheme[sample])
            else:
                error_color.append('black')
        args = np.zeros((0))
        left_edge = index + float(width) * float(sample)
        if np.amin(data[:, sample]) == 0:
            args = np.where(data[:, sample] == 0)
            data[args, sample] += 1E-4
            draw_arrows(axes=ax, xlocs=(left_edge + 0.5 * float(width))[args],
                        ylocs=error[args, sample], color=color_scheme[sample])
        for pos, val, err, color in zip(left_edge, data[:, sample],
                                        error[:, sample], error_color):
            ax.errorbar(pos + 0.075, val, err, color=color)
        axis.append(ax.bar(left=left_edge, height=tuple(data[:, sample]),
                    width=width, color=color_scheme[sample],
                    edgecolor="none", log=log))
    ylims = ax.get_ylim()
    upper_mult = 1
    if log:
        upper_mult = 10
    ax.set_ylim([mins / 10, upper_mult * ylims[1]])
    ax.set_xticks(index + float(len(legend_key)) / 2. * width)
    ax.yaxis.set_tick_params(labelsize=18)
    ax.set_xticklabels(sample_names, fontsize=18)
    ax.tick_params(axis='x', color='w')
    ax.legend([a[0] for a in axis], legend_key, loc='upper left')
    ax.annotate('', xy=(0.88, 0.8999), xycoords='axes fraction',
                xytext=(0.88, 0.9), textcoords='axes fraction',
                arrowprops=dict(edgecolor='k', facecolor='k',
                arrowstyle='-|>'))
    ax.annotate('Detection Limit', xy=(0.888, 0.905), xytext=(0.888, 0.905),
                textcoords='axes fraction', ha='left', va='center')
    ax.set_title(title, fontsize=30)
    ax.set_ylabel('Specific Activity' + legend_key[0].split(' ')[1],
                  fontsize=30)
    plt.gcf().subplots_adjust(bottom=0.15, left=0.05, right=0.95)
    plt.show()
    return ax, fig

def draw_arrows(axes, xlocs, ylocs, color):
    """
    draw_arrows places arrow hats for measurement detection limits to
    distinguish them from regular error bars.
    """
    num_els = len(xlocs)
    if num_els == 0:
        return
    if len(ylocs.shape) > 1:
        ylocs = np.squeeze(ylocs, axis=(0,))
    for index in range(0, num_els):
        dy = 1e-10
        axes.annotate("", xy=(xlocs[index], ylocs[index] - dy),
                      xycoords='data', xytext=(xlocs[index], ylocs[index]),
                      textcoords='data', arrowprops=dict(edgecolor=color,
                      facecolor=color, arrowstyle="-|>"))
    return

create_barerror_plot('Sampling_Table.csv', 'Sample Summary')
<|endoftext|>


<commit_before>import unittest
from feature_extraction.post_processing.regex.regex_entity_extraction import EntityExtraction
import regex as re

class RegexPostLogicTest(unittest.TestCase):
    def test_match_fail(self):
        text = "I am a super saiyan"
        EntityExtraction.regex_bin = {
            'MONEY_REGEX': r"(\d+(\s|,)){1,4}(\s\$|\$)"
        }
        regex_array = [
            re.compile(
                r"\[[123]\]" + r".+" + r"(demand|réclam)(ait|e|ent|aient)" + r" la résiliation du bail",
                re.IGNORECASE
            ),
            re.compile(
                r"\[[123]\]" + r".+une demande en résiliation de bail",
                re.IGNORECASE
            )
        ]
        regex_type = 'BOOLEAN'
        result = EntityExtraction.match_any_regex(text, regex_array, regex_type)
        self.assertFalse(result[0])
        self.assertEqual(result[1], 0)

    def test_match_money(self):
        text = "[3] word locateur 50 $ dommages-intérêts"
        EntityExtraction.regex_bin = {
            'MONEY_REGEX': r"(\d+(\s|,)){1,4}(\s\$|\$)"
        }
        regex_array = [
            re.compile(
                r"\[[123]\]" + r".+" + r"locat(eur|rice)(s)?" +
                r".*" + r"(\d+(\s|,)){1,4}(\s\$|\$)" + r".*dommages-intérêts",
                re.IGNORECASE
            )]
        regex_type = 'MONEY_REGEX'
        result = EntityExtraction.match_any_regex(text, regex_array, regex_type)
        self.assertTrue(result[0])
        self.assertEqual(int(result[1]), 50)

    def test_match_boolean(self):
        text = "[3] une demande en résiliation de bail"
        EntityExtraction.regex_bin = {
            'MONEY_REGEX': r"(\d+(\s|,)){1,4}(\s\$|\$)"
        }
        regex_array = [
            re.compile(
                r"\[[123]\]" + r".+" + r"(demand|réclam)(ait|e|ent|aient)" + r" la résiliation du bail",
                re.IGNORECASE
            ),
            re.compile(
                r"\[[123]\]" + r".+une demande en résiliation de bail",
                re.IGNORECASE
            )
        ]
        regex_type = 'BOOLEAN'
        result = EntityExtraction.match_any_regex(text, regex_array, regex_type)
        self.assertTrue(result[0])
        self.assertEqual(result[1], 1)

    def test_match_date(self):
        text = "[3]l'indemnité additionnelle prévue à l'article 1619 C.c.Q., à compter du 9ème octobre 2014. random text"
        regex_array = [
            re.compile(
                r"l'indemnité additionnelle prévue à l'article 1619 C\.c\.Q\., à compter du \K(?i)\d{1,2}(er|èr|ere|em|eme|ème)? \w{3,9} \d{4}",
                re.IGNORECASE
            )
        ]
        regex_type = 'DATE_REGEX'
        result = EntityExtraction.match_any_regex(text, regex_array, regex_type)
        self.assertTrue(result[0])
        self.assertEqual(result[1], 1412812800.0)

<commit_msg>[#251] fixed test<commit_after>import unittest
from feature_extraction.post_processing.regex.regex_entity_extraction import EntityExtraction
import regex as re

class RegexPostLogicTest(unittest.TestCase):
    def test_match_fail(self):
        text = "I am a super saiyan"
        EntityExtraction.regex_bin = {
            'MONEY_REGEX': r"(\d+(\s|,)){1,4}(\s\$|\$)"
        }
        regex_array = [
            re.compile(
                r"\[[123]\]" + r".+" + r"(demand|réclam)(ait|e|ent|aient)" + r" la résiliation du bail",
                re.IGNORECASE
            ),
            re.compile(
                r"\[[123]\]" + r".+une demande en résiliation de bail",
                re.IGNORECASE
            )
        ]
        regex_type = 'BOOLEAN'
        result = EntityExtraction.match_any_regex(text, regex_array, regex_type)
        self.assertFalse(result[0])
        self.assertEqual(result[1], 0)

    def test_match_money(self):
        text = "[3] word locateur 50 $ dommages-intérêts"
        EntityExtraction.regex_bin = {
            'MONEY_REGEX': r"(\d+(\s|,)){1,4}(\s\$|\$)"
        }
        regex_array = [
            re.compile(
                r"\[[123]\]" + r".+" + r"locat(eur|rice)(s)?" +
                r".*" + r"(\d+(\s|,)){1,4}(\s\$|\$)" + r".*dommages-intérêts",
                re.IGNORECASE
            )]
        regex_type = 'MONEY_REGEX'
        result = EntityExtraction.match_any_regex(text, regex_array, regex_type)
        self.assertTrue(result[0])
        self.assertEqual(int(result[1]), 50)

    def test_match_boolean(self):
        text = "[3] une demande en résiliation de bail"
        EntityExtraction.regex_bin = {
            'MONEY_REGEX': r"(\d+(\s|,)){1,4}(\s\$|\$)"
        }
        regex_array = [
            re.compile(
                r"\[[123]\]" + r".+" + r"(demand|réclam)(ait|e|ent|aient)" + r" la résiliation du bail",
                re.IGNORECASE
            ),
            re.compile(
                r"\[[123]\]" + r".+une demande en résiliation de bail",
                re.IGNORECASE
            )
        ]
        regex_type = 'BOOLEAN'
        result = EntityExtraction.match_any_regex(text, regex_array, regex_type)
        self.assertTrue(result[0])
        self.assertEqual(result[1], 1)

    def test_match_date(self):
        text = "[3]l'indemnité additionnelle prévue à l'article 1619 C.c.Q., à compter du 9èr octobre 2014. random text"
        regex_array = [
            re.compile(
                r"l'indemnité additionnelle prévue à l'article 1619 C\.c\.Q\., à compter du \K(?i)\d{1,2}(er|èr|ere|em|eme|ème)? \w{3,9} \d{4}",
                re.IGNORECASE
            )
        ]
        regex_type = 'DATE_REGEX'
        result = EntityExtraction.match_any_regex(text, regex_array, regex_type)
        self.assertTrue(result[0])
        self.assertEqual(result[1], 1412812800.0)

<|endoftext|>


<commit_before>#
#	dp for Tornado
#		YoungYong Park (youngyongpark@gmail.com)
#		2014.10.23
#

from .singleton import Singleton

class View(object, metaclass=Singleton):
    @staticmethod
    def render(controller, template_name, kwargs=None):
        if kwargs:
            controller.parent.render(template_name, **kwargs)
        else:
            controller.parent.render(template_name)

    @staticmethod
    def render_string(controller, template_name, kwargs=None):
        if kwargs:
            return controller.parent.render_string(template_name, **kwargs)
        else:
            return controller.parent.render_string(template_name)

    @staticmethod
    def write(controller, chunk):
        controller.parent.write(chunk)

    @staticmethod
    def finish(controller, chunk=None):
        controller.parent.finish(chunk)<commit_msg>Encode UTF-8 string from unicode object.<commit_after>#
#	dp for Tornado
#		YoungYong Park (youngyongpark@gmail.com)
#		2014.10.23
#

from .singleton import Singleton

class View(object, metaclass=Singleton):
    @staticmethod
    def render(controller, template_name, kwargs=None):
        if kwargs:
            controller.parent.render(template_name, **kwargs)
        else:
            controller.parent.render(template_name)

    @staticmethod
    def render_string(controller, template_name, kwargs=None):
        if kwargs:
            return str(controller.parent.render_string(template_name, **kwargs), 'UTF-8')
        else:
            return str(controller.parent.render_string(template_name), 'UTF-8')

    @staticmethod
    def write(controller, chunk):
        controller.parent.write(chunk)

    @staticmethod
    def finish(controller, chunk=None):
        controller.parent.finish(chunk)<|endoftext|>