from datetime import date, datetime

from django.http import HttpRequest, QueryDict
from django.test import SimpleTestCase, TestCase
from django.utils.http import urlencode

from dimagi.utils.dates import DateSpan

from corehq.apps.locations.tests.util import LocationHierarchyTestCase
from corehq.apps.locations.util import (
    load_locs_json,
    location_hierarchy_config,
)
from corehq.apps.reports_core.exceptions import FilterValueException
from corehq.apps.reports_core.filters import (
    REQUEST_USER_KEY,
    Choice,
    ChoiceListFilter,
    DatespanFilter,
    DynamicChoiceListFilter,
    LocationDrilldownFilter,
    NumericFilter,
    PreFilter,
)
from corehq.apps.userreports.datatypes import (
    DATA_TYPE_DATE,
    DATA_TYPE_DATETIME,
)
from corehq.apps.userreports.exceptions import BadSpecError
from corehq.apps.userreports.models import (
    DataSourceConfiguration,
    ReportConfiguration,
)
from corehq.apps.userreports.reports.filters.factory import ReportFilterFactory
from corehq.apps.userreports.reports.filters.specs import create_filter_value
from corehq.apps.userreports.reports.filters.values import (
    SHOW_ALL_CHOICE,
    DateFilterValue,
    LocationDrilldownFilterValue,
    NumericFilterValue,
    PreFilterValue,
)
from corehq.apps.userreports.reports.view import (
    ConfigurableReportView,
    query_dict_to_dict,
)
from corehq.apps.userreports.tasks import rebuild_indicators
from corehq.apps.userreports.tests.test_view import ConfigurableReportTestMixin
from corehq.apps.userreports.util import get_indicator_adapter
from corehq.apps.users.models import CommCareUser

class FilterTestCase(SimpleTestCase):

    def test_no_type(self):
        with self.assertRaises(BadSpecError):
            ReportFilterFactory.from_spec({
                "field": "some_field",
                "slug": "some_slug",
                "display": "Some display name"
            })

    def test_bad_type(self):
        with self.assertRaises(BadSpecError):
            ReportFilterFactory.from_spec({
                "type": "invalid_type",
                "field": "some_field",
                "slug": "some_slug",
                "display": "Some display name"
            })

    def test_missing_field(self):
        with self.assertRaises(BadSpecError):
            ReportFilterFactory.from_spec({
                "type": "date",
                "slug": "some_slug",
                "display": "Some display name"
            })

    def test_missing_slug(self):
        with self.assertRaises(BadSpecError):
            ReportFilterFactory.from_spec({
                "type": "date",
                "field": "some_field",
                "display": "Some display name"
            })

    def test_translation(self):
        shared_conf = {
            "type": "date",
            "field": "some_field",
            "slug": "some_slug",
        }

        # Plain string
        conf = {"display": "foo"}
        conf.update(shared_conf)
        filter = ReportFilterFactory.from_spec(conf)
        self.assertEqual(filter.context({}, None, lang=None)['label'], "foo")
        self.assertEqual(filter.context({}, None, lang="fr")['label'], "foo")

        # Translation
        conf = {"display": {"en": "english", "fr": "french"}}
        conf.update(shared_conf)
        filter = ReportFilterFactory.from_spec(conf)
        self.assertEqual(filter.context({}, None, lang=None)['label'], "english")
        self.assertEqual(filter.context({}, None, lang="fr")['label'], "french")
        self.assertEqual(filter.context({}, None, lang="en")['label'], "english")
        self.assertEqual(filter.context({}, None, lang="es")['label'], "english")

class DateFilterTestCase(SimpleTestCase):

    def test_date_filter(self):
        filter = ReportFilterFactory.from_spec({
            "type": "date",
            "field": "modified_on_field",
            "slug": "modified_on_slug",
            "display": "Date Modified"
        })
        self.assertEqual(DatespanFilter, type(filter))
        self.assertEqual('modified_on_slug', filter.name)
        self.assertEqual('Date Modified', filter.label)

    def test_compare_as_string_option(self):

        def get_query_value(compare_as_string):

            spec = {
                "type": "date",
                "field": "modified_on_field",
                "slug": "my_slug",
                "display": "date Modified",
                "compare_as_string": compare_as_string,
            }
            reports_core_filter = ReportFilterFactory.from_spec(spec)
            reports_core_value = reports_core_filter.get_value({
                "my_slug-start": "2015-06-07",
                "my_slug-end": "2015-06-08",
                "date_range_inclusive": True,
            })

            return create_filter_value(spec, reports_core_value).to_sql_values()

        val = get_query_value(compare_as_string=False)
        self.assertEqual(type(val['my_slug_startdate']), datetime)
        self.assertEqual(type(val['my_slug_enddate']), datetime)

        val = get_query_value(compare_as_string=True)
        self.assertEqual(type(val['my_slug_startdate']), str)
        self.assertEqual(type(val['my_slug_enddate']), str)

class DateFilterDBTest(ConfigurableReportTestMixin, TestCase):

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls._create_data()
        cls._create_data_source()
        cls.report_config = cls._create_report()

    @classmethod
    def _create_data(cls):
        cls._new_case({"my_date": date(2017, 1, 1), "my_datetime": datetime(2017, 1, 1, 9)}).save()

    @classmethod
    def _create_data_source(cls):
        cls.config = DataSourceConfiguration(
            domain=cls.domain,
            display_name=cls.domain,
            referenced_doc_type='CommCareCase',
            table_id="foo",
            configured_filter={
                "type": "boolean_expression",
                "operator": "eq",
                "expression": {
                    "type": "property_name",
                    "property_name": "type"
                },
                "property_value": cls.case_type,
            },
            configured_indicators=[
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'my_date'
                    },
                    "column_id": 'date_as_string',
                    "display_name": 'date_as_string',
                    "datatype": "string"
                },
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'my_date'
                    },
                    "column_id": 'date_as_date',
                    "datatype": "date"
                },
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": "my_datetime",
                    },
                    "column_id": "datetime_as_datetime",
                    "datatype": "datetime"
                }
            ],
        )
        cls.config.validate()
        cls.config.save()
        cls.addClassCleanup(cls.config.delete)

        cls.adapter = get_indicator_adapter(cls.config)
        rebuild_indicators(cls.config._id)
        cls.addClassCleanup(cls.adapter.drop_table)

    @classmethod
    def _create_report(cls):
        report_config = ReportConfiguration(
            domain=cls.domain,
            config_id=cls.config._id,
            title='foo',
            filters=[
                {
                    "type": "date",
                    "field": "date_as_date",
                    "slug": "date_as_date_filter",
                    "display": "Date as Date filter"
                },
                {
                    "type": "date",
                    "field": "date_as_string",
                    "slug": "date_as_string_filter",
                    "display": "Date as String filter",
                    "compare_as_string": True,
                },
                {
                    "type": "date",
                    "field": "datetime_as_datetime",
                    "slug": "datetime_as_datetime_filter",
                    "display": "Datetime as Datetime filter",
                    "compare_as_string": False,
                }
            ],
            aggregation_columns=['doc_id'],
            columns=[{
                # We don't really care what columns are returned, we're testing the filters
                "type": "field",
                "display": "doc_id",
                "field": 'doc_id',
                'column_id': 'doc_id',
                'aggregation': 'simple'
            }],
        )
        report_config.save()
        cls.addClassCleanup(report_config.delete)
        return report_config

    def _create_view(self, filter_values):
        request = HttpRequest()
        request.method = 'GET'
        request.GET.update(filter_values)
        view = ConfigurableReportView(request=request)
        view._domain = self.domain
        view._lang = "en"
        view._report_config_id = self.report_config._id
        return view

    def docs_returned(self, export_table):
        rows = export_table[0][1]
        return len(rows) - 1  # the first row is the headers, not a document

    def test_standard_date_filter(self):
        # Confirm that date filters include rows that match the start and/or end date.
        view = self._create_view({
            "date_as_date_filter": "2017-01-01 to 2017-01-01",
            "date_as_date_filter-start": "2017-01-01",
            "date_as_date_filter-end": "2017-01-01",
        })
        self.assertEqual(1, self.docs_returned(view.export_table))

    def test_string_date_filter(self):
        # Confirm that "compare_as_string" date filters include rows that match the start and/ord end date
        view = self._create_view({
            "date_as_string_filter": "2017-01-01 to 2017-01-01",
            "date_as_string_filter-start": "2017-01-01",
            "date_as_string_filter-end": "2017-01-01",
        })
        self.assertEqual(1, self.docs_returned(view.export_table))

    def test_standard_datetime_filter(self):
        view = self._create_view({
            "datetime_as_datetime_filter": "2017-01-01 to 2017-01-01",
            "datetime_as_datetime_filter-start": "2017-01-01",
            "datetime_as_datetime_filter-end": "2017-01-01",
        })
        self.assertEqual(1, self.docs_returned(view.export_table))

class QuarterFilterTestCase(SimpleTestCase):

    def test_date_filter(self):
        def get_query_value(year, quarter):
            spec = {
                "type": "quarter",
                "field": "modified_on_field",
                "slug": "my_slug",
                "display": "date Modified",
            }
            reports_core_filter = ReportFilterFactory.from_spec(spec)
            reports_core_value = reports_core_filter.get_value({
                "my_slug-year": year,
                "my_slug-quarter": quarter
            })

            return create_filter_value(spec, reports_core_value).to_sql_values()

        value = get_query_value(2016, 1)
        self.assertEqual(value['my_slug_startdate'], datetime(2016, 1, 1))
        self.assertEqual(value['my_slug_enddate'], datetime(2016, 4, 1))

        value = get_query_value(2016, 2)
        self.assertEqual(value['my_slug_startdate'], datetime(2016, 4, 1))
        self.assertEqual(value['my_slug_enddate'], datetime(2016, 7, 1))

        value = get_query_value(2016, 3)
        self.assertEqual(value['my_slug_startdate'], datetime(2016, 7, 1))
        self.assertEqual(value['my_slug_enddate'], datetime(2016, 10, 1))

        value = get_query_value(2016, 4)
        self.assertEqual(value['my_slug_startdate'], datetime(2016, 10, 1))
        self.assertEqual(value['my_slug_enddate'], datetime(2017, 1, 1))

class NumericFilterTestCase(SimpleTestCase):

    def test_numeric_filter(self):
        filter = ReportFilterFactory.from_spec({
            "type": "numeric",
            "field": "number_of_children_field",
            "slug": "number_of_children_slug",
            "display": "Number of Children",
        })
        self.assertEqual(NumericFilter, type(filter))
        self.assertEqual("number_of_children_slug", filter.name)
        self.assertEqual("Number of Children", filter.label)

    def test_numeric_filter_value(self):
        filter = {
            "type": "numeric",
            "field": "number_of_children_field",
            "slug": "number_of_children_slug",
            "display": "Number of Children",
        }
        NumericFilterValue(filter, None)
        NumericFilterValue(filter, {'operator': '<', 'operand': 3})
        with self.assertRaises(AssertionError):
            NumericFilterValue(filter, {'operator': 'sql injection', 'operand': 3})

class PreFilterTestCase(SimpleTestCase):

    def test_pre_filter(self):
        filter_ = ReportFilterFactory.from_spec({
            'type': 'pre',
            'field': 'at_risk_field',
            'slug': 'at_risk_slug',
            'datatype': 'string',
            'pre_value': 'true'
        })
        self.assertEqual(type(filter_), PreFilter)
        self.assertEqual(filter_.name, 'at_risk_slug')
        self.assertEqual(filter_.default_value(), {'operator': '=', 'operand': 'true'})

    def test_pre_filter_value(self):
        pre_value = 'yes'
        filter_ = {
            'type': 'pre',
            'field': 'at_risk_field',
            'slug': 'at_risk_slug',
            'datatype': 'string',
            'pre_value': pre_value
        }
        filter_value = PreFilterValue(filter_, {'operand': pre_value})
        self.assertEqual(filter_value.to_sql_values(), {'at_risk_slug': 'yes'})

    def test_pre_filter_value_empty(self):
        pre_values = ['', None]
        operators = ['', '=']
        for pre_value in pre_values:
            for operator in operators:
                filter_ = {
                    'type': 'pre',
                    'field': 'empty_field',
                    'slug': 'empty_field_slug',
                    'datatype': 'string',
                    'pre_value': pre_value,
                    'pre_operator': operator
                }
                filter_value = PreFilterValue(filter_, {'operand': pre_value, 'operator': operator})
                self.assertEqual(filter_value.to_sql_values(), {'empty_field_slug': ''})
                self.assertEqual(
                    str(filter_value.to_sql_filter().build_expression()),
                    'empty_field = :empty_field_slug OR empty_field IS NULL'
                )

    def test_pre_filter_value_empty_date_types(self):
        pre_values = ['', None]
        operators = ['', '=']
        date_types = [DATA_TYPE_DATE, DATA_TYPE_DATETIME]
        for pre_value in pre_values:
            for operator in operators:
                for datatype in date_types:
                    filter_ = {
                        'type': 'pre',
                        'field': 'empty_field',
                        'slug': 'empty_field_slug',
                        'datatype': datatype,
                        'pre_value': pre_value,
                        'pre_operator': operator
                    }
                    filter_value = PreFilterValue(filter_, {'operand': pre_value, 'operator': operator})
                    self.assertEqual(filter_value.to_sql_values(), {})
                    self.assertEqual(
                        str(filter_value.to_sql_filter().build_expression()),
                        'empty_field IS NULL'
                    )

    def test_pre_filter_value_exists(self):
        pre_values = ['', None]
        operator = '!='
        for pre_value in pre_values:
            filter_ = {
                'type': 'pre',
                'field': 'exists_field',
                'slug': 'exists_field_slug',
                'datatype': 'string',
                'pre_value': pre_value,
                'pre_operator': operator
            }
            filter_value = PreFilterValue(filter_, {'operand': pre_value, 'operator': operator})
            self.assertEqual(filter_value.to_sql_values(), {'exists_field_slug': ''})
            # != '' filters out null data in postgres which is why the expression doesn't need to check nulls
            self.assertEqual(
                str(filter_value.to_sql_filter().build_expression()),
                'exists_field != :exists_field_slug'
            )

    def test_pre_filter_value_exists_date_types(self):
        pre_values = ['', None]
        operator = '!='
        date_types = [DATA_TYPE_DATE, DATA_TYPE_DATETIME]
        for pre_value in pre_values:
            for datatype in date_types:
                filter_ = {
                    'type': 'pre',
                    'field': 'exists_field',
                    'slug': 'exists_field_slug',
                    'datatype': datatype,
                    'pre_value': pre_value,
                    'pre_operator': operator
                }
                filter_value = PreFilterValue(filter_, {'operand': pre_value, 'operator': operator})
                self.assertEqual(filter_value.to_sql_values(), {})
                self.assertEqual(
                    str(filter_value.to_sql_filter().build_expression()),
                    'exists_field IS NOT NULL'
                )

    def test_pre_filter_value_array(self):
        pre_value = ['yes', 'maybe']
        filter_ = {
            'type': 'pre',
            'field': 'at_risk_field',
            'slug': 'at_risk_slug',
            'datatype': 'array',
            'pre_value': pre_value
        }
        filter_value = PreFilterValue(filter_, {'operand': pre_value})
        self.assertEqual(filter_value.to_sql_values(), {'at_risk_slug_0': 'yes', 'at_risk_slug_1': 'maybe'})
        self.assertEqual(
            str(filter_value.to_sql_filter().build_expression()),
            'at_risk_field IN (:at_risk_slug_0, :at_risk_slug_1)'
        )

    def test_pre_filter_operator(self):
        value = {'operator': '<=', 'operand': '99'}
        filter_ = ReportFilterFactory.from_spec({
            'type': 'pre',
            'field': 'risk_indicator_field',
            'slug': 'risk_indicator_slug',
            'datatype': 'integer',
            'pre_value': value['operand'],
            'pre_operator': value['operator'],
        })
        self.assertEqual(type(filter_), PreFilter)
        self.assertEqual(filter_.default_value(), {'operator': '<=', 'operand': 99})  # operand will be coerced

    def test_pre_filter_invalid_operator(self):
        value = {'operator': 'in', 'operand': 'no'}  # "in" is invalid for scalar operand
        filter_ = {
            'type': 'pre',
            'field': 'at_risk_field',
            'slug': 'at_risk_slug',
            'datatype': 'string',
            'pre_value': value['operand'],
            'pre_operator': value['operator'],
        }
        filter_value = PreFilterValue(filter_, value)
        with self.assertRaises(TypeError):
            filter_value.to_sql_filter()

    def test_pre_filter_between_operator(self):
        value = {'operator': 'between', 'operand': ['2017-03-13', '2017-04-11']}
        filter_ = {
            'type': 'pre',
            'field': 'dob_field',
            'slug': 'dob_slug',
            'datatype': 'date',
            'pre_value': value['operand'],
            'pre_operator': value['operator'],
        }
        filter_value = PreFilterValue(filter_, value)
        self.assertEqual(filter_value.to_sql_values(), {'dob_slug_0': '2017-03-13', 'dob_slug_1': '2017-04-11'})
        self.assertEqual(
            str(filter_value.to_sql_filter().build_expression()),
            'dob_field BETWEEN :dob_slug_0 AND :dob_slug_1'
        )

    def test_pre_filter_distinct_from_operator(self):
        value = {'operator': 'distinct from', 'operand': 'test'}
        filter_ = {
            'type': 'pre',
            'field': 'at_risk_field',
            'slug': 'at_risk_slug',
            'datatype': 'string',
            'pre_value': value['operand'],
            'pre_operator': value['operator'],
        }
        filter_value = PreFilterValue(filter_, value)
        self.assertEqual(filter_value.to_sql_values(), {'at_risk_slug': 'test'})

    def test_pre_filter_dyn_operator(self):
        from corehq.apps.reports.daterange import get_daterange_start_end_dates
        start_date, end_date = get_daterange_start_end_dates('lastmonth')

        value = {'operator': 'lastmonth', 'operand': [None]}
        filter_ = {
            'type': 'pre',
            'field': 'dob_field',
            'slug': 'dob_slug',
            'datatype': 'array',
            'pre_value': value['operand'],
            'pre_operator': value['operator'],
        }
        filter_value = PreFilterValue(filter_, value)
        self.assertEqual(filter_value.to_sql_values(), {
            'dob_slug_0': str(start_date),
            'dob_slug_1': str(end_date),
        })
        self.assertEqual(
            str(filter_value.to_sql_filter().build_expression()),
            'dob_field BETWEEN :dob_slug_0 AND :dob_slug_1'
        )

class ChoiceListFilterTestCase(SimpleTestCase):
    CHOICES = [
        {
            "value": "NEGATIVE",
            "display": "negative"
        },
        {
            "value": "POSITIVE",
            "display": "positive"
        }
    ]

    def test_choice_list_filter(self):
        filter = ReportFilterFactory.from_spec({
            "type": "choice_list",
            "slug": "diagnosis_slug",
            "field": "diagnosis_field",
            "display": "Diagnosis",
            "choices": self.CHOICES,
            "show_all": False,
        })
        self.assertEqual(ChoiceListFilter, type(filter))
        self.assertEqual('diagnosis_slug', filter.name)
        self.assertEqual('Diagnosis', filter.label)
        self.assertEqual(2, len(filter.choices))
        for i, choice in enumerate(self.CHOICES):
            self.assertEqual(filter.choices[i].value, choice['value'])
            self.assertEqual(filter.choices[i].display, choice['display'])

        # check values
        self.assertEqual('positive', filter.value(diagnosis_slug='POSITIVE').display)

    def test_choice_list_filter_show_all(self):
        filter = ReportFilterFactory.from_spec({
            "type": "choice_list",
            "slug": "diagnosis_slug",
            "field": "diagnosis_field",
            "display": "Diagnosis",
            "choices": self.CHOICES,
            "show_all": True,
        })
        self.assertEqual(3, len(filter.choices))

        self.assertEqual(SHOW_ALL_CHOICE, filter.choices[0].value)
        for i, choice in enumerate(self.CHOICES):
            self.assertEqual(filter.choices[i + 1].value, choice['value'])
            self.assertEqual(filter.choices[i + 1].display, choice['display'])

        # check all value
        self.assertEqual('Show all', filter.value(diagnosis_slug=SHOW_ALL_CHOICE).display)

    def test_choice_list_filter_with_integers(self):
        choices = [
            {
                "value": 0,
                "display": "negative"
            },
            {
                "value": 1,
                "display": "positive"
            }
        ]
        filter = ReportFilterFactory.from_spec({
            "type": "choice_list",
            "slug": "diagnosis_slug",
            "field": "diagnosis_field",
            "datatype": "integer",
            "display": "Diagnosis",
            "choices": choices,
            "show_all": True,
        })
        self.assertEqual(ChoiceListFilter, type(filter))
        self.assertEqual('diagnosis_slug', filter.name)
        self.assertEqual('Diagnosis', filter.label)
        self.assertEqual(3, len(filter.choices))
        non_all_choices = filter.choices[1:]
        for i, choice in enumerate(choices):
            self.assertEqual(non_all_choices[i].value, choice['value'])
            self.assertEqual(non_all_choices[i].display, choice['display'])

        # ensure integer values work
        self.assertEqual('positive', filter.value(diagnosis_slug=1).display)
        # ensure 0 integer value works
        self.assertEqual('negative', filter.value(diagnosis_slug=0).display)
        # check string to int coercion
        self.assertEqual('positive', filter.value(diagnosis_slug='1').display)
        # ensure 0 string to int works
        self.assertEqual('negative', filter.value(diagnosis_slug='0').display)

        # check missing values raise errors
        with self.assertRaises(FilterValueException):
            filter.value(diagnosis_slug='4')

        # check non-integers raise errors
        with self.assertRaises(FilterValueException):
            filter.value(diagnosis_slug='foo')

        # check that all still works
        self.assertEqual('Show all', filter.value(diagnosis_slug=SHOW_ALL_CHOICE).display)

class DynamicChoiceListFilterTestCase(SimpleTestCase):

    def setUp(self):
        self.filter_spec = {
            "type": "dynamic_choice_list",
            "slug": "dynoslug",
            "field": "dynofield",
            "display": "Dynamic choice list",
            "show_all": False,
        }

    def test_choice_list_filter(self):
        filter = ReportFilterFactory.from_spec(self.filter_spec)
        self.assertEqual(DynamicChoiceListFilter, type(filter))
        self.assertEqual('dynoslug', filter.name)
        self.assertEqual('Dynamic choice list', filter.label)

    def test_string_datatype(self):
        self.filter_spec['datatype'] = 'string'
        filter = ReportFilterFactory.from_spec(self.filter_spec)
        tests = (
            ('1', '1'),
            ('1.2', '1.2'),
            ('hello', 'hello'),
        )
        for input, expected in tests:
            choices = filter.value(dynoslug=input)
            self.assertEqual(len(choices), 1)
            self.assertEqual(expected, choices[0].value)
            self.assertEqual(input, choices[0].display)

    def test_integer_datatype(self):
        self.filter_spec['datatype'] = 'integer'
        filter = ReportFilterFactory.from_spec(self.filter_spec)
        tests = (
            ('1', 1, '1'),
            ('1.2', 1, '1'),
            ('hello', None, ''),
        )
        for input, expected_value, expected_display in tests:
            choices = filter.value(dynoslug=input)
            self.assertEqual(len(choices), 1)
            self.assertEqual(expected_value, choices[0].value)
            self.assertEqual(expected_display, choices[0].display)

    def test_multiple_selections(self):
        self.filter_spec["datatype"] = "string"
        filter = ReportFilterFactory.from_spec(self.filter_spec)
        test_cases = (
            ['apple'],
            ['apple', 'banana'],
            ['apple', 'banana', 'carrot'],
        )
        choices = [
            Choice('apple', 'apple'),
            Choice('banana', 'banana'),
            Choice('carrot', 'carrot')
        ]
        for i, s in enumerate(test_cases):
            self.assertListEqual(choices[0:i + 1], filter.value(dynoslug=s))

    def test_ancestor_expression(self):
        filter = {
            "type": "dynamic_choice_list",
            "slug": "dynoslug",
            "field": "dynofield",
            "display": "Dynamic choice list",
            "show_all": False,
            "choice_provider": {"type": "user"},
            "ancestor_expression": {
                "field": "state_id",
                "location_type": "state",
            }
        }

        with self.assertRaises(BadSpecError):
            ReportFilterFactory.from_spec(filter)
        filter['choice_provider']['type'] = 'location'
        ReportFilterFactory.from_spec(filter)

class DateFilterOffsetTest(SimpleTestCase):
    def _computed_dates(self, actual_startdate, actual_enddate):
        filter = {
            'compare_as_string': False,
            'field': 'submission_date',
            'slug': 'submitted_on',
            'type': 'date',
            'required': False
        }
        value = DateSpan(actual_startdate, actual_enddate)
        filter_value = DateFilterValue(filter, value)
        computed_values = filter_value.to_sql_values()
        startdate = computed_values['%s_startdate' % filter['slug']]
        enddate = computed_values['%s_enddate' % filter['slug']]
        return startdate, enddate

    def test_date_objects(self):
        start, end = date(2015, 1, 1), date(2015, 1, 2)
        computed_start, computed_end = self._computed_dates(start, end)
        self.assertEqual(computed_start, start)
        self.assertEqual(computed_end, datetime.combine(end, datetime.max.time()))

    def test_datetime_objects(self):
        # computed_enddate should be last minute of the enddate
        start, end = datetime(2015, 1, 1), datetime(2015, 1, 2)
        computed_start, computed_end = self._computed_dates(start, end)
        self.assertEqual(computed_start, start)
        self.assertEqual(computed_end, datetime.combine(end, datetime.max.time()))
        self.assertEqual((computed_end - end).days, 0)

class LocationDrilldownFilterTest(LocationHierarchyTestCase):
    location_type_names = ['state', 'county', 'city']
    location_structure = [
        ('Massachusetts', [
            ('Middlesex', [
                ('Cambridge', []),
                ('Somerville', []),
            ]),
            ('Suffolk', [
                ('Boston', []),
            ])
        ])
    ]

    @classmethod
    def setUpClass(cls):
        cls.user = CommCareUser.create(cls.domain, 'test1', 'test123', None, None)
        super(LocationDrilldownFilterTest, cls).setUpClass()

    def test_filter(self):
        report = ReportConfiguration(domain=self.domain)
        ui_filter = ReportFilterFactory.from_spec({
            "slug": "block_id_drill",
            "type": "location_drilldown",
            "field": "block_id",
            "display": "Drilldown by Location",
            "include_descendants": False,
        }, report)

        self.assertEqual(type(ui_filter), LocationDrilldownFilter)

        # test filter_context
        filter_context_expected = {
            'input_name': 'block_id_drill',
            'loc_id': None,
            'hierarchy': location_hierarchy_config(self.domain),
            'locations': load_locs_json(self.domain),
            'loc_url': '/a/{}/api/v0.5/location_internal/'.format(self.domain),
            'max_drilldown_levels': 99,
            'auto_drill': 'false',
        }
        self.assertDictEqual(ui_filter.filter_context(self.user), filter_context_expected)

        # test include_descendants=False
        self.assertListEqual(
            ui_filter.value(
                **{ui_filter.name: self.locations.get('Middlesex').location_id, REQUEST_USER_KEY: self.user}
            ),
            [self.locations.get('Middlesex').location_id]
        )

        # test include_descendants=True
        ui_filter = ReportFilterFactory.from_spec({
            "slug": "block_id_drill",
            "type": "location_drilldown",
            "field": "block_id",
            "display": "Drilldown by Location",
            "include_descendants": True,
        }, report)
        self.assertListEqual(
            ui_filter.value(
                **{ui_filter.name: self.locations.get('Middlesex').location_id, REQUEST_USER_KEY: self.user}
            ),
            [self.locations.get(name).location_id
             for name in ['Middlesex', 'Cambridge', 'Somerville']]
        )

    def test_filter_value(self):
        filter = {
            "type": "location_drilldown",
            "field": "block_id",
            "slug": "block_id_drill",
            "display": "Drilldown by Location",
        }
        filter_value = LocationDrilldownFilterValue(filter, ['Middlesex'])
        self.assertDictEqual(filter_value.to_sql_values(), {'block_id_drill_0': 'Middlesex'})
        self.assertEqual(
            str(filter_value.to_sql_filter().build_expression()),
            'block_id IN (:block_id_drill_0)'
        )
        self.assertEqual(
            filter_value.to_sql_values(),
            {'block_id_drill_0': 'Middlesex'}
        )

    def test_ancestor_expression_missing_location_type(self):
        with self.assertRaises(BadSpecError):
            ReportFilterFactory.from_spec({
                "type": "location_drilldown",
                "field": "block_id",
                "slug": "block_id_drill",
                "display": "Drilldown by Location",
                "ancestor_expression": {
                    'field': 'state_id',
                    # missing 'location_type': 'state',
                }
            })

    def test_prefix_ancestor_location(self):
        filter = {
            "type": "location_drilldown",
            "field": "block_id",
            "slug": "block_id_drill",
            "display": "Drilldown by Location",
            "ancestor_expression": {
                'field': 'state_id',
                'location_type': 'state',
            }
        }
        middlesex_id = self.locations['Middlesex'].location_id
        mass_id = self.locations['Massachusetts'].location_id
        # make sure ancestor gets passed if right block is passed
        filter_value = LocationDrilldownFilterValue(filter, [middlesex_id])
        self.assertEqual(
            str(filter_value.to_sql_filter().build_expression()),
            'state_id = :state_id AND block_id IN (:block_id_drill_0)'
        )
        self.assertEqual(
            filter_value.to_sql_values(),
            {'state_id': mass_id, 'block_id_drill_0': middlesex_id}
        )
        # make sure ancestor doesn't get passed if multiple locations are passed
        filter_value = LocationDrilldownFilterValue(filter, [middlesex_id, 'Suffolk'])
        self.assertEqual(
            str(filter_value.to_sql_filter().build_expression()),
            'block_id IN (:block_id_drill_0, :block_id_drill_1)'
        )
        self.assertEqual(
            filter_value.to_sql_values(),
            {'block_id_drill_0': middlesex_id, 'block_id_drill_1': 'Suffolk'}
        )
        # no ancestor is passed if passed in location is invalid
        filter_value = LocationDrilldownFilterValue(filter, ['random'])
        self.assertEqual(
            str(filter_value.to_sql_filter().build_expression()),
            'block_id IN (:block_id_drill_0)'
        )
        self.assertEqual(
            filter_value.to_sql_values(),
            {'block_id_drill_0': 'random'}
        )

class QueryDictUtilTest(SimpleTestCase):
    def test_raw_boolean_strings_are_not_cast(self):
        request_dict = query_dict_to_dict(QueryDict(urlencode(
            {'my_string_key': 'true', 'another_string': 'false', 'non_string': 'true',
             'non_string_2': 'false', 'string_int': '1', 'non_string_int': '2', 'apple': 'orange'})),
            "some_domain",
            ['my_string_key', 'another_string', 'string_int']
        )
        self.assertDictEqual(
            request_dict,
            {
                # keys marked as string should not be casted to bool
                'apple': 'orange',
                'my_string_key': 'true',
                'another_string': 'false',
                'string_int': '1',
                # keys not marked as string are casted to bool
                'non_string': True,
                'non_string_2': False,
                'domain': 'some_domain',
                'non_string_int': 2,
            }
        )


import time
import syck

class Datastore(object):
    sentinel = object()

    def __init__(self, **kwds):
        super(Datastore, self).__init__()

    def get(self, key, default=sentinel):
        raise NotImplementedError

    def __getitem__(self, key):
        return self.get(key)

    def __iter__(self):
        return iter(self.keys())

    def keys(self):
        raise NotImplementedError

    def items(self):
        raise NotImplementedError

    def set(self, key, val=sentinel):
        raise NotImplementedError

    def __setitem__(self, key, value):
        return self.set(key, value)

    def clear(self, key):
        return self.set(key, self.sentinel)

    def create_substore(self, key, data):
        props = vars(self).copy()
        props['data'] = data
        return type(self)(**props)

class DictDatastore(Datastore):
    def __init__(self, data = None, **kwds):
        self.data = data
        super(DictDatastore, self).__init__(data=data, **kwds)

    def get(self, key, default=Datastore.sentinel):
        try:
            super(DictDatastore, self).get(key, default)
        except NotImplementedError:
            pass

        value = self.data.get(key, default)
        if value is self.sentinel:
            raise KeyError(key)
        elif isinstance(value, dict):
            return self.create_substore(key, value)
        else:
            return value

    def set(self, key, val=Datastore.sentinel):
        try:
            super(DictDatastore, self).set(key, val)
        except NotImplementedError:
            pass
        if val is self.sentinel:
            self.data.pop(key)
        else:
            self.data[key] = val

    def keys(self):
        return self.data.keys()

    def items(self):
        return self.data.items()

class FileDatastore(Datastore):
    def __init__(self, filepath, **kwds):
        self.filepath = filepath
        self._needsWrite = False
        self._lastRead = -1
        super(FileDatastore, self).__init__(filepath=filepath, **kwds)

    def set(self, key, val=Datastore.sentinel):
        mydefault = object()
        if val == self.get(key, mydefault):
            # Not changing the value, no need to set
            return

        if self._lastRead < self.get_mtime():
            raise Exception("Synchronization error: file was changed on disk and in memory")

        super(FileDatastore, self).set(key, val)
        self._needsWrite = True
        self.write()

    def get(self, key, default=Datastore.sentinel):
        mtime = self.get_mtime()
        if self._needsWrite and self._lastRead < mtime:
            raise Exception("Synchronization error: file was changed on disk and in memory")
        elif self._needsWrite:
            self.write()
        elif self._lastRead < mtime:
            self.read()

        return super(FileDatastore, self).get(key, default)

    def write(self):
        if not self.filepath:
            return
        if not self._needsWrite:
            return

        with open(self.filepath, 'wb') as f:
            self.serialize(f)
        self._lastRead = self.get_mtime()
        self._needsWrite = False

    def read(self):
        if not self.filepath:
            return

        if not self.filepath.isfile():
            self.data = {}
            self._needsWrite = True
            self.write()

        with open(self.filepath, 'rb') as f:
            self.deserialize(f)
        self._lastRead = self.get_mtime()

    def get_mtime(self):
        try:
            return getattr(self.filepath, 'mtime', None)
        except OSError:
            return 0

    def serialize(self, file):
        raise NotImplementedError

    def deserialize(self, file):
        raise NotImplementedError

    def items(self):
        if self._lastRead < self.get_mtime():
            self.read()

        return super(FileDatastore, self).items()

    def keys(self):
        if self._lastRead < self.get_mtime():
            self.read()

        return super(FileDatastore, self).keys()

class AuthenticatedDatastore(Datastore):
    def __init__(self, credentials, **kwds):
        self.credentials = credentials
        super(AuthenticatedDatastore, self).__init__(credentials=credentials, **kwds)

class EncryptingDatastore(Datastore):
    def __init__(self, encrypted_properties, **kwds):
        self.encrypted_properties = encrypted_properties
        super(EncryptingDatastore, self).__init__(encrypted_properties=encrypted_properties, **kwds)

    def get(self, key, default=Datastore.sentinel):
        value = super(EncryptingDatastore, self).get(key, default)
        if key in self.encrypted_properties and value is not default:
            try:
                value = self._decrypt(value)
            except UnicodeDecodeError:
                raise ValueError('Invalid Key')
        elif value is not Datastore.sentinel:
            value = value
        else:
            raise KeyError(key)

        return value

    def set(self, key, val=Datastore.sentinel):
        if key in self.encrypted_properties and val is not self.sentinel:
            val = self._encrypt(val)

        return super(EncryptingDatastore, self).set(key, val)

    def _encrypt(self, val):
        raise NotImplementedError

    def _decrypt(self, val):
        raise NotImplementedError

class DeepDatastore(Datastore):
    def __init__(self, sep='.', prefix=None, **kwds):
        self.sep = sep
        self.prefix = prefix
        super(DeepDatastore, self).__init__(sep=sep, prefix=prefix, **kwds)

    def get_keyparts(self, key):
        if hasattr(key, 'split'):
            keyparts = key.split('.')
        else:
            keyparts = key

        try:
            iter(keyparts)
        except:
            keyparts = (keyparts,)

        return tuple(keyparts)

    def get(self, key, default=Datastore.sentinel):
        keyparts = list(self.get_keyparts(key))

        firstkey = keyparts.pop(0)
        val = super(DeepDatastore, self).get(firstkey, default)
        if val is default:
            if default is Datastore.sentinel:
                raise KeyError
            return default

        if keyparts:
            val.prefix = (firstkey,)
            val = val.get(tuple(keyparts), default)

        return val

    def items(self):
        for k1 in super(DeepDatastore, self).keys():
            k1 = self.get_keyparts(k1)

            self.prefix = k1
            v1 = self.get(k1)
            if isinstance(v1, Datastore):
                for k2, v2 in v1.items():
                    if not isinstance(k2, tuple):
                        k2 = (k2,)
                    yield (k1 + k2, v2)
            else:
                yield (k1, v1)

    def keys(self):
        for k, _v in self.items():
            yield k

    def set(self, key, val=Datastore.sentinel):
        keyparts = list(self.get_keyparts(key))
        firstkey = keyparts.pop(0)

        mydefault = object()
        if keyparts:
            substore = self.get(firstkey, mydefault)
            if substore is mydefault:
                substore = self.create_substore(firstkey, {})

            substore.set(tuple(keyparts), val)
            super(DeepDatastore, self).set(firstkey, substore.data)
        else:
            super(DeepDatastore, self).set(firstkey, val)

    def create_substore(self, key, value):
        props = vars(self).copy()
        props['data'] = value
        props['prefix'] = key
        return type(self)(**props)

class NestedDictDatastore(DeepDatastore, DictDatastore):
    pass

class YAMLDatastore(FileDatastore, NestedDictDatastore):
    def serialize(self, f):
        syck.dump(self.data, f)

    def deserialize(self, f):
        self.data = syck.load(f)

    def create_substore(self, key, value):
        substore = super(YAMLDatastore, self).create_substore(key, value)
        substore.data = value
        #substore.read = self.read
        #substore.write = self.write
        substore.serialize = self.serialize
        substore.deserialize = self.deserialize

        return substore


from numpy.lib.function_base import append
from rejson import Client, Path
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
import math
import numpy as np
import time
import Text

def getSimilarities(client, keys, reqs, forInsert=False):

    memberRange = [1, 1090000]
    establishedRange = [1149, 2020]
    fieldLabels = [ 'Members', 'Year established', 'Headquarters Country', 'Scope', 'Funding methods', 'Languages', 'Continents', 'Countries', 'Activities']
    allFields = ['members','established', 'hq', 'scope', 'funding', 'languages', 'continents', 'countries', 'activities']
    catFields = ['hq', 'scope', 'funding', 'languages', 'continents', 'countries', 'activities']
    weights = client.jsonget('weights', '.')
    stats = client.jsonget('stats', '.')

    # Calculate the similarity of the ngo value with the range,
    # giving more weizzght to higher or lower values depending on the "higher" flag
    def numericSimilarity(reqRange, ngoValue, range, higher=True):
        if forInsert:
            reqValue = reqRange

        else:
            if ngoValue < range[0] or ngoValue > range[1]:
                return 0

            # If the value is in the range, similarity is 1
            if ngoValue >= reqRange[0] and ngoValue <= reqRange[1]:
                return 1

            # Else, similarity is the distance from the nearest limit of the range
            reqValue = 0
            if ngoValue < reqRange[0]:
                reqValue = reqRange[0]
            else:
                reqValue = reqRange[1]

        # Normalize values so they are between 0 and 1
        normReqValue = (reqValue-range[0]) / (range[1]-range[0])
        normNgoValue = (ngoValue-range[0]) / (range[1]-range[0])

        # Golden ratio -> 1.618, used in circle function of ratio sqrt(3) to determine its center
        # higher -> (x+(phi-1))²+(y-phi)²=3 -> y²-2phiy+(x+phi-1)²+phi²-3=0, np.roots([1,-2phiy,x²+pi-3]),
        # lower -> (x-phi)²+(y-phi)²=3 -> y²-2phiy+(x-phi)²+phi²-3=0, lower solution value
        phi = ( 1 + math.sqrt(5) ) / 2
        if higher:
            reqValue = np.roots([1,-2*phi, (normReqValue+phi-1)**2+phi**2-3])
            ngoValue = np.roots([1,-2*phi, (normNgoValue+phi-1)**2+phi**2-3])

        else:
            reqValue = np.roots([1,-2*phi, (normReqValue-phi)**2+phi**2-3])
            ngoValue = np.roots([1,-2*phi, (normNgoValue-phi)**2+phi**2-3])

        return 1 - abs(min(abs(reqValue))-min(abs(ngoValue)))

    # Generate matrix where for every ngo, there is an array with a position for each possible value
    # of the categorical data, where there will be a 1 in the values that the ngo has, or a 0 otherwise
    # One hot encoding
    def categoricalSimilarity(data, reqs, field):

        # Get all different values from both lists
        # colNames = data + list(set(reqs)-set(data)) not used anymore as

        # dataDummiesDF = [1 if elem in data else 0 for elem in colNames]
        # reqsDummiesDF = [1 if elem in reqs else 0 for elem in colNames]

        dataDummiesDF = [weights[field][elem] if elem in data and elem in weights[field] else 0 for elem in reqs]
        reqsDummiesDF = [weights[field][elem] if elem in reqs and elem in weights[field] else 0 for elem in reqs]

        # Calculate cosine similarity
        return cosine_similarity([reqsDummiesDF], [dataDummiesDF]).flatten()[0]

    def getMaxSimil(allSimil):
        maxFields = []

        for i in np.argpartition(allSimil, -2)[-2:]:
            maxFields.append(fieldLabels[i])
        maxFields.append('Activities')

        return maxFields

    similarities = []
    reqMembers = reqs['members'] if 'members' in reqs else None
    reqEstablished = reqs['established'] if 'established' in reqs else None

    for k in keys:

        # Numeric values
        rangeSimilarities = []

        ngo = client.jsonget(k, '.')

        if reqMembers is not None and 'members' in ngo and ngo['members'] is not None:
            rangeSimilarities.append(numericSimilarity(reqMembers, ngo['members'], memberRange, higher=False))
        else:
            rangeSimilarities.append(0)

        if reqEstablished is not None and 'established' in ngo and ngo['established'] is not None:
            rangeSimilarities.append(numericSimilarity(reqEstablished, ngo['established'], establishedRange))
        else:
            rangeSimilarities.append(0)

        # Categorical values
        ngoSimilarities = []

        for field in catFields:
            if (field in ngo and ngo[field] is not None and field in reqs and reqs[field] is not None):
                if isinstance(ngo[field], str):
                    ngo[field] = [ngo[field]]
                else: # array, filter None
                    ngo[field] = [i for i in ngo[field] if i]
                    ngo[field] = list(dict.fromkeys(ngo[field]))
                if len(ngo[field]) > 0 and len(reqs[field]) > 0:
                    ngoSimilarities.append(categoricalSimilarity([ngo[field]] if isinstance(ngo[field], str) else ngo[field], [reqs[field]] if isinstance(reqs[field], str) else reqs[field], field))
                else:
                    ngoSimilarities.append(0)
            else:
                ngoSimilarities.append(0)

        # Compute similarity
        allSimil = rangeSimilarities+ngoSimilarities

        if forInsert:
            similarities.append(allSimil)

        else:
            weightedSimil = []

            for i in range(0, len(allSimil)):
                weightedSimil.append(allSimil[i]*stats[allFields[i]]['factor']*(4.5 if allFields[i] == 'activities' else 0.5625))

            similarities.append({
                'simil': sum(weightedSimil),
                'max': getMaxSimil(weightedSimil)
            })

    return similarities


from django.urls import path
from . import views

app_name="meal"
urlpatterns = [
    path('index/', views.index, name="index"),
    path('bmi/', views.bmi, name="bmi"),
    path('database/', views.food_Database, name="database"),
    path('detail/<mpk>', views.detail, name="detail"),
]


from stack import Stack

def main():
	s = Stack()
	s.isEmpty()
	s.push(1)
	s.push(2)
	s.push(5)
	s.peek()
	s.pop()
	s.print_list()

if __name__ == '__main__':
	main()


import os
import csv

DIR_PATH = os.path.dirname(os.path.realpath(__file__))

def find_type_link(input_type):
    if input_type == "-":
        return ""

    with open(f"{DIR_PATH}/house_types.csv", "r", encoding="utf-8") as fin:
        csv_reader = csv.reader(fin, delimiter=";")
        for house_type, link in csv_reader:
            if input_type in house_type:
                return link

        return ""


# import tools

# Guess Game

"""
secret_word = "giraffe"
guess = ""
guess_count = 0
# guess_limit = 3
out_of_guesses = False

guess_limit = int(input("How many guess attempts would you like?"))

while guess != secret_word and not(out_of_guesses):
    print("Guesses left: " + str(guess_limit - guess_count) + "\n")
    if guess_count < guess_limit:
        guess = input("Enter guess: ")
        guess_count += 1
        # print(guess_limit - guess_count)
    else:
        out_of_guesses = True

if out_of_guesses:
    print("Out of Guesses, YOU LOSE!")
else:
    print("You win!")
"""

# For Loop

"""
# what are the pro's and cons to each type of loop style?

# let stands for letter. You can use any name for individual values of str
# inside the for loop condition
for let in "Ezekiel Ramirez":
    print(let)

friends = ["James", "Cameron", "Josh", "Mark", "Collin", "Zac", "Hovag"]
for friend in friends:
    print(friend)

for index in range(15):
    # the num provided in range is exclusive starting at 0
    # it will show nums 0 - 14 with range(15)
    # it will show nums 5 - 9 with range(5, 10)
    print(index)

for index in range(15):
    if index == 0:
        print("First iteration")
    else:
        print("other")

"""

# Exponent Function

"""
# 2**3 = 2^3
print(2 ** 3)

def raise_to_power(base_num, pow_num):
    result = 1
    for index in range(pow_num):
        # result = result * base_num
        result *= base_num
    return result

new_num = raise_to_power(3, 2)

print(new_num)
"""

# 2D lists and Nested Loops

"""

# we can build a list of lists
num_grid = [
    [1, 2, 3],  # row 0 -- cols 0, 1, 2
    [4, 5, 6],
    [7, 8, 9],
    [0]
]

# num_grid[0][1] should return 2
print(num_grid[0][1])
print(num_grid[1][2])

for row in num_grid:
    # print("row:\t" + str(row))
    print(row)

row_sel = int(input("What row would you like to pick"))

# if row is bigger than size of grid then throw error
# len checks the size of many data types and data structures
# https://www.digitalocean.com/community/tutorials/find-the-length-of-a-list-in-python
if row_sel > len(num_grid):
    print("Your selection is too big")
else:
    print(num_grid[row_sel])

for row in num_grid:
    for col in row:
        print(col)

"""

# Build a translator

"""
Giraffe Language
vowels -> z

dog -> dzg
cat -> czt

# take in a word and read word letter by letter
# then when it finds a vowel, replace it with z
def translate(phrase):
    trans = ""      # trans will be the word we return after changing the vowel
    for let in phrase:
        # going letter by letter through word
        if let in "AEIOUaeiou":
            # if the letter is a vowel then make the change
            # don't forget to preserve capitals if possible
            if let.isupper():
                trans += "Z"
            else:
                trans += "z"
        else:
            # else keep the original letter
            trans += let
    return trans

print(translate(input("Enter a phrase please ")))
"""

# Comments
'''
It is recommended by python to use hashes
for multi-line rather than quotations
'''
""" """

# Try Except

"""
If we can forsee a situation where the code may break
we can use a Try Except to stop errors from halting the code

try:
    num = int(input("Enter a number: "))
    print(num)
except:
    # sometimes your catch requirements may be too general
    # you may want to focus on more specific errors
    print("Invalid Input")

# best practice is to use specific error cases
try:
    test = 10 / 0
    num = int(input("Enter a number: "))
    print(num)
except ZeroDivisionError as err:
    # err could be named anything
    # err corresponds to a string that states 'division by zero'
    print(err)
except ValueError:
    print("invalid response")
"""

# Reading Files

"""
the open() command takes in a path or file name to
know which file to read data from

# here I will use the files name becuase the python file and
# data file are in the same folder/directory

# the second parameter for open has four options
# r   (Read) This allows the program to read only from the target file
# a   (Append) This only allows the program to add data to the end of the file,
#     you won't be able to modify existing data
# w   (Write) This allows the program to change existing information and/or add new data
# r+  (Read and Write)

# what kind of data type stores the opening of another .txt file?
employee_file = open("employees.txt", "r")

# print("Is the employee file readable?")
# print(employee_file.readable())

# the .read commands read the appropriate amount of lines then move the cursor
# to the next spot so be aware of the order of your read statements
# print(employee_file.readline())

# print(employee_file.read())

# this readlines file takes all lines and puts them in a list
# you can even ask for specific lines this way
# print(employee_file.readlines()[1])
# print(employee_file.readlines())

for employee in employee_file.readlines():
    print(employee)

# don't forget to close files you work with
employee_file.close()
"""

# Writing to Files

"""

# writing (w) over writes everything in the target file, BE CAREFUL
# opening a file that doesn't exist will create that file. employees1.txt is an example
# you can even write an html file in python
employee_file = open("employees1.txt", "a")
# when adding to a file, make sure you know if you need a newline character or indents
# employee_file.write("\nKelly - Human Services")
# print(employee_file.read())
employee_file.close
"""

# Modules and Pip

"""
modules are python files that we can call to use from another file location
there will be some import statements down here so we know what was used,
normally they would appear at the top of the python file

you can also find modules written by other programmers, experiment with new ones!!!

import tools
# import docx
print(tools.roll_dice(22))
# find the python resources for the list of modules I can import
# Make sure it is for the version of python you are using
# https://docs.python.org/3.7/py-modindex.html

# https://python-docx.readthedocs.io/en/latest/

# Pip is a package manager that handles the download of third party modules/installations
# my pip and python wouldn't run in the command prompt window
# when you add python for the first make sure you check that the path option is clicked ON
# https://www.geeksforgeeks.org/how-to-install-pip-on-windows/
"""

# Classes and Objects

"""

from Student import Student
# read as 'from the student file, get the student class
Student1 = Student("Zeek", "Computer Science", 3.5, False)
# the class is like a template and the instance is an actual student
print("Name: " + Student1.name)
print("Major: " + Student1.major)
print("GPA: " + str(Student1.gpa))
print("Probation: " + str(Student1.probation))
"""

# Multiple Choice Quiz

"""

from Question import Question

# here is the list of questions and the available responses
question_prompts = [
    "What color are apples?\n(a) Red/Green\n(b) Purple\n(c) Orange\n\n",
    "What color are Bananas?\n(a) Teal\n(b) Magenta\n(c) Yellow\n\n",
    "What color are strawberries?\n(a) Yellow\n(b) Red\n(c) Blue\n\n"
]

# this list is taking the prompts and putting the values into an instance of the
# question and setting what answer is correct
questions = [
    Question(question_prompts[0], "a"),
    Question(question_prompts[1], "c"),
    Question(question_prompts[2], "b")
]

# create a method to iterate through questions
# keep track of the player's score
# take in the list of questions and track their correct answers
def run_test(questions):
    score = 0
    for que in questions:
        answer = input(que.prompt)
        if answer == que.answer:
            score += 1
    print("You got " + str(score) + "/" + str(len(questions)) + " correct")

run_test(questions)

# maybe I should try to make my own test
"""

# Object Functions

""" """
from Student import Student

student1 = Student("Oscar", "Accounting", 3.1)
student2 = Student("Phyllis", "Business", 3.8)

print(student1.on_honor_roll())
print(student2.on_honor_roll())


from model_param import *
import numpy as np
from numpy import genfromtxt
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from imblearn.over_sampling import SMOTE
import logging

logging.basicConfig(
    level=logging.INFO,
    filename="Rezults.log",
    format="%(asctime)s - %(module)s - %(levelname)s - %(funcName)s: %(lineno)d - %(message)s",
    datefmt='%H:%M:%S',
    encoding='utf-8',)

def analizator():
    # Загрузили преобразованную матрицу предложений:
    x = genfromtxt(FILE_COUNT_X, delimiter=',')
    logging.info('*' * 10 + 'Предварительная подготовка данных:' + '*' * 10)
    logging.debug('Считали матрицу описания телефонов:')
    logging.debug(x)
    # Загрузили преобразованный вектор ответов:
    df_y = pd.read_csv(FILE_COUNT_Y, delimiter=',')
    y = df_y.iloc[:, -1].values
    logging.debug('Считали вектор результатов:')
    logging.debug(y)
    # Оцениваем количество положительных и нулевых ответов в У:
    zero = np.sum(y == 0.)
    pls = np.sum(y == 1.)
    str_ = 'у состоит из {0} нулевых значений и {1} еденичных значений. Общее количество: {2}'.format(zero, pls,
                                                                                len(y))
    print(str_)
    logging.info(str_)
    str_0 = f'Количество предложений: {len(x)}.'
    print(str_0)
    logging.info(str_0)
    # Начинаем подготовку данных для модели:
    # test_size показывает, какой объем данных нужно выделить для тестового набора
    # Random_state — просто сид для случайной генерации
    # Этот параметр можно использовать для воссоздания определённого результата:
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.20, random_state=2)
    # Балансируем данные
    os = SMOTE(random_state=0)
    os_data_x, os_data_y = os.fit_resample(x_train, y_train)
    # Проверяем рузультаты балансировки:
    logging.debug('Отбалансированные данные для обучения модели:')
    logging.debug(os_data_x)
    logging.debug(os_data_x.shape)
    logging.debug(os_data_y)
    logging.debug(os_data_y.shape)
    #  Состав данных для проверки качества модели:
    test_zro = np.sum(y_test == 0.)
    test_pls = np.sum(y_test == 1.)
    str_1 = 'Данные для тестирования результатов обучения модели содержат ' \
            'нулевых значений: {0}, положительных значений: {1}'.format(test_zro, test_pls)
    print(str_1)
    logging.info(str_1)
    os_data_y_zro = np.sum(os_data_y == 0.)
    os_data_y_pls = np.sum(os_data_y == 1.)
    str_2 = 'Отбалансированные данные для обучения модели содержат ' \
            'нулевых значений: {0}, положительных значений: {1}'.format(os_data_y_zro, os_data_y_pls)
    print(str_2)
    logging.info(str_2)
    print('*' * 30)
    # Применяем Логистическую регрессию:
    str_3 = f'Расчет по модели Логистическая регрессия:'
    print(str_3)
    logging.info(str_3)
    classifier = LogisticRegression(solver='lbfgs', random_state=0)
    clf = classifier.fit(x_train, y_train)
    str_4 = f'Коэффициенты b1, b2, b3 ...:\n {clf.coef_}\nКоэффициент b0:{clf.intercept_}'
    print(str_4)
    logging.info(str_4)
    predicted_y = classifier.predict(x_test)
    logging.debug(predicted_y)
    str_5 = 'Точность предсказания методом RL на тестовом примере{:.2f}%.'.format(classifier.score(x_test, y_test))
    print(str_5)
    logging.info(str_5)
    # Классификатор Случайный лес:
    str_6 = f'Расчет по модели Случайный лес:'
    print(str_6)
    logging.info(str_6)
    rfc = RandomForestClassifier()
    rfc.fit(x_train, y_train)
    rfc_predicted_y = rfc.predict(x_test)
    logging.debug(rfc_predicted_y)
    str_7 = 'Точность предсказания по модели Случайный лес на тестовом примере '
    str_7 = str_7 + 'составила: {:.2f}%.'.format(rfc.score(x_test, y_test))
    print(str_7)
    logging.info(str_7)
    str_8 = '*' * 10 + 'Расчет окончен.' + '*' * 10
    print(str_8)
    logging.info(str_8)
    return

def main():
    analizator()

# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    main()


from recognition import E2E
import cv2
from pathlib import Path
import argparse
import time
from datetime import datetime
import json
import requests

class license:
    def __init__(self, license_number):
        self.license_number = license_number

def send_license_number_plate_checkin(license_number):
    LINK = 'http://127.0.0.1:8000/validate-license/'
    params = json.dumps(license(license_number).__dict__)
    connection = requests.post(url = LINK, data= params)
    print(connection.json())

def send_license_number_plate_checkout(license_number):
    LINK = 'http://127.0.0.1:8000/validate-license/check/out'
    params = json.dumps(license(license_number).__dict__)
    connection = requests.post(url = LINK, data= params)
    print(connection.json())

i = 1
model = E2E()
while(i < 29):
    path = './images/'+str(i)+'.jpg'
    i=i+1
    try:
        print('====================\n')
        img = cv2.imread(path)
        plate = model.predict(img)
        plate = plate.replace("-","")
        print(plate)
        time_send = datetime.now()
        if plate == None:
            print(str(time_send) + " --> NO CAR")
        else:
            send_license_number_plate_checkin(plate)
            print(str(time_send) + " -->  " + str(plate))
    except :
        continue

    time.sleep(3)


"""
闭包有什么缺点呢？
缺点1、作用域没有那么直观
缺点2、因为变量不会被垃圾回收，所以存在一定的内存占用问题

闭包作用 1、可以使用同级的作用域
2、读取其他元素的内部变量
3、延长作用域

闭包总结：
1、闭包似优化了变量，原来需要类对象完成的工作，闭包也可以完成
2、由于闭包引用了外部函数的局部变量，则外部函数的局部变量没有及时释放，消耗内存
3、闭包的好处：使代码变得简洁，便于阅读代码
4、闭包是理解装饰器的基础

"""

def func():
    a = 100

    def inner_func1():
        b = 90
        s = a + b
        print(s)

    def inner_func2():
        # print(b)
        inner_func1()
        print("——————>inner_func2")
        return 'hello'

    return inner_func2  # 0x0350BC48

# 调用func
f = func()
print(f)
ff = f()
print(ff)


#2.1
s = ["hello", "my", "friend"]
d = {s.index(i) : len(i) for i in s}

for i in reversed(d):
    print(i)

n = len(s)
for i in range(n):
    for j in range(i+1,n):
        if len(s[i]) < len(s[j]):
            temp = s[i]
            s[i] = s[j]
            s[j] = temp

print(d, s)


# Author:		MS. Kingon
# Date:			27/10/2016
# Description:	Algorithim to determine if 2 words are similar providing a confidence level.
# Requirments:	Python 2.7+
#				Re
#				codecs
# ========================================= #
# Imports									#
# ========================================= #
import codecs;
import re;

# ========================================= #
# Global Variables							#
# ========================================= #
path_to_testing_file = r'Data\tester_file.txt';
path_to_results = r'Data\results.log';
correct_cnt = 0.0;
# ========================================= #
# Functions									#
# ========================================= #
def simmilar(wrd1, wrd2):
	Verdict = 'False';		# set default verdict to False
	confidence = -1;		# set default confidence Level to -1

	lev_dst_mat = levenshteimDistanceMatrix(wrd1, wrd2);
	confidence = calcConfidence(wrd1, wrd2, lev_dst_mat);

	if confidence > .75:
		Verdict = 'True';

	return (Verdict, confidence)

def prettyPrintLevenshteimMatrix(matrix):
	# just a pretty printer for a numerical matrix
	for i in matrix:
		for j in i:
			print("{:^3}".format(j)),
		print('\n')

def calcConfidence(src, tar, lev_mat):
	# given a source and target word along with the built Levenshteim Matrix, determine a confidence level that these two words are the same
	# input:	source, target, Levenshteim distance matrix
	# output:	Floating point value between 0-1 indicating confidence that these words are the same.

	if(len(src) < lev_mat[-1][-1]):
		return -1.0;

	inv_conf = float(lev_mat[-1][-1])/len(src);
	conf = 1-inv_conf;

	return conf

def levenshteimDistanceMatrix(src, tar):
	# computes the levenshteim distance Matrix between two strings.
	# create a (m+1)x(n+1) Matrix where:
	# 	m=src length
	#	n=tar length
	# Input: a source word and a target word
	# Output: Levenshteim Distance Matrix for the 2 words

	d = []
	n = len(src);
	m = len(tar);
	for j in range(n+1):
		d.append([]);
		for i in range(m+1):
			d[j].append(0);

	# set source prefix's
	for i in range(1, m+1):
		d[0][i] = i;

	# set target prefix's
	for j in range(1, n+1):
		d[j][0] = j;

	for j in range(1, n+1):
		for i in range(1, m+1):
			# print src[i]
			if src[j-1] == tar[i-1]:
				subCost = 0;
			else:
				subCost = 1;
			d[j][i] = min([d[j][i-1]+1, d[j-1][i]+1, d[j-1][i-1] + subCost])

	prettyPrintLevenshteimMatrix(d);

	return d

# Description: takes a file with testing data and reads it into a triplit array
# Input: file to fetch data from
# Output: an Nx3 Array where N is the number of test items.
def readInTester(testing_file):
	data = [];
	testing_file_lines = codecs.open(testing_file, 'r');

	for line in testing_file_lines:
		# ignore comment or emptty lines where comments are distinguished as #
		if re.search('^\s*#', line) or re.search('^\s*$', line):
			continue;
		else:
			src,tar,ver = re.findall('^(.*?)\|(.*?)\|(.*?)$', line)[0];
			data.append([src.strip(), tar.strip(), ver.strip()]);

	testing_file_lines.close();
	return data;

# Description: takes two words and the correct verdict, applyies simmilar word alg to the words, and reports if it got the match correct along woth the confidence interval.
# Input:  source word, target word, human evaluation of their simmilarity.
# Output: tuple containing, correctness of guess, and the confidense of the match
def test(src, tar, correct_verdict):
	verdict_tuple = simmilar(src.lower(), tar.lower());
	correctness = 0;

	if verdict_tuple[0] == correct_verdict:
		correctness = 1;

	return (correctness, verdict_tuple[1]);

def tester(testing_data, path_to_results):
	# takes as input a File containing lines as:

	# it then creates a report file that tells you the words the Algorithim got wrong and percentage of words it got right
	# possibly also showing words with confidences between 50-75 that are tested correct?
	global correct_cnt;
	total_tests = len(testing_data);
	result_file = codecs.open(path_to_results, 'w');
	false_pos = [];

	for item in testing_data:
		test_conclusion = test(item[0], item[1], item[2]);
		if (test_conclusion[0] == 1):
			correct_cnt += 1.0;
			continue;
		else:
			# provide log data for cases where the prediction failed
			our_predict = 'False';
			if (item[2] == 'False'):
				# keep special track of any false positives
				our_predict = 'True';
				false_pos.append([item[0], item [1], test_conclusion[1]]);

			# update log file with incoreect guesses.
			result_file.write('Source:     {0}\nTarget:     {1}\nPredicted:  {2}\nCorrect:    {3}\nConfidence: {4:5.2f}%\n'.format(item[0], item[1], our_predict, item[2], test_conclusion[1]*100));
			result_file.write('='*80 + '\n');

	# pretty print any false positives.
	result_file.write('Below is an extracted list of all the false positives along with the supposed confidence.\n');
	if false_pos == []:
		result_file.write('Wonderfull, there are No false Positives.\n' + '='*80 + '\n')
	for bad in false_pos:
		result_file.write('{0:20} | {1:20} | {2:5.2f}%\n'.format(bad[0], bad[1], bad[2]))

	result_file.write('In Conclusion; out of {0} test cases we got {1} Correct.\nThis equates to a: {2:5.2f}% success rate\n'.format(total_tests, correct_cnt, correct_cnt/total_tests*100));
	pass;

# ========================================= #
# Entry point								#
# ========================================= #
if __name__ == "__main__":
	# there are many heuristics that one could use, for an example, changes to
	# the begining of words should be more concerning than changes at the end.

	test_data = readInTester(path_to_testing_file);				# import testing data.
	tester(test_data, path_to_results);

Close string match algorithm/Similar_words_alg.py


import os, cv2
import json
import torch
import imageio
import numpy as np
from tqdm import tqdm
import torchvision.transforms as T
import torch.multiprocessing
torch.multiprocessing.set_sharing_strategy('file_system')

from kornia import create_meshgrid
from scipy import interpolate
from torch.utils.data import DataLoader, Dataset

class DoNeRFDataset(Dataset):
    def __init__(self, root_dir, split='train', data_skip=1, download_sample=1):
        super(DoNeRFDataset, self).__init__()
        self.root_dir = root_dir
        self.split = split
        self.data_skip = data_skip
        self.white_back = True
        self.download_sample = download_sample
        self.read_meta()

    def load_depth_image(self, depth_path, K, download_sample):

        depth = np.load(depth_path)
        u = range(0, depth.shape[0])
        v = range(0, depth.shape[1])

        u, v = np.meshgrid(u, v)
        u = u.astype(float)
        v = v.astype(float)

        Z = depth.astype(float)
        X = (u - K[0, 2]) * Z / K[0, 0]
        Y = (v - K[1, 2]) * Z / K[1, 1]

        sample_position = np.sqrt(X**2 + Y**2 + Z**2)
        return torch.FloatTensor(sample_position.reshape(-1, 1))

    def load_rgb_image(self, rgb_path, download_sample):
        H, W = self.resolution
        img = imageio.v2.imread(rgb_path)
        img = (np.array(img) / 255.).astype(np.float32) # 4 channels (RGBA)
        if self.H != img.shape[0]:
            img = cv2.resize(img, (H, W), interpolation=cv2.INTER_AREA)
            img = cv2.resize(img, (H//download_sample, W, download_sample), interpolation=cv2.INTER_AREA)
        img = self.transform(img)               # (4, H, W)
        img = img.view(4, -1).permute(1, 0)     # (H*W, 4)
        img = img[:, :3] * img[:, -1:] + (1 - img[:, -1:])
        return img

    def pose_to_rays(self, H, W, focal, pose):
        grid = create_meshgrid(H, W, normalized_coordinates=False)[0]
        i, j = grid.unbind(-1)
        directions = torch.stack([(i-W/2)/focal, -(j-H/2)/focal, -torch.ones_like(i)], -1) # (H, W, 3)
        pose = torch.FloatTensor(pose)
        rays_d = directions @ pose[:3, :3].T  # (H, W, 3)
        rays_d = rays_d / torch.norm(rays_d, dim=-1, keepdim=True)
        rays_o = pose[:3, 3].expand(rays_d.shape)  # (H, W, 3)
        rays_d = rays_d.view(-1, 3)
        rays_o = rays_o.view(-1, 3)
        return rays_o, rays_d

    def read_meta(self):
        with open(os.path.join(self.root_dir, "dataset_info.json"), 'r') as f:
            info = json.load(f)
        camera_angle_x = info['camera_angle_x']
        depth_ignore = info['depth_ignore']
        depth_range_warped_log = info['depth_range_warped_log']
        depth_range_warped_lin = info['depth_range_warped_lin']
        depth_range = info['depth_range']
        self.resolution = info['resolution']
        self.W, self.H = self.resolution
        self.focal = 0.5 * self.W / np.tan(0.5 * camera_angle_x)

        K = np.array([
            [self.focal, 0, 0.5*self.W],
            [0, self.focal, 0.5*self.H],
            [0, 0, 1]
        ])

        with open(os.path.join(self.root_dir, f'transforms_{self.split}.json'), 'r') as f:
            self.meta = json.load(f)

        # get rays, depth and rgb data
        if self.split == 'train':
            self.img_paths = []
            self.all_rays = []
            self.all_rgbs = []
            self.all_depth = []

            for frame in tqdm(self.meta['frames'][::self.data_skip], desc='Loading Train Dataset'):
                # get poses/rays
                pose = torch.FloatTensor(frame['transform_matrix'])[:3, :4]
                rays_o, rays_d = self.pose_to_rays(self.H//self.download_sample, self.W//self.download_sample, self.focal, pose)
                self.all_rays.append(torch.cat([rays_o, rays_d], 1))

                # get rgbs and depth
                rgb_path = os.path.join(self.root_dir, f"{frame['file_path']}.png")
                depth_path = rgb_path.replace('.png', '_depth.npy')
                self.img_paths.append(rgb_path)

                rgb = self.load_rgb_image(rgb_path, self.download_sample)
                depth = self.load_depth_image(depth_path, K, self.download_sample)
                self.all_rgbs.append(rgb)
                self.all_depth.append(depth)

            self.all_rays = torch.cat(self.all_rays, 0)     # (len(img_paths)*h*w, 6)
            self.all_rgbs = torch.cat(self.all_rgbs, 0)     # (len(img_paths)*h*w, 3)
            self.all_depth = torch.cat(self.all_depth, 0)   # (len(img_paths)*h*w, 1)

        elif self.split == 'val':
            frame = self.meta['frames'][0]
            pose = torch.FloatTensor(frame['transform_matrix'])[:3, :4]
            rays_o, rays_d = self.pose_to_rays(self.H, self.W, self.focal, pose)

            rgb_path = os.path.join(self.root_dir, f"{frame['file_path']}.png")
            depth_path = rgb_path.replace('.png', '_depth.npy')

            self.rgb = self.load_rgb_image(rgb_path, self.download_sample)        # (H*W, 3)
            self.depth = self.load_depth_image(depth_path, K, self.download_sample)  # (H*W, 1)
            self.rays = torch.cat([rays_o , rays_d], 1)     # (H*W, 6)

        elif self.split == 'test':
            pass

    def transform(self, img):
        return T.ToTensor()(img)

    def __len__(self):
        if self.split == 'train':
            return self.all_rays.shape[0]
        elif self.split == 'val':
            return self.W*self.H//(self.download_sample**2)
        elif self.split == 'test':
            return 0

    def __getitem__(self, idx):
        if self.split == 'train':
            sample = {'rays': self.all_rays[idx],
                      'rgbs': self.all_rgbs[idx],
                      'depth': self.all_depth[idx]}

        elif self.split == 'val':
            sample = {'rays': self.rays[idx],     # (H*W, 6)
                      'rgbs': self.rgb[idx],      # (H*W, 3)
                      'depth': self.depth[idx]}   # (H*W,)

        elif self.split == 'test':
            sample = {}

        return sample

if __name__ == '__main__':
    import sys
    sys.path.append('/home/baihy/datasets/DONeRF-data/')
    from torch.utils.data import DataLoader

    root_dir = '/home/baihy/datasets/DONeRF-data/barbershop'
    dataset = DoNeRFDataset(root_dir, 'train', data_skip=10, download_sample=1)
    from torch.utils.data import DataLoader

    data = DataLoader(dataset, batch_size=1, num_workers=64)
    print(len(data))
    for i, sample in enumerate(data):
        rgb = sample['rgbs']
        rays = sample['rays']
        depth = sample['depth']
        print(i, rgb.shape, rays.shape, depth.shape)
        break


#!/usr/bin/env python3
__version__ = "1.3"
import socket
import sys
import json

from argparse import ArgumentParser, SUPPRESS
from datetime import datetime
from ssl import PROTOCOL_TLSv1
from time import sleep
from csv import DictWriter

try:
    from json2html import *
except ImportError:
    print("Please install required modules: json2html. pip3 install json2html")
    sys.exit(1)

class Clr:
    """Text colors."""
    RST = '\033[39m'
    RED = '\033[31m'
    GREEN = '\033[32m'
    YELLOW = '\033[33m'

class SSLCheck:

    total_valid = 0
    total_expired = 0
    total_failed = 0
    total_warning = 0

    def get_cert(self, host, port, args):
        try:
            from OpenSSL import SSL
        except ImportError:
            print("Please install required modules: OpenSSL. pip3 install pyopenssl")
        """Connection to the host."""
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #The default is 300 seconds
        osobj = SSL.Context(PROTOCOL_TLSv1)
        sock.connect((host, int(port)))
        oscon = SSL.Connection(osobj, sock)
        oscon.set_tlsext_host_name(host.encode())
        oscon.set_connect_state()
        oscon.do_handshake()
        cert = oscon.get_peer_certificate()
        sock.close()
        print('{}Closing socket{}\n'.format(Clr.YELLOW, Clr.RST))
        return cert

    def border_msg(self, message):
        """Print the message in the box."""
        row = len(message)
        h = ''.join(['+'] + ['-' * row] + ['+'])
        result = h + '\n' "|" + message + "|"'\n' + h
        print(result)

    def get_cert_sans(self, x509cert):
        """
        Get Subject Alt Names from Certificate. Shameless taken from stack overflow:
        https://stackoverflow.com/users/4547691/anatolii-chmykhalo
        """
        san = ''
        ext_count = x509cert.get_extension_count()
        for i in range(0, ext_count):
            ext = x509cert.get_extension(i)
            if 'subjectAltName' in str(ext.get_short_name()):
                san = ext.__str__()
        # replace commas to not break csv output
        san = san.replace(',', ';')
        return san

    def get_cert_info(self, host, cert):
        """Get all the information about cert and create a JSON file."""
        context = {}

        cert_subject = cert.get_subject()

        context['host'] = host
        context['issued_to'] = cert_subject.CN
        context['issued_o'] = cert_subject.O
        context['issuer_c'] = cert.get_issuer().countryName
        context['issuer_o'] = cert.get_issuer().organizationName
        context['issuer_ou'] = cert.get_issuer().organizationalUnitName
        context['issuer_cn'] = cert.get_issuer().commonName
        context['cert_sn'] = str(cert.get_serial_number())
        context['cert_sha1'] = cert.digest('sha1').decode()
        context['cert_alg'] = cert.get_signature_algorithm().decode()
        context['cert_ver'] = cert.get_version()
        context['cert_sans'] = self.get_cert_sans(cert)
        context['cert_exp'] = cert.has_expired()
        context['cert_valid'] = False if cert.has_expired() else True

        # Valid from
        valid_from = datetime.strptime(cert.get_notBefore().decode('ascii'),
                                       '%Y%m%d%H%M%SZ')
        context['valid_from'] = valid_from.strftime('%Y-%m-%d')

        # Valid till
        valid_till = datetime.strptime(cert.get_notAfter().decode('ascii'),
                                       '%Y%m%d%H%M%SZ')
        context['valid_till'] = valid_till.strftime('%Y-%m-%d')

        # Validity days
        context['validity_days'] = (valid_till - valid_from).days

        # Validity in days from now
        now = datetime.now()
        context['days_left'] = (valid_till - now).days

        # Valid days left
        context['valid_days_to_expire'] = (datetime.strptime(context['valid_till'],
                                           '%Y-%m-%d') - datetime.now()).days

        if cert.has_expired():
            self.total_expired += 1
        else:
            self.total_valid += 1

        # If the certificate has less than 15 days validity
        if context['valid_days_to_expire'] <= 15:
            self.total_warning += 1

        return context

    def print_status(self, host, context):
        """Print all the usefull info about host."""
        print('\t{}[+]{} {}\n\t{}'.format(Clr.GREEN, Clr.RST, host, '-' * (len(host) + 5)))
        print('\t\tIssued domain: {}'.format(context[host]['issued_to']))
        print('\t\tIssued to: {}'.format(context[host]['issued_o']))
        print('\t\tIssued by: {} ({})'.format(context[host]['issuer_o'], context[host]['issuer_c']))
        print('\t\tValid from: {}'.format(context[host]['valid_from']))
        print('\t\tValid to: {} ({} days left)'.format(context[host]['valid_till'], context[host]['valid_days_to_expire']))
        print('\t\tValidity days: {}'.format(context[host]['validity_days']))
        print('\t\tCertificate valid: {}'.format(context[host]['cert_valid']))
        print('\t\tCertificate S/N: {}'.format(context[host]['cert_sn']))
        print('\t\tCertificate SHA1 FP: {}'.format(context[host]['cert_sha1']))
        print('\t\tCertificate version: {}'.format(context[host]['cert_ver']))
        print('\t\tCertificate algorithm: {}'.format(context[host]['cert_alg']))
        print('\t\tExpired: {}'.format(context[host]['cert_exp']))
        print('\t\tCertificate SAN\'s: ')

        for san in context[host]['cert_sans'].split(';'):
            print('\t\t \\_ {}'.format(san.strip()))

        print('\n')

    def show_result(self, args):
        """Get the context."""
        context = {}
        start_time = datetime.now()
        hosts = args

        summary_true=False
        json_true=False
        verbose=False

        self.border_msg(' Analyzing {} host(s) '.format(len(hosts)))

        for host in hosts:
            print('{}Working on host: {}{}\n'.format(Clr.YELLOW, host, Clr.RST))
            host, port = self.filter_hostname(host)

            # Check duplication
            if host in context.keys():
                continue

            try:
                cert = self.get_cert(host, port, args)
                context[host] = self.get_cert_info(host, cert)
                context[host]['tcp_port'] = int(port)

                self.print_status(host, context)
            except SSL.SysCallError:
                print('\t{}[-]{} {:<20s} Failed: Misconfigured SSL/TLS\n'.format(Clr.RED, Clr.RST, host))
                self.total_failed += 1
                return None
            except Exception as error:
                print('\t{}[-]{} {:<20s} Failed: {}\n'.format(Clr.RED, Clr.RST, host, error))
                self.total_failed += 1
                return None
            except KeyboardInterrupt:
                print('{}Canceling script...{}\n'.format(Clr.YELLOW, Clr.RST))
                #sys.exit(1)
                return None

        self.border_msg(' Successful: {} | Failed: {} | Valid: {} | Warning: {} | Expired: {} | Duration: {} '.format(len(hosts) - self.total_failed,self.total_failed, self.total_valid,self.total_warning, self.total_expired,datetime.now() - start_time))
        return context

    def filter_hostname(self, host):
        """Remove unused characters and split by address and port."""
        host = host.replace('http://', '').replace('https://', '').replace('/', '')
        port = 443
        if ':' in host:
            host, port = host.split(':')
        return host, port

if __name__ == '__main__':
	sslobject = SSLCheck()
	hosts = ['github.com','map.fastly.net']
	hosts = ['ic3.gov']
	context = sslobject.show_result(hosts)
	print(context)


# basic imports
import os
import pickle
import numpy as np
# framework imports
from cobel.agents.sfma import SFMAAgent
from cobel.interfaces.gridworld import InterfaceGridworld
from cobel.misc.gridworld_tools import make_open_field
# local imports
from sfma_memory import SFMAMemory

def single_run(world: dict, batch_size: int = 20) -> (list, dict):
    '''
    This method performs a single experimental run, i.e. one experiment.
    It has to be called by either a parallelization mechanism (without visual output),
    or by a direct call (in this case, visual output can be used).

    Parameters
    ----------
    world :                             The gridworld environment that the agent will be trained in.
    batch_size :                        The length of the replay batch.

    Returns
    ----------
    replay :                            A list containing replayed experiences.
    var_trace :                         A dictionary containing traces of the prioritization variables.
    '''
    np.random.seed()
    # a dictionary that contains all employed modules
    modules = {}
    modules['rl_interface'] = InterfaceGridworld(modules, world, False, None)

    # initialize RL agent
    rl_agent = SFMAAgent(interface_OAI=modules['rl_interface'], epsilon=0.1, beta=5, learning_rate=0.9, gamma=0.99, gamma_SR=0.9)
    rl_agent.M = SFMAMemory(modules['rl_interface'], 4, 0.9)
    # common settings
    rl_agent.M.beta = 9
    rl_agent.M.C_step = 1.
    rl_agent.M.reward_mod = True
    rl_agent.M.D_normalize = False
    rl_agent.M.D_normalize = False
    rl_agent.M.R_normalize = True
    rl_agent.M.mode = 'default'
    rl_agent.mask_actions = True
    rl_agent.replays_per_trial = 1

    # initialize experience
    rl_agent.M.C.fill(1.)
    for state in range(world['states']):
        for action in range(4):
            rl_agent.M.states[state, action] = np.argmax(world['sas'][state, action])

    # eventually, allow the OAI class to access the robotic agent class
    modules['rl_interface'].rl_agent = rl_agent

    # generate replay
    replay = rl_agent.M.replay(batch_size, 12)

    return replay, rl_agent.M.var_trace

if __name__ == '__main__':
    # params
    replay_length = 10
    world = make_open_field(5, 5, goal_state=0, reward=1)

    # make sure that the directory for storing the simulation results exists
    os.makedirs('data/', exist_ok=True)

    # run simulations
    replay, var_traces = single_run(world, replay_length)
    pickle.dump(replay, open('data/replay.pkl', 'wb'))
    pickle.dump(var_traces, open('data/var_trace.pkl', 'wb'))


# Given two strings s and t, return true if s is a subsequence of t, or false otherwise.

# A subsequence of a string is a new string that is formed from the original string by deleting some
# (can be none) of the characters without disturbing the relative positions of the remaining characters.
# (i.e., "ace" is a subsequence of "abcde" while "aec" is not).

# Example 1:

# Input: s = "abc", t = "ahbgdc"
# Output: true
# Example 2:

# Input: s = "axc", t = "ahbgdc"
# Output: false

# We know that we need to compare each letter in the smaller string to the larger string
# If the larger string has this letter, set the currLetter to the index of that letter.
#
#
#
#

####    curr_index_s = 1, curr_index_t = 6, valid = 'a'

class Solution(object):
    def isSubsequence(s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """

        curr_index_s = 0
        curr_index_t = 0
        valid_s_letters = ''

        while curr_index_t < len(t) and curr_index_s < len(s):
          if s[curr_index_s] == t[curr_index_t]:
              valid_s_letters += s[curr_index_s]
              curr_index_s += 1
          curr_index_t += 1
        if valid_s_letters == s:
            return True
        else:
          return False


# -*-coding:utf-8 -*

# OUVRIR UN FICHIER AVEC open()
'''
open PREND EN PARAMETRE
-> LE CHEMIN
-> LE MODE D'OUVERTURE
    => 'r' OUVERTURE EN LECTURE (READ)
    => 'w' OUVERTURE EN ECRITURE (WRITE)!!!LE CONTENU DU FICHIER EST ECRASER!!!
    => 'a' OUVERTURE EN MODE AJOUT (APPEND) ON ECRIT A LA FIN DU FIHIER SANS
        L'ECRASER!  AVEC 'w' ET 'a' SI LE FICHIER N'EXISTE PAS IL EST CREE
    ON PEUT AJOUTER A TOUT LES MODES LE SIGNE 'b'POUR L'OUVRIR EN BINAIRE
'''
monFichier = open("8fichier.txt", "r")
print(monFichier) # RENVOIE <_io.TextIOWrapper name='8fichier.txt' mode='r' encoding='UTF-8'>

'''
LA FONCTION open CREE UN FICHIER ET RENVOIE UN OBJET DE CLASSE TextIOWrapper
PAR LA SUITE NOUS ALLONS UTILISER DES METHODES DE CETTE CLASSE,
POUR INTERAGIR AVEC LE FICHIER
'''

# FERMER UN FICHIER AVEC close()
'''
IL NE FAUT PAS OUBLIER DE FERMER UN FICHIER SINON UNE AUTRE PARTIE DU CODE NE PEUT
PAS Y ACCEDER CAR IL EST ENCORE OUVERT
'''
monFichier.close()

# LIRE L'INTEGRALITE DU FICHIER read()
monFichier = open("8fichier.txt", "r")
contenu = monFichier.read()
print(contenu)
monFichier.close()

# LA METHODE read() RENVOIE TOUT LE CONTENU DU FICHIER
# contenu EST MAINTENANT UNE CHAINE NORMAL

print(len(contenu))

# ECRITURE DANS UN FICHIER write()
monFichier = open("8fichier.txt", "w") # J'ECRASE LE CONTENU DU FICHIER
monFichier.write("Premier fois que j'ecrit quelque chose dans un \
fichier et tout ca avec Python")
monFichier.close()

# write() N'ACCEPTE EN PARAMETRES QUE DES CHAINES DE CARACTERES
# LE MODULE "os"  CONTIENT BEAUCOUP DE FOCTION INTERESSANTES POUR TRAVAILER AVEC DES FICHIERS

# LE MOT CLE WITH
'''
with open(monFichier.txt, modeOuverture) as variable:
    - operation sur le fichier

ON TROUE DANS L'ORDRE :
    =>LE MOT-CLE "with" PRELUDE AU BLOC DANS LEQUEL ON VA MANIPULER NOTRE FICHIER
    =>NOTRE OBJET, QU'ON APPLELLE AVEC open ET QUI RENVOIE TextIOWrapper
    =>LE MOT-CLE as QUI SIGNIFIE "EN TANT QUE"
'''

# EXEMPLE
with open("8fichier.txt", "r") as monFichier:
    texte = monFichier.read()

# CELA SIGNIFIE SI UNE EXEPTION EST LEVER LE FICHIER SERA TOUT DE MEME FERMERA LA FIN DU BLOC
# POUR VERIFIER JE PEUX APPELLER monFichier.closed SI LE FICHIER EST FREMER monFichier.closed VAUDRA True
# C'EST RECOMMANDER D'UTILISER CETTE SYNTEX CAR ELLE EST PLUS SURE

# ==> ENREGISTRER DES OBJETS DANS DES FICHIERS - MODULE pickle <==
# IL FAUT DEJA IMPORTER LE MODULE
import pickle
'''
with open("donnees", "wb") as fichier:
    monPickle = pickle.Pickler(fichier)
    #   enregistrement ...
'''
# AU FICHIER ON DONNE PAS EXTANTION ET ON AJOUTE LA LETTRE "b" POUR ECRIRE EN BINAIRE

score = {
    "joueur 1": 5,
    "joueur 2": 35,
    "joueur 3": 20,
    "joueur 4": 2,
}
with open("donnees", "wb") as fichier:
    monPickle = pickle.Pickler(fichier)
    monPickle.dump(score) #AVEC LA METHODE .dump() ON ENREGISTRE DANS LE FICHIER

# => RECUPERER NOS OBBJETS ENREGISTRES

'''
with open("donnees", "rb") as fichier:
    monDepickler = pickle.Unpickler(fichier)
    #   lecture des objets dans le fichier
'''
# POUR LIRE DANS UN FICHIER IL FAUT UTILISER LA METHODE .load()
# ELLE RENVOIE LE PREMIER OBJET QUI ETE LU (SI IL Y ON A PLUSIEUR IL FAUT L'APPELER PLUSIEUR FOIS)

with open("donnees", "rb") as fichier:
    monDepickler = pickle.Unpickler(fichier)
    scoreRecupere = monDepickler.load()

print(scoreRecupere)


from marshmallow import Schema, fields, EXCLUDE
import datetime
from . import db

class ContactModel(db.Model):
  """
  Contact Model
  """

  # table name
  __tablename__ = 'contacts'

  id = db.Column(db.Integer, primary_key=True, autoincrement=True)
  name = db.Column(db.String(128))
  phone = db.Column(db.String(128))
  created_at = db.Column(db.DateTime)
  modified_at = db.Column(db.DateTime)
  deleted = db.Column(db.Boolean(), default=False)

  # class constructor
  def __init__(self, data):
    """
    Class constructor
    """
    self.name = data.get('name')
    self.phone = data.get('phone')
    self.created_at = datetime.datetime.utcnow()
    self.modified_at = datetime.datetime.utcnow()
    self.deleted = False

  def save(self):
    db.session.add(self)
    db.session.commit()

  def update(self, data):
    for key, item in data.items():
      setattr(self, key, item)
    self.modified_at = datetime.datetime.utcnow()
    db.session.commit()

  def delete(self):
    # db.session.delete(self)
    self.deleted = True
    db.session.commit()

  @staticmethod
  def get_all_contacts():
    return ContactModel.query.filter_by(deleted=False)

  @staticmethod
  def get_one_contact(id):
    return ContactModel.query.get(id)

  @staticmethod
  def get_one_contact_number(phone_number):
    exists = db.session.query(db.exists().where(ContactModel.phone == phone_number).where(ContactModel.deleted == False)).scalar()
    return exists

  def __repr(self):
    return '<id {}>'.format(self.id)

class ContactSchema(Schema):
  """
  Contact Schema
  """
  id = fields.Int(dump_only=True)
  name = fields.Str(dump_only=True)
  phone = fields.Str(dump_only=True)
  created_at = fields.DateTime(dump_only=True)
  modified_at = fields.DateTime(dump_only=True)
  deleted = fields.Boolean(dump_only=True)

  class Meta:
        unknown = EXCLUDE


import matplotlib.pyplot as plt
import numpy as np
from scipy.cluster.vq import kmeans
from scipy.stats import zscore

import dp_mix.data.load as load
import dp_mix.models as models

K = 2
data = zscore(load.load_faithful())

num_models = 10
num_updates = 10
# hold objective evaluation for model after each update
objs = np.zeros((num_models, num_updates))

for i in range(num_models):
    # initialize new model
    init_means = kmeans(data, K)[0]
    dp_mix = models.DPMix(data, K, (init_means, np.asarray([1] * K)),
                          np.asarray([[1, .5]] * K), .5, (np.asarray([[0, 0]]), np.asarray([1])))
    # visualize model before and after updates
    dp_mix.plot_data()
    for j in range(num_updates):
        obj = dp_mix._update()
        objs[i, j] = obj
    dp_mix.plot_data()

# plot objective from each run
for i in range(num_models):
    plt.plot(range(10), objs[i])
plt.show()


from tgr_bot.backinfo import weekday_rus, promo_relpace, date_loc_sch_dict, date_gam_sch_dict

def schedule_date_location():
    sc = date_loc_sch_dict()
    text = ''
    for date in sc.keys():
        text += '\n*' + weekday_rus(date) + ' ' + date.strftime('%d.%m') + '*\n'
        for lc in sc[date].keys():
            text += '*' + lc.location_name + '.* ' + lc.location_address + \
                    '.\n' + lc.location_point + '\n'
            for game in sc[date][lc]:
                text += '*с ' + game.schedule_time_begin.strftime('%H:%M') + ' до ' + \
                        game.schedule_time_end.strftime('%H:%M') + '*\n' + \
                        game.game.game_name + '. ' + game.game.game_description + '\n'
    return promo_relpace(text)

def schedule_date_game():
    sc = date_gam_sch_dict()
    text = ''
    for date in sc.keys():
        text += '\n*' + weekday_rus(date) + ' ' + date.strftime('%d.%m') + '*\n'
        for game in sc[date].keys():
            text += 'Игры *' + game.game_name + '.* ' + game.game_description + '.\n'
            for sch in sc[date][game]:
                text += '*с ' + sch.schedule_time_begin.strftime('%H:%M') + ' до ' + \
                        sch.schedule_time_end.strftime('%H:%M') + '*\n' + \
                        sch.location.location_name + '. ' + sch.location.location_address + '\n' + \
                        sch.location.location_point + '\n'
    return promo_relpace(text)


import logging,os
from Common.handle_config import conf
from Common.handle_path import logs_dir
class HandleLog:

    def __init__(self,name, path):
        # 创建一个日志收集器
        self.logger = logging.getLogger(name)
        self.logger.setLevel(logging.INFO)
        self.stream_handle = logging.StreamHandler()
        self.file_handle = logging.FileHandler(path, encoding="utf-8")
        fmt = ' %(asctime)s-%(name)s-%(levelname)s-%(filename)s-%(lineno)dline-日志信息: %(message)s '
        self.stream_handle.setFormatter(logging.Formatter(fmt))
        self.file_handle.setFormatter(logging.Formatter(fmt))
        self.logger.addHandler(self.stream_handle)
        self.logger.addHandler(self.file_handle)

    def get_logger(self):
        return self.logger

    def __del__(self):
        self.logger.removeHandler(self.stream_handle)
        self.logger.removeHandler(self.file_handle)
        self.stream_handle.close()
        self.file_handle.close()

if conf.getboolean("log", "file_ok"):
    file_path = os.path.join(logs_dir, conf.get("log", "file_name"))
else:
    file_path = None

mlogger = HandleLog(conf.get("log", "name"),file_path)
logger = mlogger.get_logger()
logger.info("测试日志")