import os
import dash
import pandas as pd
from dash import dcc, html, callback, Input, Output
import plotly.express as px
import plotly.graph_objects as go
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
from dateutil.relativedelta import relativedelta

dash.register_page(
    __name__,
    path='/outcomes-by-breed',
    title="Outcomes by Breed",
    name="Outcomes by Breed"
)

DATAPATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../data")

# data transformation
df = pd.read_csv(os.path.join(DATAPATH,"animal-shelter-data.csv"), index_col=False)
df["outcome_age_(months)"] = round(df["outcome_age_(days)"]/30)
df["raw_date"] = df["datetime"].str.split(' ').str[0]
df["Date"] = pd.to_datetime(df.raw_date)
df['Month'] = df['Date'].dt.month_name()
df['Year'] = df['Date'].dt.strftime('%Y')
df['Month_Year'] = df['Month']+'-'+df['Year'].astype(str)

# values for date pickers
start_date = min(df["Date"])
end_date = pd.Timestamp(start_date.date() + relativedelta(months=+12))

# values for dropdown menus
sexes = df['sex_upon_outcome'].unique().tolist()
colours = df['color'].unique().tolist()
outcomes = df['outcome_type'].unique().tolist()

# fifth page content
layout = html.Div([
    html.H3("Outcomes by Breed"),
    html.Hr(),

    # row for user-selections for graphs
    dbc.Row([
        dbc.Col([
            dcc.DatePickerRange(
                id="date-picker-range",
                start_date = start_date,
                min_date_allowed = min(df["Date"]),
                end_date = end_date,
                max_date_allowed = max(df["Date"]),
                persistence=True, persistence_type="local"
            )
        ], width=3),
        dbc.Col([
            html.Label("Age on outcome (months)"),
            dcc.RangeSlider(
                id="range-slider-age",
                min=min(df['outcome_age_(months)']),
                max=max(df['outcome_age_(months)']),
                value=[min(df['outcome_age_(months)']), 24],
                tooltip={"placement": "bottom", "always_visible": True},
                persistence=True, persistence_type="local"
            )
        ], width=5),
        dbc.Col([
            dbc.Switch(
                id="cfa-switch",
                label="CFA breeds",
                value=True,
                inputClassName = None,
                persistence=True, persistence_type="local"
            )
        ], width=2),
        dbc.Col([
            dcc.Dropdown(
                id="dropdown-colour",
                options=colours,
                placeholder="Select colour",
                multi=True,
                persistence=True, persistence_type="local"
            )
        ], width=2)
    ]),
    dbc.Tooltip(
        "Filter by date of outcome",
        target="date-picker-range"
    ),

    # row for graph
    dbc.Row([
        dbc.Col([
            dbc.Spinner(children=[dcc.Graph(id='scatter-graph-breed')], color='secondary')
        ])
    ])
])

# callback to update change colour of Switch component to gray
@callback(Output('cfa-switch', 'inputClassName'),
            Input('cfa-switch', 'value'))
def update_switch(activated):
    if activated:
        return 'bg-secondary',
    return None

@callback(Output("scatter-graph-breed", "figure"),
            [Input("date-picker-range", "start_date"),
            Input("date-picker-range", "end_date"),
            Input("range-slider-age", "value"),
            Input("dropdown-colour", "value"),
            Input("cfa-switch", "value")])
def update_scatter_chart(start_date, end_date, slider_value, dropdown2_value, switch_value):
    # filter by slider selection
    strip = df[(df['outcome_age_(months)'] >= slider_value[0]) & (df['outcome_age_(months)'] <= slider_value[1])]

    # filter by dropdown selection
    if (dropdown2_value != None):
        if (len(dropdown2_value) > 0):
            strip = strip[strip['color'].isin(dropdown2_value)]

    # create new groupby data table with appropriate values for strip chart
    strip = strip[(strip['Date'] >= start_date) & (strip['Date'] <= end_date)]
    strip = strip[strip['cfa_breed'] == switch_value]

    final = pd.DataFrame(strip.groupby(['breed', 'outcome_type', 'sex_upon_outcome'], as_index=False)['count'].count())

    fig = px.scatter(final, x="breed", y="outcome_type", size='count', color="sex_upon_outcome",
        color_discrete_sequence=px.colors.qualitative.Light24)
    fig.update_layout(autosize=False, width=1600, height=650)
    fig.update_layout({'plot_bgcolor': 'rgba(0, 0, 0, 0)', 'paper_bgcolor': 'rgba(0, 0, 0, 0)'})

    return fig


# https://leetcode.com/problems/strictly-palindromic-number/

class Solution:

    def isStrictlyPalindromic(self, n: int) -> bool:

        def convertToBase(n, base):
            string = ""
            while n:
                string+=str(n%base)
                n = n//base

            # string is number in base given

            # check if string is palindrome
            return string[::-1]==string

        for i in range(2, n-2+1):
            # If the condition is False, then the number is not strictly palindromic
            if convertToBase(n, i) == False:
                return False

        return True

"""
Intuition

The condition is extreme hard to satisfy, think about it...
for every base b between 2 and n - 2...
4 is not strictly palindromic number
5 is not strictly palindromic number
..
then the bigger, the more impossible.
Just return false

Prove

4 = 100 (base 2), so 4 is not strictly palindromic number
for n > 4, consider the base n - 2.
In base n - 1, n = 11.
In base n - 2, n = 12, so n is not strictly palindromic number.

There is no strictly palindromic number n where n >= 4

More

I think it may make some sense to ask if there a base b
between 2 and n - 2 that n is palindromic,
otherwise why it bothers to mention n - 2?

It's n - 2, not n - 1,
since for all n > 1,
n is 11 in base n - 2.
(Because n = (n - 1) + (1))

Then it's at least a algorithme problem to solve,
instead of a brain-teaser.

Maybe Leetcode just gave a wrong description.

"""


import ctk
import qt
import slicer
from MRTrackingUtils.qcomboboxcatheter import *

class MRTrackingPanelBase():
  def __init__(self, label="Base"):

    self.label = label
    self.catheters = None     #CatheterCollection
    self.currentCatheter = None

  def setCatheterCollection(self, cath):

    self.catheters = cath

  def buildGUI(self, parent, showCatheterSelector=True):
    parentLayout = qt.QVBoxLayout(parent)

    # Catheter selector
    self.catheterComboBox = QComboBoxCatheter()
    self.catheterComboBox.setCatheterCollection(self.catheters)
    self.catheterComboBox.currentIndexChanged.connect(self.onCatheterSelected)

    if showCatheterSelector:
      selectorLayout = qt.QFormLayout(parent)
      parentLayout.addLayout(selectorLayout)
      selectorLayout.addRow("Catheter: ", self.catheterComboBox)

    # Main panel
    mainPanelFrame = qt.QFrame(parent)
    parentLayout.addWidget(mainPanelFrame)
    self.buildMainPanel(mainPanelFrame)

  def onCatheterSelected(self):
    self.currentCatheter = self.catheterComboBox.getCurrentCatheter()
    self.onSwitchCatheter()

  def switchCatheter(self, name):
    col = self.catheterComboBox.collection
    if col:
      index = col.getIndex(name)
      if index >= 0:
        self.catheterComboBox.setCurrentIndex(index)
    self.onCatheterSelected()

  def switchCatheterByIndex(self, index):
    col = self.catheterComboBox.collection
    if col:
      if index >= 0 and index < col.getNumberOfCatheters():
        self.catheterComboBox.setCurrentIndex(index)
    self.onCatheterSelected()

  def buildMainPanel(self, frame):
    #
    # Should be implemented in the child class
    #
    pass

  def onSwitchCatheter(self):
    #
    # Should be implemented in the child class
    #
    pass


import odoo.addons.decimal_precision as dp
from odoo import api, fields, models

class AccountAnalyticAccount(models.Model):

    _inherit = 'account.analytic.account'

    @api.multi
    def _compute_wip_report(self):
        res = super(AccountAnalyticAccount, self)._compute_wip_report()
        for account in self:
            # Estimated gross profit percentage
            try:
                account.estimated_gross_profit_per = (
                    account.estimated_gross_profit /
                    account.total_value * 100)
            except ZeroDivisionError:
                account.estimated_gross_profit_per = 0
            # Over/Under billings
            over_under_billings =\
                account.under_billings - account.over_billings
            account.under_over = over_under_billings

            # # PAID Analytic Line
            # the problem is receivable lines without analytic account
            # that was before I introduce the hack into Odoo for that. So I have
            # to go to the invoice and then the lines
            actual_paid_line_ids = []
            invoices = []
            for line_id in account.actual_billings_line_ids:
                invoice = line_id.sudo().move_id.move_id
                if not invoice:
                    continue
                if invoice in invoices:
                    # several income lines in the same invoice, do not count it twice
                    continue
                invoices.append(invoice)
                # Issue: if invoices are mixing projects and the receivable line
                # mix several projects. Those lines are not counted
                # We can count the ones for the same project (using this
                # branch https://github.com/ForgeFlow/odoo/tree/10.0-ap_ar_analytic)
                # or we can trust the manual label in the journal item is the code
                # of the project. Or if the balance is the same as the income line
                rec_lines = invoice.mapped("line_ids").filtered(
                    lambda l: 'Receivable' in l.account_id.user_type_id.name and (
                        l.name == account.code or l.analytic_account_id == account or (
                        not l.name and abs(l.balance) == abs(line_id.balance))))
                account.actual_paid += sum([l.balance for l in rec_lines])
                # the total paid is the balance less the residual amount
                rec_lines_company_curr = rec_lines.filtered(lambda l: not l.currency_id)
                account.actual_paid -= sum(rec_lines_company_curr.mapped("amount_residual"))
                rec_lines_other_curr = rec_lines.filtered(lambda l: l.currency_id)
                account.actual_paid -= sum(rec_lines_other_curr.mapped("amount_residual_currency"))
                actual_paid_line_ids.extend(rec_lines.ids)

            account.actual_paid_line_ids = [
                (6, 0, [l for l in actual_paid_line_ids])]
        return res

    estimated_gross_profit_per = fields.Float(
        compute='_compute_wip_report',
        string='Total Value',
        help="""Estimated gros profit percentage
             (estimated gross profit/total contract value)""",
        digits=dp.get_precision('Account')
    )
    under_over = fields.Float(
        compute='_compute_wip_report',
        help="""Total under/over (under_billed-over_billed)"""
    )
    actual_paid = fields.Float(
        compute='_compute_wip_report',
        string='Paid to date',
        help="""Total paid amount from the customer to date""",
        digits=dp.get_precision('Account')
    )
    actual_paid_line_ids = fields.Many2many(
        comodel_name="account.analytic.line",
        compute='_compute_wip_report',
        string='Detail',
    )

    @api.multi
    def action_open_move_lines(self):
        line = self
        bill_lines = [x.id for x in line.actual_paid_line_ids]
        res = self.env['ir.actions.act_window'].for_xml_id(
            'account', 'action_account_moves_all_a')
        res['domain'] = "[('id', 'in', ["+','.join(
            map(str, bill_lines))+"])]"
        return res


# 1)Python veri türleri

int, float, complex #sayılar => tam sayı(int), ondalık sayı(float),karmasık sayılar(complex)

list #diziler => degistirebilir bir sıralı veri türüdür. farklı veri tipleri alabilir

tuple #demetler => değiştirilemez bir sıralı veri türüdür. farklı veri tipleri alabilir

set # =>degistirilebilir elemanları sıralı olmayan bir koleksiyon türüdür

str #string => metinsel elemanlar için kullanılır.

bool #=> true ya da false değerlerini saklar.

# 2) Kodlama.io sitesinde değişken olarak kullanıldığını düşündüğünüz verileri, veri tipleriyle birlikte örneklendiriniz.

#öncelikle değişkenin adını belirleyip adın sag tarafına atama işlemi kullanarak deger atamamız gerekiyor ( x = 3)

#kamptaki ilerleme durumunu örnek alabiliriz
#ilk önce dersi izlediysek sonraki aşamaya yani ödevlere yönlendirecektir (dersDurum=0)
#ödevler yapıldı mı (true) ise % olarak ilerleyecek, yapılmadıysa (false) % sabit kalacaktır
#ilk aşama tamamlandıysa %100(int) olarak tamamlandı yazıp diğer bölüme yönlendirilecektir. (ilerleme=100%)

# 3) python sart blokları örneği
kullaniciadi="kodlamaio"
sifre=12345

kAdi=input("kullanıcı adınızı giriniz")
kSifre = int(input("sifre giriniz"))

if(kullaniciadi==kAdi and sifre==kSifre):
    print("kullanıcı adı ve sifrenin dogrudur hosgeldiniz")
else:
    print("hatalı giriş yaptınız")


class Solution:
    def multiply(self, num1: str, num2: str) -> str:
        sti = "0123456789"
        numarr = [*range(10)]
        cache = {}
        resarr = []
        for index, digit in enumerate(num1[::-1]):
            carry_over = 0
            output = []
            if digit not in cache:
                d1 = numarr[sti.index(digit)]
                for di2 in num2[::-1]:
                    res = d1 * numarr[sti.index(di2)] + carry_over
                    carry_over = res//10
                    output.append(res%10)
                if carry_over:
                    output.append(carry_over)
                cache[digit] = output
            else:
                output = cache[digit]
            resarr += [[0]*index + output]
        ml = len(max(resarr,key=len))
        resarr = [i+[0]*(ml-len(i)) for i in resarr]
        carry_over = 0
        res = []
        for i in zip(*resarr):
            r = sum(i) + carry_over
            res += [r%10]
            carry_over = r//10
        if carry_over:
            res += [carry_over]
        if len(set(res)) == 1  and res[0]==0:
            return"0"
        return "".join(map(str,res[::-1]))

x = Solution()
print( x.multiply("9133","0") )
print(99*99)


from django.shortcuts import render, get_object_or_404
from news.models import MyNewsFb
# Create your views here.

def homeview(request):
    posts = MyNewsFb.objects.all()
    context = {
        'posts': posts
    }
    return render(request, 'index.html', context=context)

def postdetail(request, id):
    post = get_object_or_404(MyNewsFb, pk=id)
    context = {
        'post': post,
    }
    return render(request, 'detailpost.html', context=context)


"""Define common method for [de]serializing NumPyArray"""
from __future__ import absolute_import

import zlib
import numpy as np

__all__ = ['serialize_numpy_array', 'deserialize_numpy_array']

def serialize_numpy_array(array, compress=True):
    """Serialize NumPy ND Array into JSON format

    Parameters
    ----------
    array : NumPy ND Array
        Array to serialize
    compress : bool
        When True, array data are compressed. Default: True.

    Returns
    -------
    dict
        Serialized array

        shape : list
            array shape
        dtype : str
            dtype
        data : byte string
            actual data
        compressed : bool
            Indicates if data is compressed
    """
    str_ = array.tostring()
    if compress:
        str_ = zlib.compress(str_)
    return {
        'shape': array.shape,
        'dtype': array.dtype.name,
        'data': str_.encode('base64'),
        'compressed': compress,
    }

def deserialize_numpy_array(obj):
    """Deserialize NumPy ND Array from JSON format

    Parameters
    ----------
    obj : dict
        See `serialize_numpy_array` for the detail.

    Returns
    -------
    NumPy ND Array
        Resulting array
    """
    data = obj['data'].decode('base64')
    if obj['compressed']:
        data = zlib.decompress(data)
    array = np.fromstring(data, dtype=obj['dtype'])
    return array.reshape(obj['shape'])


import json
from unittest.mock import Mock

import numpy as np
import pytest

from atldld.sync import (
    DatasetDownloader,
    DatasetNotFoundError,
    RMAParameters,
    get_parallel_transform,
    pir_to_xy,
    xy_to_pir,
)

class TestGetParallelTransform:
    @pytest.mark.parametrize(
        "downsample_ref", [25, 50]
    )  # p, i, r are divisble by these
    def test_local_equals_API(self, pir_to_xy_response, downsample_ref):
        p = pir_to_xy_response["p"]
        i = pir_to_xy_response["i"]
        r = pir_to_xy_response["r"]

        axis = pir_to_xy_response["axis"]

        x = pir_to_xy_response["x"]
        y = pir_to_xy_response["y"]

        affine_2d = np.array(pir_to_xy_response["affine_2d"])
        affine_3d = np.array(pir_to_xy_response["affine_3d"])

        if axis == "coronal":
            assert i % downsample_ref == 0
            assert r % downsample_ref == 0

            slice_coordinate = p
            grid_shape = (8000 / downsample_ref, 11400 / downsample_ref)

        elif axis == "sagittal":
            assert p % downsample_ref == 0
            assert i % downsample_ref == 0

            slice_coordinate = r
            grid_shape = (13200 / downsample_ref, 8000 / downsample_ref)

        else:
            raise ValueError

        df = get_parallel_transform(
            slice_coordinate,
            affine_2d,
            affine_3d,
            axis=axis,
            downsample_ref=downsample_ref,  # the goal is to reduce computation
        )

        tx, ty = df.transformation

        assert tx.shape == grid_shape
        assert ty.shape == grid_shape

        # Asserts single pixel

        if axis == "coronal":
            i_ = int(i // downsample_ref)
            r_ = int(r // downsample_ref)

            x_pred, y_pred = tx[i_, r_], ty[i_, r_]
        elif axis == "sagittal":
            p_ = int(p // downsample_ref)
            i_ = int(i // downsample_ref)

            x_pred, y_pred = tx[p_, i_], ty[p_, i_]

        assert x_pred == pytest.approx(x, abs=1e-2)
        assert y_pred == pytest.approx(y, abs=1e-2)

class TestDatasetDownloader:
    def test_invalid_dataset(self, monkeypatch):
        # If `rma_all` returns an empty list, the API does not have any entries
        # satisfying the parameters

        mock_rma_all = Mock(return_value=[])
        monkeypatch.setattr("atldld.sync.rma_all", mock_rma_all)

        downloader = DatasetDownloader(
            dataset_id=434324132413241,
        )
        with pytest.raises(DatasetNotFoundError, match="does not seem to exist"):
            downloader.fetch_metadata()

    @pytest.mark.parametrize("include_expression", [True, False])
    def test_patched(self, include_expression, data_folder, monkeypatch):
        """Does not require internet, everything is patched."""

        # Parameters
        dataset_id = 123  # Sagittal dataset
        downsample_ref = 25
        grid_shape = (13200 // downsample_ref, 8000 // downsample_ref)

        # Mocking
        def mock_rma_all(value):
            parameters_dataset = RMAParameters(
                model="SectionDataSet",
                criteria={
                    "id": dataset_id,
                },
                include=["alignment3d"],
            )
            parameters_images = RMAParameters(
                model="SectionImage",
                criteria={
                    "data_set_id": dataset_id,
                },
                include=["alignment2d"],
            )
            if value == parameters_dataset:
                with open(data_folder / "rma_all" / "SectionDataSet.json") as f:
                    data = json.load(f)
                return [
                    data,
                    None,
                ]  # We extract only the first element of the list here.
            elif value == parameters_images:
                with open(data_folder / "rma_all" / "SectionImage.json") as f:
                    data = json.load(f)
                return [
                    data,
                ]  # In a list because can have several images
            else:
                raise ValueError("Not expected")

        fake_rma_all = Mock(side_effect=mock_rma_all)
        fake_get_image = Mock(return_value=np.zeros(grid_shape))
        monkeypatch.setattr("atldld.sync.rma_all", fake_rma_all)
        monkeypatch.setattr("atldld.sync.get_image", fake_get_image)

        # Call the function
        downloader = DatasetDownloader(
            dataset_id=dataset_id,
            include_expression=include_expression,
            downsample_ref=downsample_ref,
        )
        downloader.fetch_metadata()
        gen = downloader.run()

        # Asserts - first iteration
        x = next(gen)
        assert len(x) == 5

        img_id, slice_coordinate, img, img_expression, df = x

        assert img_id == 101945191
        if include_expression:
            assert isinstance(img_expression, np.ndarray)
        else:
            assert img_expression is None
        assert df.delta_x.shape == grid_shape
        assert df.delta_y.shape == grid_shape

        # Asserts remaining
        with pytest.raises(StopIteration):
            next(gen)

    def test_metadata(self):
        """Test metadata"""
        # Parameters
        dataset_id = 123
        include_expression = True
        downsample_ref = 25

        # Call the function
        downloader = DatasetDownloader(
            dataset_id=dataset_id,
            include_expression=include_expression,
            downsample_ref=downsample_ref,
        )

        with pytest.raises(RuntimeError):
            len(downloader)

        with pytest.raises(RuntimeError):
            gen = downloader.run()
            _ = next(gen)

        metadata = {"test": True}
        downloader.metadata = metadata
        downloader.fetch_metadata()
        # As metadata exists, check that did not fetch metadata
        assert downloader.metadata == metadata

        # Create very small metadata
        downloader.metadata = {}
        downloader.metadata["images"] = list(np.arange(10))
        downloader.metadata["dataset"] = {}
        downloader.metadata["dataset"]["plane_of_section_id"] = 3

        # Check that len is working correctly
        assert len(downloader) == 10

        # Raise ValueError because plane_of_section_id in {1, 2}
        with pytest.raises(ValueError, match="Unrecognized plane"):
            gen = downloader.run()
            next(gen)

        # Check that everything working fine if plane_of_section_id = 1
        downloader.metadata["dataset"]["plane_of_section_id"] = 1

def test_pir_to_xy(pir_to_xy_response):
    coords_ref = np.array(
        [
            pir_to_xy_response["p"],
            pir_to_xy_response["i"],
            pir_to_xy_response["r"],
        ]
    )[
        :, None
    ]  # (3, 1)

    coords_img_API = np.array([pir_to_xy_response["x"], pir_to_xy_response["y"]])[
        :, None
    ]  # We do not care about the section coordinate

    coords_img_local = pir_to_xy(
        coords_ref,
        np.array(pir_to_xy_response["affine_2d"]),
        np.array(pir_to_xy_response["affine_3d"]),
    )[:2]

    assert np.allclose(coords_img_API, coords_img_local, rtol=0, atol=1e-3)

def test_xy_to_pir(xy_to_pir_response):
    coords_img = np.array(
        [
            xy_to_pir_response["x"],
            xy_to_pir_response["y"],
            xy_to_pir_response["section_number"]
            * xy_to_pir_response["section_thickness"],
        ]
    )[
        :, None
    ]  # (3, 1)

    coords_ref_API = np.array(
        [
            xy_to_pir_response["p"],
            xy_to_pir_response["i"],
            xy_to_pir_response["r"],
        ]
    )[:, None]

    coords_ref_local = xy_to_pir(
        coords_img,
        np.array(xy_to_pir_response["affine_2d"]),
        np.array(xy_to_pir_response["affine_3d"]),
    )

    assert np.allclose(coords_ref_API, coords_ref_local, rtol=0, atol=1e-3)


#! /usr/bin/env python3

"""
Tests functionality of :class: `paper_sorts.DatabaseConnector`.
"""

import unittest
import logging

from paper_sorts.database_connector import DatabaseConnector
from paper_sorts.config_reader import ConfigReader

class DataBaseTest(unittest.TestCase):
    """
    Tests adding, searching, updating and deleting functionality, but doesn't cover a significant amount of code.
    """
    def test_search_by_author(self):
        """ Test if an entry know to be in the database can be found if searched for by author name."""
        config_reader = ConfigReader("../../database.crypt", "postgresql", "../../key")
        database = DatabaseConnector(
            config_reader.db_config,
            logging.DEBUG,
            "database_tester_logger",
            log_file="db_connector_test.log",
        )
        author_search = database.search_by_author("Pino, J.")
        self.assertEqual(
            author_search[0][3],
            "Large-scale Self- an Semi-Supervised learning for speech translation",
        )
        self.assertEqual(author_search[0][4], "Wang2021LargeScaleSA")
        self.assertRaises(KeyError, database.search_by_author, "no author")

    def test_search_by_title(self):
        """ Test if an entry know to be in the database can be found if searched for by publication title."""
        config_reader = ConfigReader("../../database.crypt", "postgresql", "../../key")
        database = DatabaseConnector(
            config_reader.db_config,
            logging.DEBUG,
            "database_tester_logger",
            log_file="db_connector_test.log",
        )
        self.assertEqual(
            database.search_by_title(
                "Direct speech-to-speech translation with discrete units"
            )[0][0],
            "Lee, Ann and Chen, Peng-Jen and Wang, Changhan and Gu, Jiatao and Ma, Xutai and Polyak, A. and Adi, Yossi "
            "and He, Qing and Tang, Yun and Pino, J. and Hsu, Wei-Ning",
        )
        self.assertRaises(KeyError, database.search_by_title, "no title")

    def test_adding_and_removing(self):
        """Test whether an entry can be added and removed from the database safely. """
        config_reader = ConfigReader("../../database.crypt", "postgresql", "../../key")
        database = DatabaseConnector(
            config_reader.db_config,
            logging.DEBUG,
            "database_tester_logger",
            log_file="db_connector_test.log",
        )

        self.assertRaises(
            ValueError,
            database.delete_paper_entry_from_database,
            "test",
            ["list_add_and_remove"],
            "x",
            "This is a remove test",
            "This is a test",
        )
        self.assertTrue(
            database.add_entry_to_db(
                "test",
                ["list_add_and_remove"],
                "x",
                "This is an add test",
                "This is a test",
            )
        )
        self.assertRaises(
            ValueError,
            database.add_entry_to_db,
            "test",
            ["list"],
            "x",
            "This is an add test",
            "This is a test",
        )
        self.assertTrue(
            database.delete_paper_entry_from_database(
                "test",
                ["list_add_and_remove"],
                "x",
                "This is an add test",
                "This is a test",
            )
        )

    def test_update_title(self):
        """Test whether the summary of an entry in the database can be updated safely. """
        config_reader = ConfigReader("../../database.crypt", "postgresql", "../../key")
        database = DatabaseConnector(
            config_reader.db_config,
            logging.DEBUG,
            "database_tester_logger",
            log_file="db_connector_test.log",
        )
        database.add_entry_to_db(
            "test",
            ["list_update_title"],
            "x",
            "This is an update title test",
            "This is a test",
        )
        paper_id = database.database_handler.fetch_from_db(
            "select id from papers where title='This is an update title test';"
        )[0][0]
        database.update_entry(
            "title",
            "updated title",
            "papers",
            paper_id
        )
        self.assertEqual(
            database.search_by_title(
                "updated title"
            )[0][0],
            "list_update_title",
        )
        database.update_entry(
            "contents",
            "updated contents",
            "papers",
            paper_id
        )
        self.assertEqual(
            database.database_handler.fetch_from_db(
                "select contents from papers where id=%s;",
                (paper_id, )
            )[0][0],
            "updated contents"
        )
        database.delete_paper_entry_from_database(
            "test",
            ["list_update_title"],
            "x",
            "updated title",
            "updated contents",
        )
        self.assertRaises(
            ValueError,
            database.update_entry,
            "test",
            "should not work",
            "papers",
            "This is a test",
        )
        self.assertRaises(
            ValueError,
            database.update_entry,
            "test",
            "should not work",
            "non-table",
            "This is a test",
        )

    def test_update_authors_papers(self):
        """ Test whether the author-paper relation of an entry cannot be changed."""
        config_reader = ConfigReader("../../database.crypt", "postgresql", "../../key")
        database = DatabaseConnector(
            config_reader.db_config,
            logging.DEBUG,
            "database_tester_logger",
            log_file="db_connector_test.log",
        )
        self.assertRaises(
            ValueError,
            database.update_entry,
            "test",
            "should not work",
            "authors_papers",
            "This is a test",
        )

    def test_update_authors(self):
        """ Test whether the authorship of a paper can be changed as expected.."""
        config_reader = ConfigReader("../../database.crypt", "postgresql", "../../key")
        database = DatabaseConnector(
            config_reader.db_config,
            logging.DEBUG,
            "database_tester_logger",
            log_file="db_connector_test.log",
        )

        database.add_entry_to_db(
            "test",
            ["list_update_authors"],
            "x",
            "This is an update author test",
            "This is a test",
        )

        author_id = database.database_handler.fetch_from_db(
                "select id from authors_id where author='list_update_authors'",
        )[0][0]
        papers = database.database_handler.fetch_from_db(
                "select paper_id from authors_papers where author_id=%s;",
                (author_id, )
        )
        database.update_entry(
            "author",
            "changed_authors",
            "authors_id",
            "list_update_authors"
        )
        author_id = database.database_handler.fetch_from_db(
                "select id from authors_id where author='changed_authors'",
        )[0][0]

        self.assertEqual(
            database.database_handler.fetch_from_db(
                "select  paper_id from authors_papers where author_id=%s;",
                (author_id, )
            ),
            papers
        )
        self.assertTrue(
            database.delete_paper_entry_from_database(
                "test",
                ["changed_authors"],
                "x",
                "This is an update author test",
                "This is a test",
            )
        )
        database.add_entry_to_db(
            "test",
            ["list_update_authors"],
            "x",
            "This is a test number 2",
            "This is a test",
        )
        database.add_entry_to_db(
            "another test",
            ["new list"],
            "u",
            "This is a another test",
            "something",
        )
        database.update_entry(
            "author",
            "new list",
            "authors_id",
            "list_update_authors"
        )
        self.assertTrue(
            database.delete_paper_entry_from_database(
                "test",
                ["new list"],
                "x",
                "This is a test number 2",
                "This is a test",
            )
        )
        self.assertTrue(
            database.delete_paper_entry_from_database(
                "another test",
                ["new list"],
                "u",
                "This is a another test",
                "something",
            )
        )
        self.assertRaises(
            ValueError,
            database.update_entry,
            "nonexistent column",
            "new list",
            "authors_id",
            "list_update_authors"
        )

    def test_update_bib(self):
        """ Test whether the content of one bibliography entry can be changed. """
        config_reader = ConfigReader("../../database.crypt", "postgresql", "../../key")
        database = DatabaseConnector(
            config_reader.db_config,
            logging.DEBUG,
            "database_tester_logger",
            log_file="db_connector_test.log",
        )
        database.add_entry_to_db(
            "test",
            ["list"],
            "x",
            "This is a bib test",
            "This is a test",
        )
        database.update_entry(
            "bibtex",
            "y",
            "bib",
            "x"
        )
        self.assertEqual(
            database.database_handler.fetch_from_db(
                "select bibtex from bib where bibtex_id='x';"
            )[0][0],
            "y"
        )
        self.assertRaises(
            ValueError,
            database.update_entry,
            "bibtex",
            "y",
            "bib",
            "x"
        )
        self.assertTrue(
            database.delete_paper_entry_from_database(
                "y",
                ["new list"],
                "x",
                "This is a bib test",
                "This is a test",
            )
        )
        self.assertRaises(
            ValueError,
            database.update_entry,
            "nonexistent",
            "y",
            "bib",
            "x"
        )

if __name__ == "__main__":
    unittest.main()


import numpy as np
import pandas as pd

left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
                     'B': ['B0', 'B1', 'B2']},
                    index=['K0', 'K1', 'K2'])
right = pd.DataFrame({'C': ['C0', 'C2', 'C3'],
                      'D': ['D0', 'D2', 'D3']},
                     index=['K0', 'K2', 'K3'])
res = pd.merge(left, right, left_index=True, right_index=True,
               how='outer')  # 根据index索引进行合并 并选择外联合并
print(res)
res = pd.merge(left, right, left_index=True, right_index=True, how='inner')
print(res)


from robotpageobjects import Page, Component, robot_alias, Override
from robot.utils import asserts

class ResultComponent(Component):

    selectors = {
        "price el": "css=div.price",
    }

    @property
    def price(self):
        return self.get_text("price el")

class ResultPage(Page):
    components = {ResultComponent: "css=ul#results li.result"}

    uri = "/site/result.html"

class ResultPageWithDOMStrategyLocator(Page):
    components = {ResultComponent: "dom=window.jQuery('#results li.result:lt(2)')"}

    uri = "/site/result.html"

class AdvancedOptionTogglerComponent(Component):

    selectors = {
        # In relation to reference webelement, which is sibling.
        "advanced options": "xpath=./following-sibling::p[1]",
    }

    def open(self):
        self.reference_webelement.click()

    @property
    def advanced_text(self):
        return self.get_text("advanced options")

class BaseSearchComponent(Component):

    selectors = {
        "search input": "id=q",
    }

    def set_search_term(self, term):
        self.input_text("search input", term)

class SearchComponent(BaseSearchComponent):
    components = {AdvancedOptionTogglerComponent: "id=advanced-options"}

    @property
    def some_property(self):
        self.log("foo", is_console=False)
        return 1

class SearchComponentWithDOMAdvancedToggler(BaseSearchComponent):
    components = {AdvancedOptionTogglerComponent: "dom=jQuery('#advanced-options')"}

class HomePage(Page):
    components = {SearchComponent: "id=search-form"}
    uri = "/site/index.html"

    def get_some_property(self):
        return self.search.some_property

class HomePageWithDOMAdvancedToggler(Page):
    components = {SearchComponentWithDOMAdvancedToggler: "id=search-form"}
    uri = "/site/index.html"

class BodyComponent(Component):
    pass

class ParaComponent(Component):
    pass

class TwoComponentsPage(Page):
    components = {BodyComponent: "css=body", ParaComponent: "css=p"}
    uri = "/site/index.html"

class TwoComponentsSubPage(TwoComponentsPage):
    components = {Override(ParaComponent): "css=p#advanced-search-content"}


class MagicDictionary(object):

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.word_dict = {}
        self.change_word_dict = {}

    def buildDict(self, dictionary):
        """
        :type dictionary: List[str]
        :rtype: None
        """
        for word in dictionary:
            self.word_dict[word] = 1
            for index in range(len(word)):
                tmp = word[:index] + '*' + word[index + 1:]
                # 统计替换字符的字典
                self.change_word_dict[tmp] = self.change_word_dict.get(tmp, 0) + 1

    def search(self, searchWord):
        """
        :type searchWord: str
        :rtype: bool
        """

        print(self.change_word_dict)
        print(self.word_dict)
        for index in range(len(searchWord)):
            tmp = searchWord[:index] + '*' + searchWord[index + 1:]
            # 查看 查找字符 替换一个字符 是否存在之前的字典中
            # self.word_dict.get(searchWord, 0) 防止 查找字符串就是 存储字符串
            if self.change_word_dict.get(tmp, 0) - self.word_dict.get(searchWord, 0) > 0:
                print(self.change_word_dict)
                print(self.word_dict)
                return True

        return False

if __name__ == '__main__':
    obj = MagicDictionary()
    obj.buildDict(["hello"])
    param_2 = obj.search('hhllo')


from solentware_base.core.constants import (
    PRIMARY,
    SECONDARY,
    BTOD_FACTOR,
    DEFAULT_RECORDS,
    DEFAULT_INCREASE_FACTOR,
    BTOD_CONSTANT,
    DDNAME,
    FILE,
    FIELDS,
    FILEDESC,
    INV,
    ORD,
    RRN,
    BRECPPG,
    FILEORG,
    DPT_PRIMARY_FIELD_LENGTH,
)
import solentware_base.core.filespec

# Reference profile of a typical game (see FileSpec docstring)
POSITIONS_PER_GAME = 75
PIECES_PER_POSITION = 23
PIECES_TYPES_PER_POSITION = 10  # Added after introduction of chessql.
BYTES_PER_GAME = 700  # Records per page set to 10 because 700 was good.

# Names used to refer to file descriptions
# DPT files or Berkeley DB primary databases
GAMES_FILE_DEF = "games"
PARTIAL_FILE_DEF = "partial"
REPERTOIRE_FILE_DEF = "repertoire"
ANALYSIS_FILE_DEF = "analysis"
SELECTION_FILE_DEF = "selection"
ENGINE_FILE_DEF = "engine"

# Names used to refer to field descriptions
# DPT fields or Berkeley DB secondary databases
GAME_FIELD_DEF = "Game"
SOURCE_FIELD_DEF = "source"
EVENT_FIELD_DEF = "Event"
SITE_FIELD_DEF = "Site"
DATE_FIELD_DEF = "Date"
ROUND_FIELD_DEF = "Round"
WHITE_FIELD_DEF = "White"
BLACK_FIELD_DEF = "Black"
RESULT_FIELD_DEF = "Result"
POSITIONS_FIELD_DEF = "positions"
PIECESQUAREMOVE_FIELD_DEF = "piecesquaremove"
PIECEMOVE_FIELD_DEF = "piecemove"
SQUAREMOVE_FIELD_DEF = "squaremove"
PARTIAL_FIELD_DEF = "Partial"
PARTIALPOSITION_FIELD_DEF = "partialposition"
PARTIALPOSITION_NAME_FIELD_DEF = "partialpositionname"
NEWGAMES_FIELD_DEF = "newgames"
REPERTOIRE_FIELD_DEF = "Repertoire"
OPENING_FIELD_DEF = "Opening"
OPENING_ERROR_FIELD_DEF = "openingerror"
PGN_DATE_FIELD_DEF = "pgndate"
ANALYSIS_FIELD_DEF = "Analysis"
VARIATION_FIELD_DEF = "variation"
ENGINE_FIELD_DEF = "engine"
SELECTION_FIELD_DEF = "rulename"
RULE_FIELD_DEF = "rule"
PROGRAM_FIELD_DEF = "program"
COMMAND_FIELD_DEF = "command"

# Non-standard field names. Standard is x_FIELD_DEF.title()
_PIECESQUAREMOVE_FIELD_NAME = "PieceSquareMove"
_PIECEMOVE_FIELD_NAME = "PieceMove"
_SQUAREMOVE_FIELD_NAME = "SquareMove"
_PARTIALPOSITION_FIELD_NAME = "PartialPosition"
_PP_NAME_FIELD_NAME = "PartialPositionName"
_NEWGAMES_FIELD_NAME = "NewGames"
_OPENING_ERROR_FIELD_NAME = "OpeningError"
_PGN_DATE_FIELD_NAME = "PGNdate"

# Berkeley DB environment.
DB_ENVIRONMENT_GIGABYTES = 0
DB_ENVIRONMENT_BYTES = 1024000
DB_ENVIRONMENT_MAXLOCKS = 120000  # OpenBSD only.
DB_ENVIRONMENT_MAXOBJECTS = 120000  # OpenBSD only.

# Symas LMMD environment.
LMMD_MINIMUM_FREE_PAGES_AT_START = 20000

# Any partial position indexed by NEWGAMES_FIELD_VALUE on _NEWGAMES_FIELD_NAME
# has not been recalculated since an update to the games file.  The partial
# position's _PARTIALGAMES_FIELD_NAME reference on the games file is out of
# date and may be wrong.
NEWGAMES_FIELD_VALUE = "changed"

class FileSpec(solentware_base.core.filespec.FileSpec):
    """Specify a chess database.

    Parameters for Berkeley DB, DPT, and Sqlite3, are defined.

    Ignore settings irrelevant to the database engine in use.

    Berkeley DB and Sqlite3 look after themselves for sizing purposes when
    increasing the size of a database.

    The sizing parameters for the Games file in DPT were chosen using figures
    from a few game collections: ~25000 games in 4NCL up to 2011, ~4500 games
    in a California collection spanning the 20th century, ~2500 games in a
    collection of Volga Gambit games, ~150000 games from section 00 of
    enormous.pgn, ~500 games from 1997 4NCL divisions one and two separately.

             <            per game              >  <     pages    >
      Games Positions Pieces Data bytes PGN Bytes  Table B  Table D   Ratio
      25572     74      23      493        761       2557     20148     7.9
       4445     75      23      418        682        445      6034    13.6
       2324     76      23      416        683        232      3308    14.3
     156954     75      23      375        637      15803    120932     7.7
        528     77      23      481        757         52       891    17.1
        528     74      23      472        739         52       863    16.6

    There is not enough data to conclude that Table D usage is proportional
    to the index entries per game, but it is reasonable to expect this and
    the Positions and Table D ratios in the two 528 game samples are close
    enough to make the assumption.  Above, say, 20000 games it is assumed
    that typical games, 75 positions per game and 23 pieces per position,
    lead to a Table B to Table D ratio of 8, or 14 when CQL statements are
    supported.  The higher ratios at lower numbers of games are assumed to
    arise from the lower chance of compressed inverted lists.

    It is completely unclear what value to use for records per Table B page
    because games can have comments and variations as well as just the moves
    played.  The samples have few comments or variations. A value of 10 seems
    as good a compromise as any between wasting space and getting all record
    numbers used. 16 average sized records would fit on a Table B page.

    """

    def __init__(
        self, use_specification_items=None, dpt_records=None, **kargs
    ):
        """Define chess database."""
        dptdsn = FileSpec.dpt_dsn
        field_name = FileSpec.field_name

        super().__init__(
            use_specification_items=use_specification_items,
            dpt_records=dpt_records,
            **{
                GAMES_FILE_DEF: {
                    DDNAME: "GAMES",
                    FILE: dptdsn(GAMES_FILE_DEF),
                    FILEDESC: {
                        BRECPPG: 10,
                        FILEORG: RRN,
                    },
                    BTOD_FACTOR: 14,
                    BTOD_CONSTANT: 800,
                    DEFAULT_RECORDS: 10000,
                    DEFAULT_INCREASE_FACTOR: 0.01,
                    PRIMARY: field_name(GAME_FIELD_DEF),
                    DPT_PRIMARY_FIELD_LENGTH: 200,
                    SECONDARY: {
                        SOURCE_FIELD_DEF: SOURCE_FIELD_DEF.title(),
                        EVENT_FIELD_DEF: None,
                        SITE_FIELD_DEF: None,
                        DATE_FIELD_DEF: None,
                        ROUND_FIELD_DEF: None,
                        WHITE_FIELD_DEF: None,
                        BLACK_FIELD_DEF: None,
                        RESULT_FIELD_DEF: None,
                        POSITIONS_FIELD_DEF: POSITIONS_FIELD_DEF.title(),
                        PIECESQUAREMOVE_FIELD_DEF: _PIECESQUAREMOVE_FIELD_NAME,
                        PIECEMOVE_FIELD_DEF: _PIECEMOVE_FIELD_NAME,
                        SQUAREMOVE_FIELD_DEF: _SQUAREMOVE_FIELD_NAME,
                        PARTIALPOSITION_FIELD_DEF: _PARTIALPOSITION_FIELD_NAME,
                        PGN_DATE_FIELD_DEF: _PGN_DATE_FIELD_NAME,
                    },
                    FIELDS: {
                        field_name(GAME_FIELD_DEF): None,
                        SOURCE_FIELD_DEF.title(): {INV: True, ORD: True},
                        WHITE_FIELD_DEF: {INV: True, ORD: True},
                        BLACK_FIELD_DEF: {INV: True, ORD: True},
                        EVENT_FIELD_DEF: {INV: True, ORD: True},
                        ROUND_FIELD_DEF: {INV: True, ORD: True},
                        DATE_FIELD_DEF: {INV: True, ORD: True},
                        RESULT_FIELD_DEF: {INV: True, ORD: True},
                        SITE_FIELD_DEF: {INV: True, ORD: True},
                        POSITIONS_FIELD_DEF.title(): {
                            INV: True,
                            ORD: True,
                        },  # , ACCESS_METHOD:HASH},
                        _PIECESQUAREMOVE_FIELD_NAME: {
                            INV: True,
                            ORD: True,
                        },  # , ACCESS_METHOD:HASH},
                        _PIECEMOVE_FIELD_NAME: {
                            INV: True,
                            ORD: True,
                        },  # , ACCESS_METHOD:HASH},
                        _SQUAREMOVE_FIELD_NAME: {
                            INV: True,
                            ORD: True,
                        },  # , ACCESS_METHOD:HASH},
                        _PARTIALPOSITION_FIELD_NAME: {INV: True, ORD: True},
                        _PGN_DATE_FIELD_NAME: {INV: True, ORD: True},
                    },
                },
                PARTIAL_FILE_DEF: {
                    DDNAME: "PARTIAL",
                    FILE: dptdsn(PARTIAL_FILE_DEF),
                    FILEDESC: {
                        BRECPPG: 40,
                        FILEORG: RRN,
                    },
                    BTOD_FACTOR: 1,  # a guess
                    BTOD_CONSTANT: 100,  # a guess
                    DEFAULT_RECORDS: 10000,
                    DEFAULT_INCREASE_FACTOR: 0.5,
                    PRIMARY: field_name(PARTIAL_FIELD_DEF),
                    DPT_PRIMARY_FIELD_LENGTH: 127,
                    SECONDARY: {
                        PARTIALPOSITION_NAME_FIELD_DEF: _PP_NAME_FIELD_NAME,
                        NEWGAMES_FIELD_DEF: _NEWGAMES_FIELD_NAME,
                    },
                    FIELDS: {
                        field_name(PARTIAL_FIELD_DEF): None,
                        _PP_NAME_FIELD_NAME: {INV: True, ORD: True},
                        _NEWGAMES_FIELD_NAME: {INV: True, ORD: True},
                    },
                },
                REPERTOIRE_FILE_DEF: {
                    DDNAME: "REPERT",
                    FILE: dptdsn(REPERTOIRE_FILE_DEF),
                    FILEDESC: {
                        BRECPPG: 1,
                        FILEORG: RRN,
                    },
                    BTOD_FACTOR: 0.1,
                    BTOD_CONSTANT: 800,
                    DEFAULT_RECORDS: 100,
                    DEFAULT_INCREASE_FACTOR: 0.01,
                    PRIMARY: field_name(REPERTOIRE_FIELD_DEF),
                    DPT_PRIMARY_FIELD_LENGTH: 200,
                    SECONDARY: {
                        OPENING_FIELD_DEF: None,
                        OPENING_ERROR_FIELD_DEF: _OPENING_ERROR_FIELD_NAME,
                    },
                    FIELDS: {
                        field_name(REPERTOIRE_FIELD_DEF): None,
                        OPENING_FIELD_DEF: {INV: True, ORD: True},
                        _OPENING_ERROR_FIELD_NAME: {INV: True, ORD: True},
                    },
                },
                ANALYSIS_FILE_DEF: {
                    DDNAME: "ANALYSIS",
                    FILE: dptdsn(ANALYSIS_FILE_DEF),
                    FILEDESC: {
                        BRECPPG: 10,
                        FILEORG: RRN,
                    },
                    BTOD_FACTOR: 1,
                    BTOD_CONSTANT: 800,
                    DEFAULT_RECORDS: 100000,
                    DEFAULT_INCREASE_FACTOR: 1.0,
                    PRIMARY: field_name(ANALYSIS_FIELD_DEF),
                    DPT_PRIMARY_FIELD_LENGTH: 200,
                    SECONDARY: {
                        ENGINE_FIELD_DEF: ENGINE_FIELD_DEF.title(),
                        VARIATION_FIELD_DEF: VARIATION_FIELD_DEF.title(),
                    },
                    FIELDS: {
                        field_name(ANALYSIS_FIELD_DEF): None,
                        ENGINE_FIELD_DEF.title(): {INV: True, ORD: True},
                        VARIATION_FIELD_DEF.title(): {INV: True, ORD: True},
                    },
                },
                SELECTION_FILE_DEF: {
                    DDNAME: "SLCTRULE",
                    FILE: dptdsn(SELECTION_FILE_DEF),
                    FILEDESC: {
                        BRECPPG: 20,
                        FILEORG: RRN,
                    },
                    BTOD_FACTOR: 1,  # a guess
                    BTOD_CONSTANT: 100,  # a guess
                    DEFAULT_RECORDS: 10000,
                    DEFAULT_INCREASE_FACTOR: 0.5,
                    PRIMARY: field_name(SELECTION_FIELD_DEF),
                    DPT_PRIMARY_FIELD_LENGTH: 127,
                    SECONDARY: {
                        RULE_FIELD_DEF: RULE_FIELD_DEF.title(),
                    },
                    FIELDS: {
                        field_name(SELECTION_FIELD_DEF): None,
                        RULE_FIELD_DEF.title(): {INV: True, ORD: True},
                    },
                },
                ENGINE_FILE_DEF: {
                    DDNAME: "ENGINE",
                    FILE: dptdsn(ENGINE_FILE_DEF),
                    FILEDESC: {
                        BRECPPG: 150,
                        FILEORG: RRN,
                    },
                    BTOD_FACTOR: 1,  # a guess
                    BTOD_CONSTANT: 100,  # a guess
                    DEFAULT_RECORDS: 1000,
                    DEFAULT_INCREASE_FACTOR: 0.5,
                    PRIMARY: field_name(PROGRAM_FIELD_DEF),
                    DPT_PRIMARY_FIELD_LENGTH: 127,
                    SECONDARY: {
                        COMMAND_FIELD_DEF: COMMAND_FIELD_DEF.title(),
                    },
                    FIELDS: {
                        field_name(PROGRAM_FIELD_DEF): None,
                        COMMAND_FIELD_DEF.title(): {INV: True, ORD: True},
                    },
                },
            }
        )


from column_frequency import getFrequency

def getRating(word):
    rating = 0

    # Add up the ratings of each letter in each column
    for i in range(5):
        rating += letterFrequency[i][word[i]]

    return rating

letterFrequency = getFrequency()

database = open("../database/filtered.txt", "r")

answerDict = {}

for word in database:
    word = word.strip()
    answerDict[word] = getRating(word)

# https://www.tutorialsteacher.com/articles/sort-dict-by-value-in-python
sortedScores = sorted(answerDict.items(), key=lambda x:x[1], reverse=True)

overallRating = open("./columnRating.txt", "w")
for score in sortedScores:
    overallRating.writelines(score[0] + "\n")


import numpy
from firedrake import Constant, DirichletBC, Function
from firedrake import NonlinearVariationalProblem as NLVP
from firedrake import NonlinearVariationalSolver as NLVS
from firedrake import interpolate, split
from ufl.constantvalue import as_ufl

from .deriv import TimeDerivative
from .tools import replace

class BCThingy:
    def __init__(self):
        pass

    def __call__(self, u):
        return u

class BCCompOfNotMixedThingy:
    def __init__(self, comp):
        self.comp = comp

    def __call__(self, u):
        return u[self.comp]

class BCMixedBitThingy:
    def __init__(self, sub):
        self.sub = sub

    def __call__(self, u):
        return u.sub(self.sub)

class BCCompOfMixedBitThingy:
    def __init__(self, sub, comp):
        self.sub = sub
        self.comp = comp

    def __call__(self, u):
        return u.sub(self.sub)[self.comp]

def getThingy(V, bc):
    num_fields = len(V)
    Vbc = bc.function_space()
    if num_fields == 1:
        comp = Vbc.component
        if comp is None:
            return BCThingy()
        else:
            return BCCompOfNotMixedThingy(comp)
    else:
        sub = bc.function_space_index()
        comp = Vbc.component
        if comp is None:
            return BCMixedBitThingy(sub)
        else:
            return BCCompOfMixedBitThingy(sub, comp)

def getFormDIRK(F, butch, t, dt, u0, bcs=None):
    if bcs is None:
        bcs = []

    v = F.arguments()[0]
    V = v.function_space()
    msh = V.mesh()
    assert V == u0.function_space()

    num_fields = len(V)

    k = Function(V)
    g = Function(V)

    # If we're on a mixed problem, we need to replace pieces of the
    # solution.  Stores an array of the splittings of the k for each stage.
    if num_fields == 1:
        k_bits = [k]
        u0bits = [u0]
        gbits = [g]
    else:
        k_bits = numpy.array(split(k), dtype=object)
        u0bits = split(u0)
        gbits = split(g)

    # Note: the Constant c is used for substitution in both the
    # variational form and BC's, and we update it for each stage in
    # the loop over stages in the advance method.  The Constant a is
    # used similarly in the variational form
    c = Constant(1.0, domain=msh)
    a = Constant(1.0, domain=msh)

    repl = {t: t+c*dt}
    for u0bit, kbit, gbit in zip(u0bits, k_bits, gbits):
        repl[u0bit] = gbit + dt * a * kbit
        repl[TimeDerivative(u0bit)] = kbit
    stage_F = replace(F, repl)

    bcnew = []
    gblah = []

    # For the DIRK case, we need one new BC for each old one (rather
    # than one per stage), but we need a `Function` inside of each BC
    # and a rule for computing that function at each time for each
    # stage.
    for bc in bcs:
        Vbc = bc.function_space()
        bcarg = as_ufl(bc._original_arg)
        bcarg_stage = replace(bcarg, {t: t+c*dt})
        try:
            gdat = interpolate(bcarg, Vbc)
            gmethod = lambda gd, gc: gd.interpolate(gc)
        except:  # noqa: E722
            gdat = interpolate(bcarg, Vbc)
            gmethod = lambda gd, gc: gd.project(gc)

        new_bc = DirichletBC(Vbc, gdat, bc.sub_domain)
        bcnew.append(new_bc)

        dat4bc = getThingy(V, bc)
        gdat2 = Function(gdat.function_space())
        gblah.append((gdat, gdat2, bcarg_stage, gmethod, dat4bc))

    return stage_F, (k, g, a, c), bcnew, gblah

class DIRKTimeStepper:
    """Front-end class for advancing a time-dependent PDE via a diagonally-implicit
    Runge-Kutta method formulated in terms of stage derivatives."""

    def __init__(self, F, butcher_tableau, t, dt, u0, bcs=None,
                 solver_parameters=None,
                 appctx=None, nullspace=None):
        assert butcher_tableau.is_diagonally_implicit

        self.num_steps = 0
        self.num_nonlinear_iterations = 0
        self.num_linear_iterations = 0

        self.butcher_tableau = butcher_tableau
        self.V = V = u0.function_space()
        self.u0 = u0
        self.t = t
        self.dt = dt
        self.num_fields = len(u0.function_space())
        self.num_stages = num_stages = butcher_tableau.num_stages
        self.ks = [Function(V) for _ in range(num_stages)]

        # "k" is a generic function for which we will solve the
        # NVLP for the next stage value
        # "ks" is a list of functions for the stage values
        # that we update as we go.  We need to remember the
        # stage values we've computed earlier in the time step...

        stage_F, (k, g, a, c), bcnew, gblah = getFormDIRK(
            F, butcher_tableau, t, dt, u0, bcs=bcs)

        self.bcnew = bcnew
        self.gblah = gblah

        appctx_irksome = {"F": F,
                          "butcher_tableau": butcher_tableau,
                          "t": t,
                          "dt": dt,
                          "u0": u0,
                          "bcs": bcs,
                          "bc_type": "DAE",
                          "nullspace": nullspace}
        if appctx is None:
            appctx = appctx_irksome
        else:
            appctx = {**appctx, **appctx_irksome}

        self.problem = NLVP(stage_F, k, bcnew)
        self.solver = NLVS(
            self.problem, appctx=appctx, solver_parameters=solver_parameters,
            nullspace=nullspace)

        self.kgac = k, g, a, c

    def advance(self):
        k, g, a, c = self.kgac
        ks = self.ks
        u0 = self.u0
        dtc = float(self.dt)
        bt = self.butcher_tableau
        AA = bt.A
        CC = bt.c
        BB = bt.b
        gsplit = g.subfunctions
        for i in range(self.num_stages):
            # update a, c constants tucked into the variational problem
            # for the current stage
            a.assign(AA[i, i])
            c.assign(CC[i])
            # compute the already-known part of the state in the
            # variational form
            g.assign(u0)
            for j in range(i):
                ksplit = ks[j].subfunctions
                for (gbit, kbit) in zip(gsplit, ksplit):
                    gbit += dtc * float(AA[i, j]) * kbit

            # update BC's for the variational problem
            for (bc, (gdat, gdat2, gcur, gmethod, dat4bc)) in zip(self.bcnew, self.gblah):
                # Evaluate the Dirichlet BC at the current stage time
                gmethod(gdat, gcur)

                gmethod(gdat2, dat4bc(u0))
                gdat -= gdat2

                # Subtract previous stage values
                for j in range(i):
                    gmethod(gdat2, dat4bc(ks[j]))
                    gdat -= dtc * float(AA[i, j]) * gdat2

                # Rescale gdat
                gdat /= dtc * float(AA[i, i])

            # solve new variational problem, stash the computed
            # stage value.

            # Note: implicitly uses solution value for stage i as
            # initial guess for stage i+1 and uses the last stage from
            # previous time step for stage 0 of the next one.  The
            # former is probably optimal, we hope for the best with
            # the latter.
            self.solver.solve()
            mysnes = self.solver.snes
            self.num_nonlinear_iterations += mysnes.getIterationNumber()
            self.num_linear_iterations += mysnes.getLinearSolveIterations()
            ks[i].assign(k)

        # update the solution with now-computed stage values.
        for i in range(self.num_stages):
            for (u0bit, kbit) in zip(u0.subfunctions, ks[i].subfunctions):
                u0bit += dtc * float(BB[i]) * kbit

        self.num_steps += 1

    def solver_stats(self):
        return self.num_steps, self.num_nonlinear_iterations, self.num_linear_iterations


#!/usr/bin/env python3

from tkinter import Label, Entry, Button, Tk, filedialog, messagebox, ttk, END
from resizer import resize_video

CODEC_LIST = ['VP8', 'VP9', 'h265', 'AV1']
CODEC_NAME = ['libvpx', 'libvpx-vp9', 'libx265', 'libaom-av1']
EXT_LIST = ['.webm', '.webm', '.mp4', '.webm']

def converter_GUI(window):
    window.title('Converter Utility')
    window.geometry('420x200')

    # VIDEO RESOLUTION GUI
    label = Label(window, text='Video resolution')
    label.grid(column=0, row=0)

    txt_width_res = Entry(window, width=6)
    txt_width_res.grid(column=0, row=1)

    label = Label(window, text='x')
    label.grid(column=0, row=2)

    txt_height_res = Entry(window, width=6)
    txt_height_res.grid(column=0, row=3)

    # VIDEO CODEC SELECTION GUI
    label = Label(window, text='Video codec')
    label.grid(column=1, row=1)

    combo_codec_selector = ttk.Combobox(state='readonly', values=CODEC_LIST)
    combo_codec_selector.grid(column=1, row=2)

    # Video file selection
    txt_video_dir = Entry(window, width=20)
    txt_video_dir.grid(column=0, row=4)

    label = Label(window, text='New video name:')
    label.grid(column=0, row=5)

    txt_new_video_dir = Entry(window, width=20)
    txt_new_video_dir.grid(column=1, row=5)

    def launch_item_search():
        selected_folder = filedialog.askopenfilename()
        txt_video_dir.delete(0, END)
        txt_video_dir.insert(0, selected_folder)

    video_search_button = Button(window,
                                 text='Search video file',
                                 command=launch_item_search)
    video_search_button.grid(column=1, row=4)

    # VIDEO CONVERTION BUTTON
    def launch_conversion():
        new_file_name = txt_new_video_dir.get() + \
            EXT_LIST[combo_codec_selector.current()]

        messagebox.showinfo('Converter Utility', 'Starting compression')

        resize_video(txt_video_dir.get(),
                     new_file_name,
                     txt_width_res.get(),
                     txt_height_res.get(),
                     CODEC_NAME[combo_codec_selector.current()])
        messagebox.showinfo('Converter Utility', 'Finished compression')

    convert_button = Button(window, text='Convert', command=launch_conversion)
    convert_button.grid(column=4, row=2)

if __name__ == '__main__':
    window = Tk()
    converter_GUI(window)
    window.mainloop()


from resource_management.core.providers import Provider
from resource_management.core.logger import Logger
from resource_management.core.base import Fail
from resource_management.core import ExecuteTimeoutException
from multiprocessing import Queue
import time
import os
import subprocess
import shutil
from resource_management.libraries.script import Script

def _merge_env(env1, env2, merge_keys=['PYTHONPATH']):
  """
  Merge env2 into env1. Also current python instance variables from merge_keys list taken into account and they will be
  merged with equivalent keys from env1 and env2 using system path separator.
  :param env1: first environment, usually returned by CreateEnvironmentBlock
  :param env2: custom environment
  :param merge_keys: env variables to merge as PATH
  :return: merged environment
  """
  env1 = dict(env1)  # copy to new dict in case env1 is os.environ
  if env2:
    for key, value in env2.iteritems():
      if not key in merge_keys:
        env1[key] = value
  # strnsform keys and values to str(windows can not accept unicode)
  result_env = {}
  for key, value in env1.iteritems():
    if not key in merge_keys:
      result_env[str(key)] = str(value)
  #merge keys from merge_keys
  def put_values(key, env, result):
    if env and key in env:
      result.extend(env[key].split(os.pathsep))

  for key in merge_keys:
    all_values = []
    for env in [env1, env2, os.environ]:
      put_values(key, env, all_values)
    result_env[str(key)] = str(os.pathsep.join(set(all_values)))
  return result_env

# Execute command. As windows stack heavily relies on proper environment it is better to reload fresh environment
# on every execution. env variable will me merged with fresh environment for user.
def _call_command(command, logoutput=False, cwd=None, env=None, wait_for_finish=True, timeout=None, user=None,
                  pid_file_name=None, poll_after=None):
  # TODO implement user
  Logger.info("Executing %s" % (command))
  proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                          cwd=cwd, env=env, shell=False)
  code = None
  if not wait_for_finish:
    Logger.debug("No need to wait for the process to exit. Will leave the process running ...")
    code = 0
    logAnyway = False
    if pid_file_name:
      Logger.debug("Writing the process id %s to file %s" % (str(proc.pid), pid_file_name))
      pidfile = open(pid_file_name, 'w')
      pidfile.write(str(proc.pid))
      pidfile.close()
      Logger.info("Wrote the process id to file %s" % pid_file_name)

      ## wait poll_after seconds and poll
    if poll_after:
      time.sleep(poll_after)
      if proc.poll() is None:
        return code, None, None  # if still running then return
      else:
        logAnyway = True  # assume failure and log
        Logger.warning("Process is not up after the polling interval " + str(poll_after) + " seconds.")
    else:
      return code, None, None

  if timeout:
    q = Queue()
    t = threading.Timer(timeout, on_timeout, [proc, q])
    t.start()

  out, err = proc.communicate()
  code = proc.returncode

  if logoutput or logAnyway:
    if out:
      Logger.info("Out: " + str(out))
    if err:
      Logger.info("Err: " + str(err))
    if code:
      Logger.info("Ret Code: " + str(code))

  return code, out, err

# see msdn Icacls doc for rights
def _set_file_acl(file, user, rights):
  acls_modify_cmd = "icacls {0} /grant {1}:{2}".format(file, user, rights)
  acls_remove_cmd = "icacls {0} /remove {1}".format(file, user)
  code, out, err = _call_command(acls_remove_cmd)
  if code != 0:
    raise Fail("Can not remove rights for path {0} and user {1}".format(file, user))
  code, out, err = _call_command(acls_modify_cmd)
  if code != 0:
    raise Fail("Can not set rights {0} for path {1} and user {2}".format(rights, file, user))
  else:
    return

class FileProvider(Provider):
  def action_create(self):
    path = self.resource.path

    if os.path.isdir(path):
      raise Fail("Applying %s failed, directory with name %s exists" % (self.resource, path))

    dirname = os.path.dirname(path)
    if not os.path.isdir(dirname):
      raise Fail("Applying %s failed, parent directory %s doesn't exist" % (self.resource, dirname))

    write = False
    content = self._get_content()
    if not os.path.exists(path):
      write = True
      reason = "it doesn't exist"
    elif self.resource.replace:
      if content is not None:
        with open(path, "rb") as fp:
          old_content = fp.read()
        if content != old_content:
          write = True
          reason = "contents don't match"
          if self.resource.backup:
            self.resource.env.backup_file(path)

    if write:
      Logger.info("Writing %s because %s" % (self.resource, reason))
      with open(path, "wb") as fp:
        if content:
          fp.write(content)

    if self.resource.owner and self.resource.mode:
      _set_file_acl(self.resource.path, self.resource.owner, self.resource.mode)

  def action_delete(self):
    path = self.resource.path

    if os.path.isdir(path):
      raise Fail("Applying %s failed, %s is directory not file!" % (self.resource, path))

    if os.path.exists(path):
      Logger.info("Deleting %s" % self.resource)
      os.unlink(path)

  def _get_content(self):
    content = self.resource.content
    if content is None:
      return None
    elif isinstance(content, basestring):
      return content
    elif hasattr(content, "__call__"):
      return content()
    raise Fail("Unknown source type for %s: %r" % (self, content))

class ExecuteProvider(Provider):
  def action_run(self):
    if self.resource.creates:
      if os.path.exists(self.resource.creates):
        return

    Logger.debug("Executing %s" % self.resource)

    if self.resource.path != []:
      if not self.resource.environment:
        self.resource.environment = {}

      self.resource.environment['PATH'] = os.pathsep.join(self.resource.path)

    for i in range(0, self.resource.tries):
      try:
        code, _, _  = _call_command(self.resource.command, logoutput=self.resource.logoutput,
                                    cwd=self.resource.cwd, env=self.resource.environment,
                                    wait_for_finish=self.resource.wait_for_finish,
                                    timeout=self.resource.timeout, user=self.resource.user,
                                    pid_file_name=self.resource.pid_file, poll_after=self.resource.poll_after)
        if code != 0 and not self.resource.ignore_failures:
          raise Fail("Failed to execute " + self.resource.command)
        break
      except Fail as ex:
        Logger.info("Error raised: %s" % str(ex))
        if i == self.resource.tries - 1:  # last try
          raise ex
        else:
          Logger.info("Retrying after %d seconds. Reason: %s" % (self.resource.try_sleep, str(ex)))
          time.sleep(self.resource.try_sleep)
      except ExecuteTimeoutException:
        err_msg = ("Execution of '%s' was killed due timeout after %d seconds") % (
          self.resource.command, self.resource.timeout)

        if self.resource.on_timeout:
          Logger.info("Executing '%s'. Reason: %s" % (self.resource.on_timeout, err_msg))
          _call_command(self.resource.on_timeout)
        else:
          raise Fail(err_msg)

class DirectoryProvider(Provider):
  def action_create(self):
    path = DirectoryProvider._trim_uri(self.resource.path)
    if not os.path.exists(path):
      Logger.info("Creating directory %s" % self.resource)
      if self.resource.recursive:
        os.makedirs(path)
      else:
        dirname = os.path.dirname(path)
        if not os.path.isdir(dirname):
          raise Fail("Applying %s failed, parent directory %s doesn't exist" % (self.resource, dirname))

        os.mkdir(path)

    if not os.path.isdir(path):
      raise Fail("Applying %s failed, file %s already exists" % (self.resource, path))

    if self.resource.owner and self.resource.mode:
      _set_file_acl(path, self.resource.owner, self.resource.mode)

  def action_delete(self):
    path = self.resource.path
    if os.path.exists(path):
      if not os.path.isdir(path):
        raise Fail("Applying %s failed, %s is not a directory" % (self.resource, path))

      Logger.info("Removing directory %s and all its content" % self.resource)
      shutil.rmtree(path)

  @staticmethod
  def _trim_uri(file_uri):
    if file_uri.startswith("file:///"):
      return file_uri[8:]
    return file_uri


# This code defines the agent (as in the playable version) in a way that can be called and executed from an evolutionary algorithm. The code is partial and will not execute. You need to add to the code to create an evolutionary algorithm that evolves and executes a snake agent.
#import curses
#from curses import KEY_LEFT
import random
import operator
from functools import partial
import time
from multiprocessing import Process

import numpy

#from deap import algorithms
#from deap import base
#from deap import creator
#from deap import tools
#from deap import gp

from copy import deepcopy as dc

import math

import tkinter as tk

S_RIGHT, S_LEFT, S_UP, S_DOWN = 0, 1, 2, 3
NFOOD = 1  # NOTE: YOU MAY NEED TO ADD A CHECK THAT THERE ARE ENOUGH SPACES LEFT FOR THE FOOD (IF THE TAIL IS VERY LONG)

# This class can be used to create a basic player object (snake agent)
# A few of the new sensing functions I added were not used but intentionally left in for future work
class SnakePlayer(list):
    global S_RIGHT, S_LEFT, S_UP, S_DOWN

    def __init__(self, XSIZE, YSIZE):
        self.XSIZE, self.YSIZE = XSIZE, YSIZE
        self.direction = S_RIGHT
        # self.body = [[4, 10], [4, 9], [4, 8], [4, 7], [4, 6], [4, 5], [4, 4], [4, 3], [4, 2], [4, 1], [4, 0]]
        self.body = [[random.randint(0, self.XSIZE - 1), random.randint(0, self.YSIZE - 1)]]
        self.score = 0
        self.ahead = []
        self.food = []

    def _reset(self):
        self.direction = S_RIGHT
        # self.body[:] = [[4, 10], [4, 9], [4, 8], [4, 7], [4, 6], [4, 5], [4, 4], [4, 3], [4, 2], [4, 1], [4, 0]]
        self.body = [[random.randint(0, self.XSIZE - 1), random.randint(0, self.YSIZE - 1)]]
        self.score = 0
        self.ahead = []
        self.food = []

    def changeDirectionRightRel(self):
        if self.direction == S_UP:
            self.direction = S_RIGHT
        elif self.direction == S_RIGHT:
            self.direction = S_DOWN
        elif self.direction == S_DOWN:
            self.direction = S_LEFT
        elif self.direction == S_LEFT:
            self.direction = S_UP

    def changeDirectionLeftRel(self):
        if self.direction == S_UP:
            self.direction = S_LEFT
        elif self.direction == S_RIGHT:
            self.direction = S_UP
        elif self.direction == S_DOWN:
            self.direction = S_RIGHT
        elif self.direction == S_LEFT:
            self.direction = S_DOWN

    # ONLY CALL WHEN DOING NOVELTY SEARCH
    def make_random_snake_board(self):
        self.body = []
        snake = [[random.choice(range(self.YSIZE)), random.choice(range(self.XSIZE))]]
        snake_length = random.randint(5, 194)
        for i in range(snake_length):
            coord = [random.choice(range(self.YSIZE)), random.choice(range(self.XSIZE))]
            while coord in snake:
                coord = [random.choice(range(self.YSIZE)), random.choice(range(self.XSIZE))]
            self.body.append(coord)
        coord = [random.choice(range(self.YSIZE)), random.choice(range(self.XSIZE))]
        while coord in self.body:
            coord = [random.choice(range(self.YSIZE)), random.choice(range(self.XSIZE))]
        self.food = [coord]

    def setAheadToHead(self):
        self.ahead = self.body[0]

    def move_ahead(self, vector):
        self.ahead = [self.ahead[0] + vector[0], self.ahead[1] + vector[1]]

    def getUpLocation(self):
        self.ahead = [self.body[0][0] - 1, self.body[0][1]]

    def getRightLocation(self):
        self.ahead = [self.body[0][0], self.body[0][1] + 1]

    def getLeftLocation(self):
        self.ahead = [self.body[0][0], self.body[0][1] - 1]

    def getDownLocation(self):
        self.ahead = [self.body[0][0] + 1, self.body[0][1]]

    def getAheadLocation(self):
        self.ahead = [self.body[0][0] + (self.direction == S_DOWN and 1) + (self.direction == S_UP and -1),
                      self.body[0][1] + (self.direction == S_LEFT and -1) + (self.direction == S_RIGHT and 1)]

    def updatePosition(self):
        self.getAheadLocation()
        self.body.insert(0, self.ahead)

    ## You are free to define more sensing options to the snake

    def changeDirectionUp(self):
        self.direction = S_UP

    def changeDirectionRight(self):
        self.direction = S_RIGHT

    def changeDirectionDown(self):
        self.direction = S_DOWN

    def changeDirectionLeft(self):
        self.direction = S_LEFT

    def snakeHasCollided(self):
        self.hit = False
        if self.body[0][0] == 0 or self.body[0][0] == (self.YSIZE - 1) or self.body[0][1] == 0 or self.body[0][1] == (
                self.XSIZE - 1): self.hit = True
        if self.body[0] in self.body[1:]: self.hit = True
        return (self.hit)

    def sense_wall_at_ahead_loc(self):
        return self.ahead[0] == 0 or self.ahead[0] == (self.YSIZE - 1) or self.ahead[1] == 0 or self.ahead[1] == (
                    self.XSIZE - 1)

    def sense_tail_at_ahead_loc(self):
        return self.ahead in self.body

    def get_distance_to_obsticals(self):
        output = []
        vector = [-1, 1]
        self.setAheadToHead()
        self.move_ahead(vector)
        output.append(float(1))
        while not (self.sense_wall_at_ahead_loc() or self.sense_tail_at_ahead_loc()):
            output[-1] += 1
            self.move_ahead(vector)
        vector = [0, 1]
        self.setAheadToHead()
        self.move_ahead(vector)
        output.append(float(1))
        while not (self.sense_wall_at_ahead_loc() or self.sense_tail_at_ahead_loc()):
            output[-1] += 1
            self.move_ahead(vector)
        vector = [1, 1]
        self.setAheadToHead()
        self.move_ahead(vector)
        output.append(float(1))
        while not (self.sense_wall_at_ahead_loc() or self.sense_tail_at_ahead_loc()):
            output[-1] += 1
            self.move_ahead(vector)
        vector = [1, 0]
        self.setAheadToHead()
        self.move_ahead(vector)
        output.append(float(1))
        while not (self.sense_wall_at_ahead_loc() or self.sense_tail_at_ahead_loc()):
            output[-1] += 1
            self.move_ahead(vector)
        vector = [1, -1]
        self.setAheadToHead()
        self.move_ahead(vector)
        output.append(float(1))
        while not (self.sense_wall_at_ahead_loc() or self.sense_tail_at_ahead_loc()):
            output[-1] += 1
            self.move_ahead(vector)
        vector = [0, -1]
        self.setAheadToHead()
        self.move_ahead(vector)
        output.append(float(1))
        while not (self.sense_wall_at_ahead_loc() or self.sense_tail_at_ahead_loc()):
            output[-1] += 1
            self.move_ahead(vector)
        vector = [-1, -1]
        self.setAheadToHead()
        self.move_ahead(vector)
        output.append(float(1))
        while not (self.sense_wall_at_ahead_loc() or self.sense_tail_at_ahead_loc()):
            output[-1] += 1
            self.move_ahead(vector)
        vector = [-1, 0]
        self.setAheadToHead()
        self.move_ahead(vector)
        output.append(float(1))
        while not (self.sense_wall_at_ahead_loc() or self.sense_tail_at_ahead_loc()):
            output[-1] += 1
            self.move_ahead(vector)
        for out in range(len(output)):
            output[out] = 1 - (output[out] / 14)
        return output

    def sense_walls(self):
        self.getUpLocation()
        to_return = [self.sense_wall_at_ahead_loc()]
        self.getDownLocation()
        to_return.append(self.sense_wall_at_ahead_loc())
        self.getLeftLocation()
        to_return.append(self.sense_wall_at_ahead_loc())
        self.getRightLocation()
        to_return.append(self.sense_wall_at_ahead_loc())
        return to_return

    def sense_tails(self):
        self.getUpLocation()
        to_return = [self.ahead in self.body]
        self.getDownLocation()
        to_return.append(self.ahead in self.body)
        self.getLeftLocation()
        to_return.append(self.ahead in self.body)
        self.getRightLocation()
        to_return.append(self.ahead in self.body)
        return to_return

    def sense_obsticals(self):
        walls = self.sense_walls()
        tails = self.sense_tails()
        to_return = []
        for i in range(len(walls)):
            to_return.append(walls[i] or tails[i])
        return to_return

    def get_board(self):
        board = []
        for x in range(self.XSIZE):
            board.append([])
            for y in range(self.YSIZE):
                if [x, y] in self.body:
                    board[x].append(-1)
                elif [x, y] == self.get_food_loc():
                    board[x].append(1)
                else:
                    board[x].append(0)
        return board

    def get_board_rel(self, win_size):
        board = self.get_board()
        head_loc = self.get_head_loc()
        window = []
        for row in range(head_loc[0] - win_size, head_loc[0] + win_size + 1):
            for column in range(head_loc[1] - win_size, head_loc[1] + win_size + 1):
                window.append([row, column])
        new_window = []
        for coordinate in window:
            if coordinate[0] < 0 or coordinate[1] < 0 or coordinate[0] >= self.XSIZE or coordinate[1] >= self.YSIZE:
                new_window.append(-1)
            else:
                new_window.append(board[coordinate[0]][coordinate[1]])
        return new_window

    def get_board_rel_2d(self, win_size):
        board = self.get_board()
        head_loc = self.get_head_loc()
        window = []
        for row in range(head_loc[0] - win_size, head_loc[0] + win_size + 1):
            window.append([])
            for column in range(head_loc[1] - win_size, head_loc[1] + win_size + 1):
                if column < 0 or row < 0 or column >= self.XSIZE or row >= self.YSIZE:
                    window[-1].append([0,0,1])
                else:
                    window[-1].append([board[row][column] == 1, board[row][column] == 0, board[row][column] == -1])
        return window

    def get_food_loc(self):
        return self.food

    def get_head_loc(self):
        return self.body[0]

    def find_angle_to_food_rel(self):
        food_vector_tmp = list(map(lambda x, y: float(x - y), self.get_food_loc()[0], self.get_head_loc()))
        food_vector_size = math.sqrt(food_vector_tmp[0] ** 2 + food_vector_tmp[1] ** 2)
        food_vector_tmp = [food_vector_tmp[0] / food_vector_size, food_vector_tmp[1] / food_vector_size]
        food_vector = [0, 0]
        if self.direction == S_LEFT:
            food_vector[0] = food_vector_tmp[1]
            food_vector[1] = -food_vector_tmp[0]
        elif self.direction == S_RIGHT:
            food_vector[0] = -food_vector_tmp[1]
            food_vector[1] = food_vector_tmp[0]
        elif self.direction == S_DOWN:
            food_vector[0] = -food_vector_tmp[1]
            food_vector[1] = -food_vector_tmp[0]
        else:
            food_vector = food_vector_tmp
        angle = 0
        if food_vector[1] > 0:
            angle = 0.5 + (food_vector[0] / 2)
        elif food_vector[1] < 0:
            angle = -0.5 - (food_vector[0] / 2)
        elif food_vector[1] == 0:
            if food_vector[0] < 0:
                angle = 0
            else:
                angle = 1
        return angle

    def find_angle_to_food(self):
        food_vector_tmp = list(map(lambda x, y: float(x - y), self.food[0], self.body[0]))
        food_vector_size = math.sqrt(food_vector_tmp[0] ** 2 + food_vector_tmp[1] ** 2)
        food_vector = [food_vector_tmp[0] / food_vector_size, food_vector_tmp[1] / food_vector_size]
        angle = 0
        if food_vector[1] > 0:
            angle = 0.5 + (food_vector[0] / 2)
        elif food_vector[1] < 0:
            angle = -0.5 - (food_vector[0] / 2)
        elif food_vector[1] == 0:
            if food_vector[0] < 0:
                angle = 0
            else:
                angle = 1
        return food_vector

    def get_direction(self):
        if self.direction == S_RIGHT:
            return [1, 0, 0, 0]
        elif self.direction == S_UP:
            return [0, 1, 0, 0]
        elif self.direction == S_LEFT:
            return [0, 0, 1, 0]
        elif self.direction == S_DOWN:
            return [0, 0, 0, 1]

    def snakeHasCollided(self):
        self.hit = False
        if self.body[0][0] == 0 or self.body[0][0] == (self.YSIZE - 1) or self.body[0][1] == 0 or self.body[0][1] == (
                self.XSIZE - 1): self.hit = True
        if self.body[0] in self.body[1:]: self.hit = True
        return (self.hit)

    def sense_wall_ahead(self):
        self.getAheadLocation()
        return (
                self.ahead[0] == 0 or self.ahead[0] == (self.YSIZE - 1) or self.ahead[1] == 0 or self.ahead[1] == (
                    self.XSIZE - 1))

def get_output_old(individual, snake):
    # print alternative_input
    # inputs = snake.sense_obsticals()
    # inputs  = snake.get_head_loc()
    # inputs.append(snake.direction)
    # inputs.extend(snake.get_food_loc())
    # inputs.extend(snake.get_head_loc())
    # alternative_input = [snake.get_head_loc()[0], snake.get_head_loc()[1], (snake.direction-2) / 4]#, snake.get_food_loc()[0], snake.get_food_loc()[1]]
    inputs = snake.get_board_rel()
    inputs.append(snake.find_angle_to_food())
    for input in range(len(inputs)):
        if type(inputs[input]) == bool:
            if inputs[input]:
                inputs[input] = 1
            else:
                inputs[input] = 0

    #        inputs = snake.get_board()
    outputs = individual.run(inputs)
    choice = outputs.index(max(outputs))
    # if outputs.count(0) == 4:
    #    choice = random.randint(0, 4)
    if choice == 1:
        snake.changeDirectionRight()
    elif choice == 0:
        snake.changeDirectionLeft()
    elif choice == 3:
        snake.changeDirectionDown()
    else:
        snake.changeDirectionUp()
    return choice

def get_output(individual, snake, novelty=False):
    #inputs = snake.get_board_rel(snake.XSIZE) + snake.find_angle_to_food()
    #inputs += snake.get_direction()
    #inputs += [(snake.body[0][0] / 7) - 1, (snake.body[0][1] / 7) - 1]
    #inputs += [(snake.food[0][0] / 7) - 1, (snake.food[0][1] /7) - 1]
    #for input in range(len(inputs)):
    #    if type(inputs[input]) == bool:
    #        if inputs[input]:
    #            inputs[input] = 1
    #        else:
    #            inputs[input] = 0
    inputs = snake.get_board_rel_2d(snake.XSIZE)
    outputs = individual.run(inputs)
    choice = outputs.index(max(outputs))
    if snake.direction == 0 and choice == 1:
        snake.direction = 0
    elif snake.direction == 1 and choice == 0:
        snake.direction = 1
    elif snake.direction == 2 and choice == 3:
        snake.direction = 2
    elif snake.direction == 3 and choice == 2:
        snake.direction = 3
    else:
        snake.direction = choice
    return choice

# This function places a food item in the environment
def placeFood(snake):
    food = []
    while len(food) < NFOOD:
        potentialfood = [random.randint(1, (snake.YSIZE - 2)), random.randint(1, (snake.XSIZE - 2))]
        if not (potentialfood in snake.body) and not (potentialfood in food):
            food.append(potentialfood)
    snake.food = food  # let the snake know where the food is
    return (food)

#snakes = [SnakePlayer(i, i) for i in range(4, 20, 2)]
snake = SnakePlayer(14,14)

def get_box(xcor, ycor):
    return xcor * 20 + 4, ycor * 20 + 4, xcor * 20 + 20, ycor * 20 + 20

def player(queue):
    global snake
    snake_i = dc(snake)
    root = tk.Tk()
    root.geometry("284x284")
    canvas = tk.Canvas(root, width=284, height=284)
    canvas.configure(background="black")
    canvas.pack()
    keep_going = True
    #root.update_idle_tasks()
    root.update()
    first = True
    while keep_going:
        keep_going, network, choice = queue.get()
        network = dc(network)
        canvas.delete("all")

        snake_i = dc(snake)
        food = placeFood(snake_i)

        for f in food:
            food_id = canvas.create_rectangle(*get_box(f[0], f[1]), fill="red")

        timer = 0
        collided = False
        body = []
        while not collided and not timer == ((2 * snake_i.XSIZE) * snake_i.YSIZE):
            root.update()
            get_output(network, snake_i)
            snake_i.updatePosition()
            if snake_i.body[0] in food:
                snake_i.score += 1
                for f in food: canvas.delete(food_id)
                food = placeFood(snake_i)
                for f in food: canvas.create_rectangle(*get_box(f[0], f[1]), fill="red")
                timer = 0
            else:
                if len(snake_i.body) > 10:
                    snake_i.body.pop()
                    canvas.delete(body[0])
                    body = body[1:]
                timer += 1  # timesteps since last eaten
            # win.addch(snake.XSIZE-2, snake.YSIZE-2, 'o')
            body.append(canvas.create_rectangle(*get_box(snake_i.body[0][0], snake_i.body[0][1]), fill="grey"))
            collided = snake_i.snakeHasCollided()
            hitBounds = (timer == ((2 * snake_i.XSIZE) * snake_i.YSIZE))
            time.sleep(0.1)

def snakeHasCollided(self):
    self.hit = False
    if self.body[0][0] == 0 or self.body[0][0] == (snake.YSIZE - 1) or self.body[0][1] == 0 or self.body[0][1] == (
            snake.XSIZE - 1): self.hit = True
    if self.body[0] in self.body[1:]: self.hit = True
    return (self.hit)

def sense_wall_ahead(self):
    self.getAheadLocation()
    return (
            self.ahead[0] == 0 or self.ahead[0] == (snake.YSIZE - 1) or self.ahead[1] == 0 or self.ahead[1] == (
                snake.XSIZE - 1))

def sense_food_ahead(self):
    self.getAheadLocation()
    return self.ahead in self.food

def sense_tail_ahead(self):
    self.getAheadLocation()
    return self.ahead in self.body

    print(hitBounds)
    raw_input("Press to continue...")

    return snake.score,

# This outline function provides partial code for running the game with an evolved agent
# There is no graphical output, and it runs rapidly, making it ideal for
# you need to modify it for running your agents through the game for evaluation
# which will depend on what type of EA you have used, etc.
# Feel free to make any necessary modifications to this section.

def xor_test(individual):
    fitness = float(0)
    for i in range(100):
        input = [random.choice([0, 1]), random.choice([0, 1])]
        input_temp = list(input)
        output = individual.run(input_temp)
        if (input == [0, 0] or input == [1, 1]) and output.index(max(output)) == 0:
            fitness += 1
        elif (input == [1, 0] or input == [0, 1]) and output.index(max(output)) == 1:
            fitness += 1
    return fitness / 100,

def runGameAverage(individual, gen_no=0, fitness_type="food", snake_id=5):
    output = 0
    for i in range(10):
        output += runGame(individual, gen_no=gen_no, fitness_type=fitness_type, snake_id=snake_id)
    return output / 10

def runGameAverage0(individual, gen_no=0, fitness_type="food"):
    return runGameAverage(individual, gen_no, fitness_type, 0)

def runGameAverage1(individual, gen_no=0, fitness_type="food"):
    return runGameAverage(individual, gen_no, fitness_type, 1)

def runGameAverage2(individual, gen_no=0, fitness_type="food"):
    return runGameAverage(individual, gen_no, fitness_type, 2)

def runGameAverage3(individual, gen_no=0, fitness_type="food"):
    return runGameAverage(individual, gen_no, fitness_type, 3)

def runGameAverage4(individual, gen_no=0, fitness_type="food"):
    return runGameAverage(individual, gen_no, fitness_type, 4)

def runGameAverage5(individual, gen_no=0, fitness_type="food"):
    return runGameAverage(individual, gen_no, fitness_type, 5)

def runGameAverage6(individual, gen_no=0, fitness_type="food"):
    return runGameAverage(individual, gen_no, fitness_type, 6)

def runGameAverage7(individual, gen_no=0, fitness_type="food"):
    return runGameAverage(individual, gen_no, fitness_type, 7)

def runGame(individual, fitness_type="food", location="", gen_no=0, snake_id=5):
    global snake
    #snake = snakes[snake_id]
    totalScore = 0
    snake = dc(snake)

    snake._reset()
    food = placeFood(snake)
    timer = 0
    timer_cumulative = [1.0, 0.0]
    alive_timer = 0
    explored_area = []
    choices = []
    while not snake.snakeHasCollided() and not timer == snake.XSIZE * snake.YSIZE:
        choice = get_output(individual, snake)
        choices.append(choice)
        snake.updatePosition()

        if snake.body[0] not in explored_area:
            explored_area.append(list(snake.body[0]))

        if snake.body[0] in food:
            snake.score += 1
            food = placeFood(snake)
            timer_cumulative = [timer_cumulative[0] + 1, timer_cumulative[1] + timer]
            timer = 0
        else:
            if len(snake.body) > 10:
                snake.body.pop()
            timer += 1  # timesteps since last eaten
        alive_timer += 1
    if fitness_type == "food":
        return snake.score


"""Summary statistics table.

Functions
---------
print_summary_statistics(data_dictionary, sigfigs=2, plusfigs=1, file=sys.stdout)

"""
import sys

import numpy as np
import tabulate

__author__ = "Randal J Barnes and Elizabeth Barnes"
__version__ = "30 October 2021"

def print_summary_statistics(data_dictionary, sigfigs=2, plusfigs=1, file=sys.stdout):
    """Print a summary statistics table for the data in the dictionary.

    The summary statistics include:
        "cnt" : count
        "min" : minimum value
        "25%" : 25 percentile
        "50%" : median
        "75%" : 75 percentile
        "max" : maximum value
        "avg" : arithmetic average
        "std" : standard deviation (sample)
        "iqr" : inter-quartile range

    Arguments
    ---------
    data_dictionary : dict
        The key:values pairs in the dictionary are name and data vector.
        The name is a str, the data vector is a ndarray of shape (n,).

    sigfigs : int, default=2
        The number of places to the right of the decimal point used to
        print the data order statistics.

    plusfigs : int, default=1
        The number of additional places to the right of the decimal point
        used to print the mean and standard deviation.

    file : file object, default=sys.stdout (i.e. the screen)
        Where to print the table.

    Returns
    -------
    None

    Usage
    -----
    print_summary_statistics({"y_train" : y_train, "y_val" : y_val})

    Notes
    -----
    * The computations do not filter out nan values.  So, if there are
        nan or inf values in the data vector, the resulting statistics
        will be impacted.

    * If the computation of any statistic fails and raises an exception,
        then the entire row in the table is set to nan.

    """
    # Make the table.
    table = []
    for key in data_dictionary:
        data_vector = data_dictionary[key]
        try:
            row = [
                key,
                np.shape(data_vector)[0],
                np.min(data_vector),
                np.percentile(data_vector, 25),
                np.median(data_vector),
                np.percentile(data_vector, 75),
                np.max(data_vector),
                np.mean(data_vector),
                np.std(data_vector),
                np.percentile(data_vector, 75) - np.percentile(data_vector, 25),
            ]
        except:
            row = [
                key,
                np.nan,
                np.nan,
                np.nan,
                np.nan,
                np.nan,
                np.nan,
                np.nan,
                np.nan,
                np.nan,
            ]
        table.append(row)

    # Print a table.
    print("\n", file=file)
    print(
        tabulate.tabulate(
            table,
            [" ", "cnt", "min", "25%", "50%", "75%", "max", "avg", "std", "iqr"],
            tablefmt="presto",
            floatfmt=(
                "s",
                ".0f",
                f".{sigfigs}f",
                f".{sigfigs}f",
                f".{sigfigs}f",
                f".{sigfigs}f",
                f".{sigfigs}f",
                f".{sigfigs+plusfigs}f",
                f".{sigfigs+plusfigs}f",
                f".{sigfigs}f",
            ),
        ),
        file=file,
    )
    print("\n", file=file)


import datagood

if __name__ == '__main__':
    with open('list_goods.txt', 'r', encoding='utf-8') as file:
        list_with_goods = file.readlines()
        for str_good in list_with_goods:
            list_good = str_good.split(':')
            name = list_good[0]
            price = list_good[1]
            count = list_good[2]
            production_date = list_good[3]
            expiration_day = list_good[4]
            datagood.good_list.add_good_in_list(datagood.Good(name, price, count, production_date, expiration_day))

print('Товар с максимальной ценой:', datagood.good_list.get_good_with_max_price())
print('Товар с минимальной ценой:', datagood.good_list.get_good_with_min_price())
print('Максимальное количество товара:', datagood.good_list.get_good_with_max_count())
print('Минимальное количество товара:', datagood.good_list.get_good_with_min_count())
print('Данные из get_mean_price:')
print(datagood.good_list.get_mean_price())