# -*- coding: utf-8 -*-
# Name: sql.py
# Author: Shao Shidong
# Date: 2020/5/24
# Version: Python 3.6 64-bit

import re
import shlex
from itertools import zip_longest

SQL_OPS = ['=','>','<','>=','<=','!=','NOT LIKE','LIKE','BETWEEN']
SQL_AGG = ['max','min','count','sum','avg','']
SQL_COND_OPS = ['AND','OR','']
SQL_ORDERBY_OPS = ['DESC LIMIT','ASC LIMIT','DESC','ASC','LIMIT','']
SQL_DISTINCT_OP = ['distinct','']
SQL_KEYWORDS = ['where','group by','order by']

SQL_AGG_dict = {'max':'maximum', 'min':'minimum', 'count':'count','sum':'sum', 'avg':'average'}
SQL_ORDERBY_OPS_dict = {'DESC LIMIT':'descending limit', 'ASC LIMIT':'ascending limit', 'DESC':'descending', 'ASC':'ascending', 'LIMIT':'limit', 'NONE': 'none'}
SQL_OPS_dict = {'=':'=','>':'>','<':'<','>=':'> =','<=':'< =','!=':'! =','NOT LIKE':'not like','LIKE':'like','BETWEEN':'between'}

class SQLStatement():
    def __init__(self, query = None, database=None):
        self.COLS = []
        self.WHERE = []
        self.GROUPBY = []
        self.ORDERBY = []
        self.ORDERBY_OP = []
        self.TABLE = ""
        self.HAVING = []
        self.LIMIT_VALUE = ""
        self.database = database
        if isinstance(query, str):
            self.from_query(query)

    def __eq__(self, other):
        if not isinstance(other, SQLStatement):
            return NotImplemented
        if not self.TABLE :
            self.TABLE = self.COLS[0].column.table_name
        if not other.TABLE :
            other.TABLE = other.COLS[0].column.table_name
        return (set(self.COLS)==set(other.COLS) and set(self.WHERE)==set(other.WHERE) and set(self.GROUPBY)==set(other.GROUPBY)and set(self.ORDERBY)==set(other.ORDERBY)and set(self.ORDERBY_OP)==set(other.ORDERBY_OP)
                and self.TABLE == other.TABLE and set(self.HAVING)==set(other.HAVING) and str(self.LIMIT_VALUE)==str(other.LIMIT_VALUE))

    def component_match(self, other):
        return (
            set(self.COLS)==set(other.COLS),
            set(self.WHERE)==set(other.WHERE) if self.WHERE else None,
            set(self.GROUPBY)==set(other.GROUPBY) if self.GROUPBY else None,
            set(self.ORDERBY)==set(other.ORDERBY) and set(self.ORDERBY_OP)==set(other.ORDERBY_OP) if self.ORDERBY else None,
            set(self.HAVING)==set(other.HAVING) if self.HAVING else None,
            str(self.LIMIT_VALUE)==str(other.LIMIT_VALUE) if self.LIMIT_VALUE else None,
            self.keywords == other.keywords)

    @property
    def keywords(self):
        keywords = []
        if self.WHERE:
            keywords += ['where']
        if self.GROUPBY:
            keywords += ['group by']
        if self.ORDERBY:
            keywords += ['order by']
        return keywords

    @property
    def and_ors(self):
        andors = []
        for condition in self.WHERE:
            if condition.cond_op:
                andors += [condition.cond_op]
        for condition in self.HAVING:
            if condition.cond_op:
                andors += [condition.cond_op]
        return andors

    def from_query(self, query):
        query = query.replace(';','')
        if ' - ' in query or ' + ' in query or ' / ' in query:
            raise NotImplementedError(f"Doesn't support arithmetic in query : {query}")
        if 'AS ' in query:
            aliases = re.findall(r'(?<=AS ).\w+', query)
            for alias in aliases:
                query = query.replace(f'{alias}.','')
                query = query.replace(f'AS {alias}','')
        clauses = ['SELECT','FROM','WHERE','GROUP BY','HAVING','ORDER BY']
        clauses = [clause for clause in clauses if clause in query]
        query_split = re.split(f'({"|".join(clauses)})',query)[1:]
        self.TABLE = str.lower(query_split[3]).strip()
        for i in range(0,len(query_split),2):
            clause = query_split[i]
            statement = query_split[i+1]
            if clause == 'SELECT':
                for column in statement.split(','):
                    agg, distinct = '',''
                    column = str.lower(column).strip()
                    if 'distinct(' in column:
                        distinct, column = column.split('(')
                        column = column.replace('(','').replace(')','')
                    if '(' in column:
                        agg = column.split('(')[0]
                        agg = agg.replace('distinct','').strip()
                        column = column.split('(')[1].split(')')[0].strip()
                    if 'distinct' in column:
                        distinct, column = column.split()
                    column = self.database.get_column(column, self.TABLE)
                    self.COLS.append(ColumnSelect(column, agg=agg, distinct=distinct))
            elif clause == 'WHERE':
                if ' BETWEEN ' in statement:
                    col = statement.split(' BETWEEN ')
                    intervals = col[1].split(' AND ')
                    col = col[0].strip(' ')
                    statement = col + ' BETWEEN ' + intervals[0] +  ' ' + intervals[1]
                conditional_ops = re.findall('( AND | OR | BETWEEN )',statement)
                conditions = re.split(' AND | OR ',statement)
                for condition, conditional_op in zip_longest(conditions, conditional_ops, fillvalue=""):
                    if conditional_op == ' BETWEEN ':
                        column, op, value, valueless = condition.split(' ')
                        conditional_op = ''
                    else:
                        column, op, value = re.findall(r'(.*\(.*?\)|\'.*?\'|".*?"|NOT LIKE|\S+)',condition)
                        valueless = ""
                    value = str.lower(value.strip('\'"%'))
                    valueless = str.lower(valueless.strip('\'"%'))
                    column = str.lower(column).strip()
                    conditional_op = conditional_op.strip()
                    column = self.database.get_column(column, self.TABLE)
                    self.WHERE.append(Condition(column, op, value, conditional_op,"","",valueless))
            elif clause == 'GROUP BY':
                for column in statement.split(','):
                    column = str.lower(column).replace('(','').replace(')','').strip()
                    column = self.database.get_column(column, self.TABLE)
                    column = ColumnSelect(column, '', '')
                    self.GROUPBY.append(column)
            elif clause == 'HAVING':
                if ' BETWEEN ' in statement:
                    col = statement.split(' BETWEEN ')
                    intervals = col[1].split(' AND ')
                    col = col[0].strip(' ')
                    statement = col + ' BETWEEN ' + intervals[0] +  ' ' + intervals[1]
                conditional_ops = re.findall('( AND | OR | BETWEEN )',statement)
                conditions = re.split(' AND | OR ',statement)
                for condition, conditional_op in zip_longest(conditions, conditional_ops, fillvalue=""):
                    if conditional_op == ' BETWEEN ':
                        column, op, value, valueless = condition.split(' ')
                        conditional_op = ''
                    else:
                        column, op, value = re.findall(r'(.*\(.*?\)|\'.*?\'|".*?"|NOT LIKE|\S+)',condition)
                        valueless=""
                    agg, distinct = '', ''
                    column = str.lower(column)
                    if '(' in column:
                        agg = column.split('(')[0].strip()
                        column = column.split('(')[1].split(')')[0]
                    if 'distinct' in column:
                        distinct, column = column.split()
                    value = str.lower(value.strip('\'"%'))
                    valueless = str.lower(valueless.strip('\'"%'))
                    conditional_op = conditional_op.strip()
                    column = self.database.get_column(column, self.TABLE)
                    self.HAVING.append(Condition(column, op, value, conditional_op, agg, distinct,valueless))
            elif clause == 'ORDER BY':
                for column in statement.split(','):
                    agg, distinct = '', ''
                    if '(' in column:
                        agg = column.split('(')[0].strip()
                        col = column.split('(')[1].split(')')[0].strip()
                    else:
                        col = column.split()[0].strip()
                    col = str.lower(col)
                    if 'distinct' in col:
                        distinct, col = col.split()
                    orderby_op = re.findall(f'({"|".join(SQL_ORDERBY_OPS[:-1])})', column)
                    if orderby_op:
                        self.ORDERBY_OP += orderby_op
                        if 'LIMIT' in orderby_op[0]:
                            fnd = re.findall(r'\d+', statement)
                            self.LIMIT_VALUE = fnd[-1]
                    else:
                        self.ORDERBY_OP += [""]
                    agg = str.lower(agg)
                    column = self.database.get_column(col, self.TABLE)
                    column = ColumnSelect(column, agg, distinct)
                    self.ORDERBY.append(column)

    def generate_history(self):
        history_dict = {'col':[], 'agg':[], 'andor':[], 'keyword':[], 'op':[], 'value':[], 'having':[], 'decasc':[], 'distinct':[]}
        history = ['select']
        history_dict['keyword'] += history.copy()
        history_dict['col'] += [history.copy()]
        for column in self.COLS:
            history += [' '.join(column.column.to_list())]
            history_dict['agg'] += [history.copy()]
            if column.agg:
                history += [column.agg]
            history_dict['col'] += [history.copy()]

            history_dict['distinct'] += [history.copy()]
            if column.distinct:
                history += [column.distinct]
        if self.WHERE:
            history += ['where']
            for condition in self.WHERE:
                history += [' '.join(condition.column.to_list())]
                history_dict['op'] += [history.copy()]
                history += [condition.op]
                if condition.op == 'BETWEEN':
                    if condition.value:
                        history += [condition.value]
                    history_dict['value'] += [history.copy()]
                else:
                    history_dict['value'] += [history.copy()]
                    if condition.value:
                        history += [condition.value]
                history_dict['andor'] += [history.copy()]
                if condition.cond_op:
                    history += [condition.cond_op]
            history_dict['col'] += [history.copy()]
        if self.GROUPBY:
            history += ['group by']
            for groupby in self.GROUPBY:
                history += [' '.join(groupby.column.to_list())]
            history_dict['col'] += [history.copy()]
        history_dict['having'] += [history.copy()]
        if self.HAVING:
            history += ['having']
            for condition in self.HAVING:
                history += [' '.join(condition.column.to_list())]
                history_dict['agg'] += [history.copy()]
                if condition.column_select.agg:
                    history += [condition.column_select.agg]
                history_dict['op'] += [history.copy()]
                history += [condition.op]
                history_dict['value'] += [history.copy()]
                if condition.value:
                    history += [condition.value]
                history_dict['andor'] += [history.copy()]
                if condition.cond_op:
                    history += [condition.cond_op]
            history_dict['col'] += [history.copy()]
        if self.ORDERBY:
            history += ['order by']
            for orderby in self.ORDERBY:
                history += [' '.join(orderby.column.to_list())]
                history_dict['agg'] += [history.copy()]
                if orderby.agg:
                    history += [orderby.agg]
            history_dict['col'] += [history.copy()]
        for orderby_op in self.ORDERBY_OP:
            history_dict['decasc'] += [history.copy()]
            if orderby_op:
                history += [orderby_op]
        return history_dict

    def __str__(self):
        """Convert object to string representation of SQL"""
        string_cols = [str(col) for col in self.COLS]
        string_where = [str(where) for where in self.WHERE]
        string_group = [str(group) for group in self.GROUPBY]
        string_having = [str(having) for having in self.HAVING]
        string_order = [f"{str(order)} {orderop} {limitvalue}" for order, orderop, limitvalue in zip_longest(self.ORDERBY, self.ORDERBY_OP, [self.LIMIT_VALUE], fillvalue="") if self.ORDERBY]
        if not self.TABLE :
            self.TABLE = self.COLS[0].column.table_name
        sql_string = f"SELECT {','.join(string_cols)} FROM {self.TABLE}"
        if string_where:
            sql_string += f" WHERE {' '.join(string_where)}"
        if string_group:
            sql_string += f" GROUP BY {','.join(string_group)}"
        if string_having:
            sql_string += f" HAVING {' '.join(string_having)}"
        if string_order:
            sql_string += f" ORDER BY {','.join(string_order)}"
        sql_string = sql_string.replace('( ','(').replace('  ',' ')
        return sql_string

class ColumnSelect():
    column = None
    agg = ""
    distinct = ""
    def __init__(self, column, agg="", distinct=""):
        self.column = column
        self.agg = agg
        self.distinct = distinct

    def __str__(self):
        assert self.column, "column name can't be empty"
        assert self.agg in SQL_AGG, f"{self.agg} is not an SQL aggregator"
        assert self.distinct in SQL_DISTINCT_OP, f"{self.distinct} is not an SQL distinct operator"
        if self.agg:
            return f"{self.agg}({self.distinct} {self.column})"
        return f"{self.distinct} {self.column}"

    def __eq__(self, other):
        if not isinstance(other, ColumnSelect):
            return NotImplemented
        return str(self) == str(other)

    def __hash__(self):
        return hash(str(self))

class Condition():
    column_select = None
    op = ""
    value = ""
    cond_op = ""
    @property
    def column(self):
        return self.column_select.column

    @property
    def agg(self):
        return self.column_select.agg
    @agg.setter
    def agg(self, value):
        self.column_select.agg = value

    @property
    def distinct(self):
        return self.column_select.distinct

    @distinct.setter
    def distinct(self, value):
        self.column_select.distinct = value

    def __init__(self, column, op="", value="", cond_op="", agg="", distinct="",valueless=""):
        self.column_select = ColumnSelect(column, agg, distinct)
        self.op = op
        self.value = value
        self.cond_op = cond_op
        self.valueless = valueless

    def __str__(self):
        assert self.op in SQL_OPS, f"{self.op} is not an SQL operation"
        assert self.cond_op in SQL_COND_OPS, f"{self.cond_op} is not an SQL conditional operator (AND/OR)"

        if self.column.column_type == 'text':
            if "BETWEEN" in self.op:
                return f'{self.column_select} {self.op} "%{self.value}%" {SQL_COND_OPS[0]} {self.valueless}'
            elif "LIKE" in self.op:
                return f'{self.column_select} {self.op} "%{self.value}%" {self.cond_op}'
            else:
                return f'{self.column_select} {self.op} "{self.value}" {self.cond_op}'
        if "BETWEEN" in self.op:
            return f"{self.column_select} {self.op} {self.value} {SQL_COND_OPS[0]} {self.valueless}"
        else:
            return f"{self.column_select} {self.op} {self.value} {self.cond_op}"

    def __eq__(self, other):
        if not isinstance(other, Condition):
            return NotImplemented
        return str(self) == str(other)

    def __hash__(self):
        return hash(str(self))

SQL_TYPES = ("text","number", "others")

class DataBase():
    def __init__(self, data):
        self.tables = []
        self.tables_dict = {}
        if isinstance(data, dict):
            self.from_dict(data)

    def from_dict(self, data_dict):
        self.db_name = data_dict['db_id']
        self.primary_keys = data_dict['primary_keys']
        columns_all = []
        column_types_all = []
        table_names = data_dict['table_names_original']
        for (table_id, column_name), column_type in zip(data_dict['column_names_original'], data_dict['column_types']):
            column_name = str.lower(column_name)
            if table_id >= len(columns_all):
                columns_all.append([])
                column_types_all.append([])
            if table_id>=0:
                columns_all[table_id].append(column_name)
                column_types_all[table_id].append(column_type)

        for table_name, columns, column_types in zip(table_names, columns_all, column_types_all):
            table_name =  str.lower(table_name)
            columns.append('*')
            column_types.append('text')
            table = Table(table_name, columns, column_types)
            self.tables.append(table)
            self.tables_dict[table_name] = table

    def to_list(self):
        lst = []
        for table in self.tables:
            lst += [[col_type, table.table_name,col_name] for col_name, col_type in zip(table.columns, table.column_types)]
        return lst

    def get_column(self, column, table):
        return self.tables_dict[table].column_dict[column]

    def get_column_from_idx(self, idx):
        columns = []
        for table in self.tables:
            columns += list(table.column_dict.values())
        return columns[idx]

    def get_idx_from_column(self, column):
        columns = self.to_list()
        return columns.index(column.to_list())

class Table():
    def __init__(self, table_name, column_names, column_types):
        self.column_dict = {}
        for column_name, column_type in zip(column_names, column_types):
            col = Column(column_name, table_name, column_type)
            self.column_dict[column_name] = col
        self.table_name = table_name
        self.columns = column_names
        self.column_types = column_types

class Column():
    def __init__(self, column_name, table_name, column_type, database_name=""):
        self.column_name = column_name
        self.table_name = table_name
        self.column_type = column_type
        self.database_name = database_name

    def __str__(self):
        return self.column_name

    def __repr__(self):
        return str(self)

    def to_list(self):
        return [self.column_type, self.table_name,self.column_name]


from django.contrib.auth import get_user_model
from django.core.cache import cache
from django.test import TestCase, Client

from http import HTTPStatus

from ..models import Post, Group

User = get_user_model()

class StaticURLTests(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.user = User.objects.create_user(username='test-user')
        cls.author = User.objects.create_user(username='author')
        cls.group = Group.objects.create(
            title='Тестовая группа',
            slug='test-slug',
            description='Тестовое описание',
        )
        cls.post = Post.objects.create(
            author=cls.author,
            text='Тестовый пост',
        )

    def setUp(self):
        cache.clear()
        self.guest_client = Client()
        self.authorized_client = Client()
        self.authorized_client.force_login(self.user)
        self.author_client = Client()
        self.author_client.force_login(self.author)

    def test_home_url_exists_at_desired_location(self):
        """Страница / доступна любому пользователю."""
        response = self.guest_client.get('/')
        self.assertEqual(response.status_code, HTTPStatus.OK)

    def test_group_list_url_exists_at_desired_location(self):
        """Страница /group/test-slug/ доступна любому пользователю."""
        response = self.guest_client.get('/group/test-slug/')
        self.assertEqual(response.status_code, HTTPStatus.OK)

    def test_profile_url_exists_at_desired_location(self):
        """Страница /profile/test-user/ доступна любому пользователю."""
        response = self.guest_client.get('/profile/test-user/')
        self.assertEqual(response.status_code, HTTPStatus.OK)

    def test_post_detail_url_exists_at_desired_location(self):
        """Страница /posts/1/ доступна любому пользователю."""
        response = self.guest_client.get('/posts/1/')
        self.assertEqual(response.status_code, HTTPStatus.OK)

    def test_post_create_url_exists_at_desired_location(self):
        """Страница /create/ доступна авторизованному пользователю."""
        response = self.authorized_client.get('/create/')
        self.assertEqual(response.status_code, HTTPStatus.OK)

    def test_post_edit_url_exists_at_desired_location(self):
        """Страница /posts/1/edit/ доступна автору."""
        response = self.author_client.get('/posts/1/edit/')
        self.assertEqual(response.status_code, HTTPStatus.OK)

    def test_unexisting_url_exists_at_desired_location(self):
        """Страница /unexisting_page/ не доступна."""
        response = self.guest_client.get('/unexisting_page/')
        self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND)

    def test_urls_uses_correct_template(self):
        """URL-адрес использует соответствующий шаблон."""
        templates_url_names = {
            '/': 'posts/index.html',
            '/group/test-slug/': 'posts/group_list.html',
            '/profile/test-user/': 'posts/profile.html',
            f'/posts/{self.post.id}/': 'posts/post_detail.html',
            '/create/': 'posts/create_post.html',
            f'/posts/{self.post.id}/edit/': 'posts/create_post.html',
        }
        for address, template in templates_url_names.items():
            with self.subTest(address=address):
                response = self.author_client.get(address)
                self.assertTemplateUsed(response, template)


from functools import reduce

from odoo import _, api, fields, models

class CrmPhonecall(models.Model):
    """Model for CRM phonecalls."""

    _name = "crm.phonecall"
    _description = "Phonecall"
    _order = "id desc"
    _inherit = ["mail.thread", "utm.mixin"]

    date_action_last = fields.Datetime(string="Last Action", readonly=True)
    date_action_next = fields.Datetime(string="Next Action", readonly=True)
    create_date = fields.Datetime(string="Creation Date", readonly=True)
    team_id = fields.Many2one(
        comodel_name="crm.team",
        string="Sales Team",
        index=True,
        help="Sales team to which Case belongs to.",
    )
    user_id = fields.Many2one(
        comodel_name="res.users",
        string="Responsible",
        default=lambda self: self.env.user,
    )
    partner_id = fields.Many2one(comodel_name="res.partner", string="Contact")
    company_id = fields.Many2one(comodel_name="res.company", string="Company")
    description = fields.Text()
    state = fields.Selection(
        [
            ("open", "Confirmed"),
            ("cancel", "Cancelled"),
            ("pending", "Pending"),
            ("done", "Held"),
        ],
        string="Status",
        tracking=3,
        default="open",
        help="The status is set to Confirmed, when a case is created.\n"
        "When the call is over, the status is set to Held.\n"
        "If the callis not applicable anymore, the status can be set "
        "to Cancelled.",
    )
    email_from = fields.Char(string="Email", help="These people will receive email.")
    date_open = fields.Datetime(string="Opened", readonly=True)
    name = fields.Char(string="Call Summary", required=True)
    active = fields.Boolean(required=False, default=True)
    duration = fields.Float(help="Duration in minutes and seconds.")
    tag_ids = fields.Many2many(
        comodel_name="crm.tag",
        relation="crm_phonecall_tag_rel",
        string="Tags",
        column1="phone_id",
        column2="tag_id",
    )
    partner_phone = fields.Char(string="Phone")
    partner_mobile = fields.Char("Mobile")
    priority = fields.Selection(
        selection=[("0", "Low"), ("1", "Normal"), ("2", "High")],
        default="1",
    )
    date_closed = fields.Datetime(string="Closed", readonly=True)
    date = fields.Datetime(default=lambda self: fields.Datetime.now())
    opportunity_id = fields.Many2one(comodel_name="crm.lead", string="Lead/Opportunity")
    direction = fields.Selection(
        [("in", "In"), ("out", "Out")], default="out", required=True
    )

    @api.onchange("partner_id")
    def _onchange_partner_id(self):
        """Contact number details should be change based on partner."""
        if self.partner_id:
            self.partner_phone = self.partner_id.phone
            self.partner_mobile = self.partner_id.mobile

    @api.onchange("opportunity_id")
    def _onchange_opportunity_id(self):
        """Based on opportunity, change contact, tags, partner, team."""
        if self.opportunity_id:
            self.team_id = self.opportunity_id.team_id.id
            self.partner_phone = self.opportunity_id.phone
            self.partner_mobile = self.opportunity_id.mobile
            self.partner_id = self.opportunity_id.partner_id.id
            self.tag_ids = self.opportunity_id.tag_ids.ids

    def write(self, values):
        """Override to add case management: open/close dates."""
        if values.get("state"):
            if values.get("state") == "done":
                values["date_closed"] = fields.Datetime.now()
                self.compute_duration()
            elif values.get("state") == "open":
                values["date_open"] = fields.Datetime.now()
                values["duration"] = 0.0
        return super().write(values)

    def compute_duration(self):
        """Calculate duration based on phonecall date."""
        phonecall_dates = self.filtered("date")
        phonecall_no_dates = self - phonecall_dates
        for phonecall in phonecall_dates:
            if phonecall.duration <= 0 and phonecall.date:
                duration = fields.Datetime.now() - phonecall.date
                values = {"duration": duration.seconds / 60.0}
                phonecall.write(values)
            else:
                phonecall.duration = 0.0
        phonecall_no_dates.write({"duration": 0.0})
        return True

    def get_values_schedule_another_phonecall(self, vals):
        res = {
            "name": vals.get("name"),
            "user_id": vals.get("user_id") or self.user_id.id,
            "description": self.description,
            "date": vals.get("schedule_time") or self.date,
            "team_id": vals.get("team_id") or self.team_id.id,
            "partner_id": self.partner_id.id,
            "partner_phone": self.partner_phone,
            "partner_mobile": self.partner_mobile,
            "priority": self.priority,
            "opportunity_id": self.opportunity_id.id,
            "campaign_id": self.campaign_id.id,
            "source_id": self.source_id.id,
            "medium_id": self.medium_id.id,
        }
        if vals.get("tag_ids"):
            res.update({"tag_ids": [(6, 0, vals.get("tag_ids"))]})
        return res

    def schedule_another_phonecall(self, vals, return_recordset=False):
        """Action :('schedule','Schedule a call'), ('log','Log a call')."""
        phonecall_dict = {}
        for call in self:
            values = call.get_values_schedule_another_phonecall(vals)
            new_id = self.create(values)
            if vals.get("action") == "log":
                call.write({"state": "done"})
            phonecall_dict[call.id] = new_id
        if return_recordset:
            return reduce(lambda x, y: x + y, phonecall_dict.values())
        else:
            return phonecall_dict

    def redirect_phonecall_view(self):
        """Redirect on the phonecall related view."""
        # Select the view
        tree_view_id = self.env.ref("crm_phonecall.crm_case_phone_tree_view").id
        form_view_id = self.env.ref("crm_phonecall.crm_case_phone_form_view").id
        search_view_id = self.env.ref(
            "crm_phonecall.view_crm_case_phonecalls_filter"
        ).id
        value = {}
        for call in self:
            value = {
                "name": _("Phone Call"),
                "view_type": "form",
                "view_mode": "tree,form",
                "res_model": "crm.phonecall",
                "res_id": call.id,
                "views": [
                    (form_view_id or False, "form"),
                    (tree_view_id or False, "tree"),
                    (False, "calendar"),
                ],
                "type": "ir.actions.act_window",
                "search_view_id": search_view_id or False,
            }
        return value

    def action_make_meeting(self):
        """Open meeting's calendar view to schedule a meeting on phonecall."""
        partner_ids = [self.env["res.users"].browse(self.env.uid).partner_id.id]
        res = {}
        for phonecall in self:
            if phonecall.partner_id and phonecall.partner_id.email:
                partner_ids.append(phonecall.partner_id.id)
            res = self.env["ir.actions.act_window"]._for_xml_id(
                "calendar.action_calendar_event"
            )
            res["context"] = {
                "default_phonecall_id": phonecall.id,
                "default_partner_ids": partner_ids,
                "default_user_id": self.env.uid,
                "default_email_from": phonecall.email_from,
                "default_name": phonecall.name,
            }
        return res

    def _prepare_opportunity_vals(self):
        return {
            "name": self.name,
            "partner_id": self.partner_id.id,
            "phone": self.partner_phone or self.partner_id.phone,
            "mobile": self.partner_mobile or self.partner_id.mobile,
            "email_from": self.partner_id.email,
            "team_id": self.team_id.id,
            "description": self.description,
            "priority": self.priority,
            "type": "opportunity",
            "campaign_id": self.campaign_id.id,
            "source_id": self.source_id.id,
            "medium_id": self.medium_id.id,
            "tag_ids": [(6, 0, self.tag_ids.ids)],
        }

    def action_button_convert2opportunity(self):
        """Convert a phonecall into an opp and redirect to the opp view."""
        self.ensure_one()
        opportunity = self.env["crm.lead"]
        opportunity_id = opportunity.create(self._prepare_opportunity_vals())
        self.write({"opportunity_id": opportunity_id.id, "state": "done"})
        return opportunity_id.redirect_lead_opportunity_view()


import pygame as pg
from pygame import *
from OpenGL.GL import *
from OpenGL.GLU import *
import numpy as np
import random
from rectangle import RectangleMesh
from handle_json import write, clear_json

class App:

    def __init__(self):

        # initialize pygame for GUI
        pg.init()
        self.display = (512,512)
        self.screen = pg.display.set_mode(self.display, pg.OPENGL|pg.DOUBLEBUF) # tell pygame we run OPENGL & DOUBLEBUFFERING, one frame vis & one drawing
        pg.display.set_caption("Wireframe generator")

        # activation variables
        self.axes = 0
        self.screenshot = 1
        clear_json()

        # initialize OpenGL
        glClearColor(0,0,0,1)

        glMatrixMode(GL_PROJECTION) # activate projection matrix
        gluPerspective(45, self.display[0]/self.display[1], 0.1, 50)
        self.projectionmatrix = glGetDoublev(GL_PROJECTION_MATRIX)
        # draw wired rectangle
        self.rectangle = RectangleMesh(random.uniform(0.1,5), random.uniform(0.1,5), random.uniform(0.1,5), [0,0,0], [0,0,-15])
        self.rectangle.draw_wired_rect()

        self.mainLoop()

    def mainLoop(self):
        rect_name = 1
        img_number = 1 # counts the rectangle that is been shown
        img_shot = 1 # counts how many screenshots were taken

        running = True
        while(running):
            # Check for events
            for event in pg.event.get():

                if (event.type == pg.QUIT):
                    running = False

                if (event.type == KEYDOWN) and (event.key == K_s):
                    # enable screenshots
                    self.screenshot = not self.screenshot

                if (event.type == KEYDOWN) and (event.key == K_a):
                    # draw axes
                    self.axes = not self.axes

                if (event.type == KEYDOWN) and (event.key == K_RIGHT):

                    # random position of rectangle
                    self.rectangle.set_rotation(random.uniform(0,360), random.uniform(0,360), random.uniform(0,360))
                    self.rectangle.set_translation(random.uniform(-5,5), random.uniform(-5,5), random.uniform(-10,-20))
                    self.rectangle.draw_wired_rect()
                    pg.time.wait(60)

                    print(f"random rotation: {self.rectangle.eulers}")
                    print(f"random translation: {self.rectangle.position}")

                    # take screenshot && write rectangle data to CSV file
                    if (self.screenshot):

                        # calculate annotation
                        wc, pc, center = self.get_annotations(self.rectangle.modelview, self.projectionmatrix, glGetIntegerv(GL_VIEWPORT))
                        # check if rectangle valid
                        valid = self.object_on_screen(pc)
                        # write to json
                        write(rect_name, img_shot, self.rectangle.get_norm_dim(),  wc, pc, center, valid)

                        if (rect_name == img_number):
                            self.save_image(rect_name, img_shot)
                            img_shot += 1
                        else:
                            img_number += 1
                            rect_name = img_number
                            img_shot = 1
                            self.save_image(rect_name, img_shot)
                            img_shot += 1

                if (event.type == KEYDOWN) and (event.key == K_RETURN):
                    print("delete rectangle...")
                    del self.rectangle
                    # new size of rectangle
                    self.rectangle = RectangleMesh(random.uniform(0.1,5), random.uniform(0.1,5), random.uniform(0.1,5), [0,0,0], [0,0,-15])
                    print("created rectangle: ", self.rectangle.width, self.rectangle.height, self.rectangle.depth)
                    # rectangle name count
                    rect_name += 1

                # --- Drawing the scene --- #
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

                self.rectangle.draw_wired_rect()

                if (self.axes):
                    self.draw_axes()

                pg.display.flip()
                pg.time.wait(60)

        self.quit()

    def quit(self):
        pg.quit()

    def save_image(self, rect_name, img_shot):
        print("taking screenshot...")
        pixels = glReadPixels(0, 0, self.display[0], self.display[1], GL_RGB, GL_UNSIGNED_BYTE)
        image = pg.image.frombuffer(pixels, (self.display[0], self.display[1]), 'RGB') # read pixels from the OpenGL buffer
        #image = pg.transform.flip(image, False, True) # flip
        name = "wireframes\\img" + str(rect_name) + "_" + str(img_shot) + ".png"
        pg.image.save(image, name) # It then converts those pixels into a Pygame surface and saves it using pygame.image.save()

    def draw_axes(self):
        glPushMatrix()
        glTranslatef(0,0,-15)
        # X axis (red)
        glBegin(GL_LINES)
        glColor3f(1, 0, 0)
        glVertex3f(0, 0, 0)
        glVertex3f(5, 0, 0)
        glEnd()

        # Y axis (green)
        glBegin(GL_LINES)
        glColor3f(0, 1, 0)
        glVertex3f(0, 0, 0)
        glVertex3f(0, 5, 0)
        glEnd()

        # Z axis (blue)
        glBegin(GL_LINES)
        glColor3f(0, 0, 1)
        glVertex3f(0, 0, 0)
        glVertex3f(0, 0, 5)
        glEnd()
        glPopMatrix()

    def get_annotations(self, model_view, projection, viewport):
        # Calculate world and pixel cords of vertices rectangle
        world_coordinates = []
        pixel_coordinates = []
        center = []
        for vertex in self.rectangle.vertices:
            x_screen, y_screen, z =  gluProject(vertex[0], vertex[1], vertex[2], model_view, projection, viewport)
            pixel_coordinates.append((int(x_screen),int(y_screen)))
            x_world, y_world, z_world = gluUnProject( x_screen, y_screen, 0, model_view, projection, viewport)
            world_coordinates.append((x_world, y_world, z_world))

        print("pixel coordinates: ",pixel_coordinates)
        print("world coordinates: ",world_coordinates)

        # Calculate center
        x_screen, y_screen, z = gluProject(0, 0, 0, model_view, projection, viewport)
        x_world, y_world, z_world = gluUnProject( x_screen, y_screen, 0, model_view, projection, viewport)
        center.append((x_world, y_world, z_world))
        center.append((int(x_screen), int(y_screen)))

        return world_coordinates, pixel_coordinates, center

    def object_on_screen(self, projection_coordinates):
        for i in projection_coordinates:
            if (i[0] not in range(0,self.display[0]+1) or i[1] not in range(0,self.display[1]+1)):
                return "false"
            else:
                continue
        return "true"

if __name__ == "__main__":
    myApp = App()


import re

import requests

import tekinbot.utils.post as pu
from tekinbot.utils.config import tekin_id

comm_re = re.compile(
    f'(^{tekin_id} :?(mtg me|mtg)'
    f'(?P<exact> exactly|)(: |:| )(?P<query>.*)$|'
    f'^.*\[\[(?P<exact_bk>!)?(?P<query_bk>.*)\]\].*$)',
    flags=re.IGNORECASE
)

link_stem = 'https://api.scryfall.com/cards/named'
tekin_planeswalker = 'https://i.imgur.com/9agLW68.png'
scryfall_favicon = 'https://assets.scryfall.com/favicon.ico'
mtg_colours = {
    'W': '#F8E7B9',
    'U': '#B3CEEA',
    'B': '#A69F9D',
    'R': '#EA9F82',
    'G': '#C4D3CA',
    'C': '#FFFFFF',
}

def search(query, exact):
    search_payload = {"exact" if exact else "fuzzy": query}
    search_resp = requests.get(
        link_stem, params=search_payload
    )

    if search_resp.status_code == 404:
        return {'text': (
            'Can\'t find the said card, or there are multiple matches. '
            'Try to be more precise. Anyway, here is me in the Multiverse: '
            f'{tekin_planeswalker}'
        )}
    elif not search_resp.ok:
        return {'text': 'I can\'t into internetz'}

    try:
        resp = search_resp.json()

        text = (
            f'I did a scry 1 and found {resp["name"]} based on the search '
            f'query:\n{resp["scryfall_uri"]}.\nTry to be more '
            'precise if this is not it.'
        )

        colour = resp.get('color_identity')
        colour = 'C' if not colour else colour[0]

        attachment = {
            'fallback': text,
            'author_name': 'Scryfall:TM: brought to you by Tekin',
            'author_link': f'{resp["scryfall_uri"]}',
            'author_icon': f'{scryfall_favicon}',
            'pretext': f'I did a scry 1 and found {resp["name"]}',
            'image_url': (
                '{url}'.format(url=resp["image_uris"]["normal"])
            ) if resp["layout"] != "transform" else (
                '\n'.join([
                    face['image_uris']['normal'] for face in resp['card_faces']
                ])
            ),
            'color': mtg_colours[colour],
            'fields': [
                {'title': 'Name', 'value': f'{resp["name"]}', 'short': True},
                {'title': 'Mana', 'value': '{}'.format(
                    resp["mana_cost"] if resp['layout'] != 'transform' else (
                        ' // '.join([face['mana_cost']
                                     for face in resp['card_faces']])
                    )), 'short': True},
                {'title': 'Type Line',
                    'value': f'{resp["type_line"]}', 'short': True},
                {'title': 'Set', 'value': f'{resp["set"]}', 'short': True},
                {'title': 'Text', 'value': '{}'.format(
                    resp['oracle_text'] if resp['layout'] == 'normal' else (
                        '\n'.join([face['oracle_text']
                                   for face in resp['card_faces']])
                    )
                )}
            ]
        }
        return {'attachments': [attachment]}

    except Exception as e:
        print(e)
        return {'text': 'Can\'t find the said card.'}

def process(request):
    match = re.fullmatch(comm_re, request['event']['text'])
    query = match.group('query') or match.group('query_bk')
    exact = bool(match.group('exact') or match.group('exact_bk'))

    if not query:
        return {'text': 'What exactly are you looking for?'}

    return search(query, exact)

def post(request, resp):
    return pu.post_formatted_text(request, resp, auth=pu.bot_auth())


import numpy as np
import csv, math

file = open("data.txt")
clean = list(file)
cl = [i.split(',') for i in clean]
out = np.concatenate(cl).tolist()
out.remove("")
#print(len(out))
n = 4
list_ = []
i=0
while(i<len(out)):
	x = out[i:i+n]
	#print(x)
	s = x[0].split(" ")
	x = [int(s[0]),int(s[1]),int(x[1]),int(x[2]),int(x[3])]
	list_.append(x)
	i=i+n

print(list_)
csvfile=open('data.csv','w')
obj=csv.writer(csvfile)
for data in list_:
	obj.writerow(data)
csvfile.close()

#print(type(list_[0][0]))
#########################################################
id_pos = {1:(0,0), 2:(0,1), 3:(0,2), 4:(0,3), 5:(0,4),
		  6:(1,0), -104:(1,1), 8:(1,2), 9:(1,3), 10:(1,4),
		  11:(2,0), 12:(2,1), -1407:(2,2), 14:(2,3), 15:(2,4),
		  16:(3,0), 17:(3,1), 18:(3,2), 19:(3,3), 20:(3,4),
		  21:(4,0), 22:(4,1), 23:(4,2), 24:(4,3), 25:(4,4),}

# zero = ["-1047"] #(id,time)
# five = ["-104"]
zero = []
five = []

t = list_[0][1]
i = 0
for node in list_:
	if(i==0 and (node[1]-t)<30):
		zero.append(node[0])
	else:
		i=-1
		five.append(node[0])
predict = []

print(zero)
print(five)

x,y = 0,0

pos1 = id_pos[zero[0]]

for b in five:
	#print(pos2)
	pos2 = id_pos[b]
#
	d = (pos2[0]-pos1[0] , pos2[1]-pos1[1])
	x,y = x+d[0] , y+d[1]
	predict_pos = (pos2[0]+d[0],pos2[1]+d[1])
	predict.append(predict_pos)

x = x/len(five)
y = y/len(five)
if(y==0):
	print("Net predicted direction is: 90 degrees from "+str(pos1))

else:
	print("Net predicted direction is:"+str(math.degrees(math.atan(x/y))) +"degrees from "+str(pos1))
for a in predict:
	print(a)


import torch
import numpy as np
import torch.nn as nn
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde
from scipy.special import kl_div
import os
from util import mix_dataset

np.random.seed(35813)
torch.manual_seed(35813)

### Direct to working environment
WORK_PATH = "/home/jia/Desktop/MSc_Project/imagetemplate/FedLIT"
MODEL_OUTPUT_PATH = "/home/jia/Desktop/MSc_Project/imagetemplate/FedLIT/output"

# def plot_latent_distribution(local_ground_truth, mixed_ground_truth, predicted, save_path):

#     # Flatten the datasets to 1D arrays
#     flattened_dataset1 = np.array(local_ground_truth).reshape(-1,1)
#     flattened_dataset2 = np.array(mixed_ground_truth).reshape(-1,1)
#     flattened_dataset3 = np.array([img.flatten() for img in predicted]).reshape(-1,1)
#     # Calculate the KDE for each dataset
#     kde_dataset1 = gaussian_kde(flattened_dataset1)
#     kde_dataset2 = gaussian_kde(flattened_dataset2)
#     kde_dataset3 = gaussian_kde(flattened_dataset3)

#     # Define the x-axis range for the plots
#     x_range = np.linspace(min(flattened_dataset1.min(), flattened_dataset2.min(), flattened_dataset3.min()),
#                           max(flattened_dataset1.max(), flattened_dataset2.max(), flattened_dataset3.max()), 50)

#     # Plot the KDE curves as line graphs
#     plt.plot(x_range, kde_dataset1(x_range), label='local test set')
#     plt.plot(x_range, kde_dataset2(x_range), label='mixed test set')
#     plt.plot(x_range, kde_dataset3(x_range), label='augmented')

#     # plt.hist(flattened_dataset1, bins=50, alpha=0.7, label='ground_truth')
#     # plt.hist(flattened_dataset2, bins=50, alpha=0.7, label='predicted')

#     plt.xlabel('Value')
#     plt.ylabel('Density')
#     plt.title('Distributions of Latent Embeddings')
#     plt.legend()
#     plt.savefig(save_path)
#     plt.show()

# def linearize_image_data(dataset):
#     new_dataset = []
#     for image, label in dataset:
#         linear_image = image.flatten()
#         new_dataset.append(linear_image)
#     return new_dataset

def plot_latent_distribution(local_ground_truth, mixed_ground_truth, predicted, save_path):

    # Flatten the datasets to 1D arrays
    flattened_dataset1 = np.concatenate(local_ground_truth).flatten()
    flattened_dataset2 = np.concatenate(mixed_ground_truth).flatten()
    flattened_dataset3 = np.concatenate(predicted).flatten()

    # Calculate the KDE for each dataset
    kde_dataset1 = gaussian_kde(flattened_dataset1)
    kde_dataset2 = gaussian_kde(flattened_dataset2)
    kde_dataset3 = gaussian_kde(flattened_dataset3)

    # Define the x-axis range for the plots
    x_range = np.linspace(min(flattened_dataset1.min(), flattened_dataset2.min(), flattened_dataset3.min()),
                          max(flattened_dataset1.max(), flattened_dataset2.max(), flattened_dataset3.max()), 50)

    # Plot the KDE curves as line graphs
    plt.plot(x_range, kde_dataset1(x_range), label='local test set')
    plt.plot(x_range, kde_dataset2(x_range), label='mixed test set')
    plt.plot(x_range, kde_dataset3(x_range), label='augmented')

    # plt.hist(flattened_dataset1, bins=50, alpha=0.7, label='ground_truth')
    # plt.hist(flattened_dataset2, bins=50, alpha=0.7, label='predicted')

    plt.xlabel('Value')
    plt.ylabel('Density')
    plt.title('Distributions of Latent Embeddings')
    plt.legend()
    plt.savefig(save_path)
    plt.show()

def mix_dataset(datset_list):
    mixed_dataset = []

    for datset in datset_list:
        mixed_dataset.extend(datset)

    np.random.shuffle(mixed_dataset)

    return mixed_dataset

# if __name__ == '__main__':

#     for number in range(5):
#         output_path = MODEL_WEIGHT_BACKUP_PATH + "/" + 'number' + str(number)
#         data_path = WORK_PATH + "/" + 'classifier_data/'
#         gt_imgs1 = np.load(data_path + 'client1/mixed_test_data.npy', allow_pickle=True)
#         gt_imgs1 = linearize_image_data(gt_imgs1)
#         gt_imgs2 = np.load(data_path + 'client2/mixed_test_data.npy', allow_pickle=True)
#         gt_imgs2 = linearize_image_data(gt_imgs2)
#         gt_imgs3 = np.load(data_path + 'client3/mixed_test_data.npy', allow_pickle=True)
#         gt_imgs3 = linearize_image_data(gt_imgs3)
#         gt_imgs4 = np.load(data_path + 'client4/mixed_test_data.npy', allow_pickle=True)
#         gt_imgs4 = linearize_image_data(gt_imgs4)
#         gt_imgs5 = np.load(data_path + 'client5/mixed_test_data.npy', allow_pickle=True)
#         gt_imgs5 = linearize_image_data(gt_imgs5)

#         mixed_gt_imgs = mix_dataset([gt_imgs1, gt_imgs2, gt_imgs3, gt_imgs4, gt_imgs5])

#         for type in ['ablated_nofed', 'ablated_fed']:
#             save_path = output_path + "/" + type
#             dist_path = save_path + "/" + "dist_imgs" + "/"
#             if not os.path.exists(dist_path):
#                 os.makedirs(dist_path)

#             aug_img_path = save_path + '/' + 'aug_imgs/'
#             aug_imgs1 = np.load(aug_img_path + 'client1_aug_imgs.npy')
#             aug_imgs2 = np.load(aug_img_path + 'client2_aug_imgs.npy')
#             aug_imgs3 = np.load(aug_img_path + 'client3_aug_imgs.npy')
#             aug_imgs4 = np.load(aug_img_path + 'client4_aug_imgs.npy')
#             aug_imgs5 = np.load(aug_img_path + 'client5_aug_imgs.npy')

#             plot_latent_distribution(gt_imgs1, mixed_gt_imgs, aug_imgs1, dist_path+'client1_latent_dist')
#             plot_latent_distribution(gt_imgs2, mixed_gt_imgs, aug_imgs2, dist_path+'client2_latent_dist')
#             plot_latent_distribution(gt_imgs3, mixed_gt_imgs, aug_imgs3, dist_path+'client3_latent_dist')
#             plot_latent_distribution(gt_imgs4, mixed_gt_imgs, aug_imgs4, dist_path+'client4_latent_dist')
#             plot_latent_distribution(gt_imgs5, mixed_gt_imgs, aug_imgs5, dist_path+'client5_latent_dist')

if __name__ == '__main__':

    for number in range(5):
        work_path = MODEL_OUTPUT_PATH + "/" + 'number' + str(number)

        gt_emb_path = MODEL_OUTPUT_PATH + f'/number{number}/ablated_nofed/gt_embs/'
        gt_embs1 = np.load(gt_emb_path + 'client1_test_embs.npy')
        gt_embs2 = np.load(gt_emb_path + 'client2_test_embs.npy')
        gt_embs3 = np.load(gt_emb_path + 'client3_test_embs.npy')
        gt_embs4 = np.load(gt_emb_path + 'client4_test_embs.npy')
        gt_embs5 = np.load(gt_emb_path + 'client5_test_embs.npy')

        mixed_gt_embs = mix_dataset([gt_embs1, gt_embs2, gt_embs3, gt_embs4, gt_embs5])

        for type in ['ablated_nofed', 'ablated_fed']:
            save_path = work_path + "/" + type
            dist_path = save_path + "/" + "dist_embs" + "/"
            if not os.path.exists(dist_path):
                os.makedirs(dist_path)

            aug_emb_path = save_path + '/' + 'aug_embs/'
            aug_embs1 = np.load(aug_emb_path + 'client1_aug_embs.npy')
            aug_embs2 = np.load(aug_emb_path + 'client2_aug_embs.npy')
            aug_embs3 = np.load(aug_emb_path + 'client3_aug_embs.npy')
            aug_embs4 = np.load(aug_emb_path + 'client4_aug_embs.npy')
            aug_embs5 = np.load(aug_emb_path + 'client5_aug_embs.npy')

            plot_latent_distribution(gt_embs1, mixed_gt_embs, aug_embs1, dist_path+'client1_latent_dist')
            plot_latent_distribution(gt_embs2, mixed_gt_embs, aug_embs2, dist_path+'client2_latent_dist')
            plot_latent_distribution(gt_embs3, mixed_gt_embs, aug_embs3, dist_path+'client3_latent_dist')
            plot_latent_distribution(gt_embs4, mixed_gt_embs, aug_embs4, dist_path+'client4_latent_dist')
            plot_latent_distribution(gt_embs5, mixed_gt_embs, aug_embs5, dist_path+'client5_latent_dist')


import os
import glob
import logging
import argparse
import tqdm
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

from data import fullsize_sequence, DOWNGRADES
from model import load_model
from util import reset_session

DATASETS = ['Set5_LR_bicubic', 'Set14_LR_bicubic', 'DIV2K_valid_LR_bicubic', 'BSDS100_LR_bicubic', 'Urban100_LR_bicubic']

logger = logging.getLogger(__name__)

def model_paths(input_dir):
	if os.path.splitext(input_dir)[1] == '.h5':
		return [input_dir]
	path_pattern = os.path.join(input_dir, '**', '*.h5')
	paths = glob.glob(path_pattern, recursive=True)
	paths.sort()
	return paths

def predict_model(model_path, image_path, scale, outdir):
	print('Load model %s', model_path)
	model = load_model(model_path, compile=False)

	for dataset_name in DATASETS:
		print(dataset_name)
		target_outdir = os.path.join(outdir, dataset_name, 'X%d'%(scale))
		target_image_path = os.path.join(image_path, dataset_name, 'X%d'%(scale))
		if not os.path.exists(target_outdir):
			os.makedirs(target_outdir)

		image_filenames = sorted(glob.glob(os.path.join(target_image_path, '*.png')))
		print(os.path.join(target_image_path, '*.png'))
		if len(image_filenames) == 0:
			logger.warning('No image files. Stop prediction..')
			exit()

		logger.info('Start prediction with %s', model_path)
		for i, f in tqdm.tqdm(enumerate(image_filenames)):
			filename = os.path.split(f)[1]
			im = Image.open(f).convert('RGB')
			im = np.array(im)
			im = np.reshape(im, (1,) + im.shape)
			output = model.predict(im, batch_size=1)
			output = np.squeeze(output)
			im_out = output
			if output.shape[-1] > 3:
				im_out = output[:,:,:3]
				logvar = output[:,:,3:]
				logvar_filename = os.path.join(target_outdir, os.path.splitext(filename)[0])
				np.save(logvar_filename, logvar)
				plt.imsave(logvar_filename+'_logvar.png', logvar.mean(axis=-1), cmap='viridis')

			im_out = Image.fromarray(np.uint8(im_out))
			im_out.save(os.path.join(target_outdir, filename))

def main(args):
	"""
	Evaluate all models in a user-defined directory against the DIV2K validation set.

	The results are written to a user-defined JSON file. All models in the input
	directory must have been trained for the same downgrade operator (bicubic or
	unknown) and the same scale (2, 3 or 4).
	"""

	mps = model_paths(args.indir)

	if mps:
		reset_session(args.gpu_memory_fraction)
		predict_model(mps[-1], args.dataset, args.scale, args.outdir)

	else:
		logger.warning('No models found in %s', args.indir)

def parser():
	parser = argparse.ArgumentParser(description='Evaluation against DIV2K validation set')

	parser.add_argument('-d', '--dataset', type=str, default='/home/esoc/datasets/SuperResolution/',
						help='path to DIV2K dataset with images stored as numpy arrays')
	parser.add_argument('-i', '--indir', type=str,
						help='path to models directory')
	parser.add_argument('-o', '--outdir', type=str, default='./image_predictions',
						help='output JSON file')
	parser.add_argument('-s', '--scale', type=int, default=2, choices=[2, 3, 4],
						help='super-resolution scale')
	parser.add_argument('--downgrade', type=str, default='bicubic', choices=DOWNGRADES,
						help='downgrade operation')
	parser.add_argument('--gpu-memory-fraction', type=float, default=0.8,
						help='fraction of GPU memory to allocate')

	return parser

if __name__ == '__main__':
	logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)

	main(parser().parse_args())


import csv
import requests
from bs4 import BeautifulSoup

url = 'https://barefootbuttons.com/product-category/version-1/'
response = requests.get(url)

html = response.text
soup = BeautifulSoup(html, 'html.parser')

products = soup.find_all('div', 'product-small box')

for product in products:
    link = product.find('a')['href']
    title = product.find('p', {'class': 'name product-title woocommerce-loop-product__title'}).text.strip()
    price = float(product.find('span', {'class': 'woocommerce-Price-amount amount'}).text.strip().replace('$', ''))
    with open('woo_products.csv', 'a', newline='', encoding='utf-8') as file:
        writer = csv.writer(file)
        writer.writerow([title, link, price])


#!/usr/bin/env python
# coding=utf-8

import sys
import os
import shutil

sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'common'))
import common

_creator_list = []

class UnityRuntimeCreator(object):
    def __init__(self, opts):
        self.TAG = "UnityRuntimeCreator"
        common.LOGI(self.TAG, "opts: " + str(opts))
        self.build_sdk = opts["build_sdk"]
        self.workspace = opts["workspace"]
        self.script_path = opts["script_path"]
        self.target = opts["target"]
        if not self.target:
            self.target = "online"

        self.build_replacer_list = []

        self.proj_unityruntime_dir = os.path.join(self.script_path, "../../framework/UnityRuntime")
        self.proj_gplayenginebridge_dir = os.path.join(self.script_path, "../../framework/GplayEngineBridge")

        self.proj_unityruntime_dir_src_dir = os.path.join(self.proj_unityruntime_dir, "src", "main", "java")
        self.proj_gplayenginebridge_src_dir = os.path.join(self.proj_gplayenginebridge_dir, "src", "main", "java")

        self.proj_unityruntime_build_dir = os.path.join(self.proj_unityruntime_dir, "build")
        self.proj_gplayenginebridge_build_dir = os.path.join(self.proj_gplayenginebridge_dir, "build")

        self.version = self._get_version()
        self.versionName = self._get_version_name().replace('"', "")
        common.LOGI(self.TAG, "Runtime SDK versionCode: " + self.version)

        if not opts["out"]:
            self.out_dir = os.path.join(self.workspace, 'out-unityruntime-sdk')
            self.out_dir = os.path.join(self.out_dir, self._get_version_name().replace('"', ""))
            common.recreate_folder(self.out_dir)
            self.debug_directory = os.path.join(self.workspace, 'debug')
        else:
            self.out_dir = os.path.join(opts["out"], self._get_version_name().replace('"', ""))
            self.debug_directory = os.path.join(self.out_dir, 'debug')
        self.out_dir_temp = os.path.join(self.workspace, "out-unityruntime-sdk-temp")
        common.recreate_folder(self.out_dir_temp)

        self.sdk_file_for_runtimesdk_no_dex = os.path.join(self.out_dir, "libunityruntime-not-dex-" + self.versionName + ".jar")
        self.sdk_file_for_runtimesdk = os.path.join(self.out_dir, "libunityruntime-" + self.versionName + ".jar")

        self.sdk_jar_no_dex_obfuscated_path = os.path.join(self.out_dir_temp, "libunityruntime-sdk-no-dex-obfuscated.jar")
        self.sdk_jar_dex_path = os.path.join(self.out_dir_temp, "libunityruntime-sdk-dex.jar")
        self.output_class_path = os.path.join(self.out_dir_temp, "classes")
        self.proguard = not opts["dont_proguard"]

    def _get_version(self):
        # Get the version of current SDK
        return common.find_string_from_file(
            os.path.join(self.proj_unityruntime_dir_src_dir, "com", "skydragon", "gplay", "runtime", "bridge", "CocosRuntimeBridge.java"),
            r"private\s+static\s+final\s+int\s+VERSION_CODE\s*=\s*(.*)\s*;"
        )

    def _get_version_name(self):
        versionName =  common.find_string_from_file(
            os.path.join(self.proj_unityruntime_dir_src_dir, "com", "skydragon", "gplay", "runtime", "bridge", "CocosRuntimeBridge.java"),
            r"private\s+static\s+final\s+String\s+VERSION\s*=\s*(.*);"
        )
        return versionName

    def _clean(self):
        common.LOGI(self.TAG, "Cleaning ...")

        file_to_remove_list = [
            self.out_dir_temp,
            self.proj_unityruntime_build_dir,
            self.proj_gplayenginebridge_build_dir
        ]

        common.safe_remove_files(file_to_remove_list)

    def _generate_cut_jar(self, jar_path, config, out_dir):
        '''Invoke JarCutter tool to customize jar file'''
        # Ensure the our dir is empty
        common.recreate_folder(out_dir)

        # Run the JarCutter
        common.run_command(
            "python " + os.path.join(self.script_path, "../jar-cutter/JarCutter.py") +
            " -c " + config +
            " -s " + jar_path +
            " -o " + out_dir,
            error_message="cutting jar file (%s) failed!" % jar_path
        )

    def _generate_unityruntime_jar_file(self, force_dont_proguard=False):
        common.LOGI(self.TAG, "Generating runtime sdk jar file ..., force_dont_proguard:" + str(force_dont_proguard))

        common.ensure_folder_exists(self.debug_directory)

        proguard_file_path = "None"
        mapping_file_path = "None"
        if not force_dont_proguard and self.proguard:
            proguard_file_path = os.path.join(self.script_path, "proguard-unityruntime.txt")
            mapping_file_path = os.path.join(self.debug_directory, "mapping-libunityruntime-" + self.version + ".txt")

        common.run_command(
            "python " + os.path.join(self.script_path, "../jar-maker/JarMaker.py") +
            " -s " + self.proj_unityruntime_dir_src_dir +
            " -s " + self.proj_gplayenginebridge_src_dir +
            " -o " + self.out_dir_temp +
            " -f " + os.path.split(self.sdk_jar_no_dex_obfuscated_path)[-1] +
            " --ref-lib " + os.path.join(self.script_path, "..", "common", "lib", "android.jar") +
            " -p " + proguard_file_path +
            " -m " + mapping_file_path
        )

    def _generate_cut_jar_for_unityruntime_sdk_dex(self):
        common.LOGI(self.TAG, "Generating jar file for unityruntime sdk ...")
        out_jar_file_name = common.get_file_name(self.sdk_jar_no_dex_obfuscated_path)
        jar_cutter_out_dir = os.path.join(self.out_dir_temp, "jar-cutter-out-for-unityruntime-dex")
        jar_cutter_config_path = os.path.join(self.script_path, "jar-cutter-for-unityruntime-dex.json")
        self._generate_cut_jar(self.sdk_jar_no_dex_obfuscated_path, jar_cutter_config_path, jar_cutter_out_dir)
        cut_jar_file_path = os.path.join(jar_cutter_out_dir, out_jar_file_name)
        common.generate_dex_jar(cut_jar_file_path, self.sdk_jar_dex_path)
        # Copy dex sdk file to the output directory
        shutil.copy(self.sdk_jar_dex_path, self.sdk_file_for_runtimesdk)
        shutil.copy(self.sdk_jar_no_dex_obfuscated_path, self.sdk_file_for_runtimesdk_no_dex)
        # Remove the dex file since it may be generated with the same name
        # in next step (I means generating cut jar for tencent)
        common.safe_remove_file(self.sdk_jar_dex_path)

    def revert(self):
        for replacer in self.build_replacer_list:
            replacer.revert()
        return

    def run(self):
        common.LOGI(self.TAG, "RUNNING ...")
        # Clean temp files before generate classes files
        self._clean()

        if self.build_sdk == "all" or self.build_sdk == "runtime":
            # Generate runtime for normal channel
            self._generate_unityruntime_jar_file()
            self._generate_cut_jar_for_unityruntime_sdk_dex()
            self.revert()

        # clean after build
        self._clean()

        common.LOGI(self.TAG, "DONE!")

def main():
    common.LOGI("SDKCreator.py:main", "main entry ...")

    from optparse import OptionParser

    parser = OptionParser()

    build_sdk = ("all", "gplay", "runtime", "cocosv2", "cocosv3")

    build_target = ("online", "sandbox", "develop")

    parser.add_option("-t", "--target",
                      action="store", type="choice", choices=build_target, dest="target", default="online",
                      help="SDK run in target to be built, could be " + "'" + "', '".join(build_target) + "'")

    parser.add_option("-o", "--out",
                      action="store", type="string", dest="out", default=None,
                      help="The output folder")

    parser.add_option("-b", "--build-sdk",
                      action="store", type="choice", choices=build_sdk,
                      dest="build_sdk", default="all",
                      help="SDK kind to be built, could be " + "'" + "', '".join(build_sdk) + "'")

    parser.add_option("", "--dont-proguard",
                      action="store_true", dest="dont_proguard", default=False,
                      help="Whether to obfuscate java codes")

    (opts, args) = parser.parse_args()

    common.assert_if_failed(len(args) == 0, "Don't add parameters without `-t`,`-b` and `--dont-proguard`")

    opts = vars(opts)
    opts['workspace'] = os.path.abspath(os.getcwd())
    opts['script_path'] = os.path.dirname(os.path.realpath(__file__))

    if opts["build_sdk"] == "all" or opts["build_sdk"] == "unityv5":
        opts["engineVersion"] = "V5"
        unity_creator = UnityRuntimeCreator(opts)
        _creator_list.append(unity_creator)
        unity_creator.run()

if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        # raceback.print_exc()
        #for creator in _creator_list:
        #    creator.revert()

        if e.__class__.__name__ == "ErrorMessage":
            common.LOGE("SDKCreator.py", e.message)
            sys.exit(1)
        else:
            raise


from datetime import datetime
from typing import Dict, Generator, List, Optional, Tuple, Union
from sqlalchemy.future import select
from sqlalchemy.sql.expression import delete, update
from sqlalchemy.sql.functions import func
from zavod.logs import get_logger
from followthemoney.types import registry
from nomenklatura.resolver import Resolver
from nomenklatura.statement import Statement

from opensanctions.core.db import stmt_table
from opensanctions.core.db import Conn, upsert_func
from opensanctions.core.dataset import Dataset

log = get_logger(__name__)

def save_statements(conn: Conn, statements: List[Statement]) -> None:
    # unique = {s["id"]: s for s in values}
    # values = list(unique.values())
    if not len(statements):
        return None
    # log.debug("Saving statements", size=len(statements))
    values = [s.to_dict() for s in statements]
    istmt = upsert_func(stmt_table).values(values)
    stmt = istmt.on_conflict_do_update(
        index_elements=["id"],
        set_=dict(
            canonical_id=istmt.excluded.canonical_id,
            schema=istmt.excluded.schema,
            prop_type=istmt.excluded.prop_type,
            target=istmt.excluded.target,
            lang=istmt.excluded.lang,
            original_value=istmt.excluded.original_value,
            last_seen=istmt.excluded.last_seen,
        ),
    )
    conn.execute(stmt)
    return None

def all_statements(
    conn: Conn, dataset: Dataset = None, external: bool = False
) -> Generator[Statement, None, None]:
    q = select(stmt_table)
    if dataset is not None and dataset.name != Dataset.ALL:
        q = q.filter(stmt_table.c.dataset.in_(dataset.scope_names))
    if external is False:
        q = q.filter(stmt_table.c.external == False)
    # q = q.order_by(stmt_table.c.canonical_id.asc())
    conn = conn.execution_options(stream_results=True)
    cursor = conn.execute(q)
    while True:
        rows = cursor.fetchmany(20000)
        if not rows:
            break
        for row in rows:
            yield Statement.from_db_row(row)
    # for row in result.yield_per(20000):
    #     yield Statement.from_db_row(row)

def count_entities(
    conn: Conn,
    dataset: Optional[Dataset] = None,
    target: Optional[bool] = None,
    schemata: Optional[List[str]] = None,
) -> int:
    q = select(func.count(func.distinct(stmt_table.c.canonical_id)))
    q = q.filter(stmt_table.c.prop_type == Statement.BASE)
    q = q.filter(stmt_table.c.external == False)  # noqa
    if target is not None:
        q = q.filter(stmt_table.c.target == target)
    if dataset is not None:
        q = q.filter(stmt_table.c.dataset.in_(dataset.scope_names))
    if schemata is not None and len(schemata):
        q = q.filter(stmt_table.c.schema.in_(schemata))
    return conn.scalar(q)

def entities_datasets(
    conn: Conn, dataset: Optional[Dataset] = None
) -> Generator[Tuple[str, str], None, None]:
    """Return all entity IDs with the dataset they belong to."""
    q = select(stmt_table.c.entity_id, stmt_table.c.dataset)
    q = q.filter(stmt_table.c.prop_type == Statement.BASE)
    if dataset is not None:
        q = q.filter(stmt_table.c.dataset.in_(dataset.scope_names))
    q = q.distinct()
    result = conn.execution_options(stream_results=True).execute(q)
    for row in result:
        entity_id, scope = row
        yield (entity_id, scope)

def cleanup_dataset(conn: Conn, dataset: Dataset):
    # remove non-current statements (in the future we may want to keep them?)
    q = select(func.max(stmt_table.c.last_seen))
    q = q.filter(stmt_table.c.prop == Statement.BASE)
    # q = q.filter(stmt_table.c.external == False)  # noqa
    q = q.filter(stmt_table.c.dataset == dataset.name)
    q = q.group_by(stmt_table.c.dataset)
    cursor = conn.execute(q)
    last_seen = cursor.scalar()
    if last_seen is not None:
        pq = delete(stmt_table)
        pq = pq.where(stmt_table.c.dataset == dataset.name)
        pq = pq.where(stmt_table.c.last_seen < last_seen)
        conn.execute(pq)

def resolve_all_canonical(conn: Conn, resolver: Resolver):
    log.info("Getting all canonical value pairs...", resolver=resolver)
    q = select(stmt_table.c.entity_id, stmt_table.c.canonical_id)
    q = q.distinct()
    # updated = 0
    updates: Dict[str, str] = {}
    cursor = conn.execute(q)
    while True:
        pairs = cursor.fetchmany(5000)
        if not pairs:
            break
        for (entity_id, current_id) in pairs:
            canonical_id = resolver.get_canonical(entity_id)
            if canonical_id != current_id:
                log.info(
                    "Resolve",
                    entity_id=entity_id,
                    canonical_id=canonical_id,
                    current_id=current_id,
                )
                updates[entity_id] = canonical_id

    log.info("Collected updates", count=len(updates))
    for entity_id, canonical_id in updates.items():
        uq = update(stmt_table)
        uq = uq.where(stmt_table.c.entity_id == entity_id)
        uq = uq.where(stmt_table.c.canonical_id != canonical_id)
        uq = uq.values({stmt_table.c.canonical_id: canonical_id})
        conn.execute(uq)

def resolve_canonical(conn: Conn, resolver: Resolver, canonical_id: str):
    referents = resolver.get_referents(canonical_id)
    log.debug(
        "Resolving",
        canonical=canonical_id,
        referents=referents,
        resolver=resolver,
    )
    q = update(stmt_table)
    q = q.where(stmt_table.c.entity_id.in_(referents))
    q = q.values({stmt_table.c.canonical_id: canonical_id})
    conn.execute(q)

def clear_statements(
    conn: Conn,
    dataset: Optional[Dataset] = None,
    external: Optional[bool] = None,
):
    q = delete(stmt_table)
    if external is not None:
        q = q.filter(stmt_table.c.external == external)
    # TODO: should this do collections?
    if dataset is not None:
        q = q.filter(stmt_table.c.dataset == dataset.name)
    conn.execute(q)


# https://leetcode.com/problems/merge-two-sorted-lists/
# tags: #bit_manipulation, #hash_table, #rolling_hash, #string
#
# Solution 1: Hash set
# We can count the number of combinations that can be formed of length k using input s and then compare it with
# the required number of combinations: 2^k
# Time complexity: O(n*k), Space complexity: O(n*k)
#
# Solution 1: Rolling hash
# https://leetcode.com/problems/check-if-a-string-contains-all-binary-codes-of-size-k/discuss/2092553/Explaining-the-Rolling-Hash-Method-or-Guide
# Time complexity: O(n), Space complexity: O(2^k)
class Solution:
    def hasAllCodes_set(self, s: str, k: int) -> bool:
        n, required_count = len(s), 2 ** k
        seen = set()

        for i in range(n - k + 1):
            temp = s[i:i+k]
            if temp not in seen:
                seen.add(temp)
                required_count -= 1
                if required_count == 0:
                    return True

        return False

    def hasAllCodes_rolling(self, s: str, k: int) -> bool:
        required_count, hash_code = 1 << k, 0
        seen = [0] * ((required_count - 1) // 32 + 1)
        mask = required_count - 1

        for i in range(len(s)):
            hash_code = ((hash_code << 1) & mask) | (int(s[i]))
            idx, bit_pos = hash_code // 32, hash_code % 32

            if i >= k - 1 and seen[idx] & (1 << bit_pos) == 0:
                seen[idx] |= (1 << bit_pos)
                required_count -= 1
                if required_count == 0:
                    return True
        return False

if __name__ == '__main__':
    sol = Solution()
    print(sol.hasAllCodes_rolling(s="00110110", k=2))  # True


import logging
import threading
import time

from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.decorators import (
    api_view,
    authentication_classes,
    permission_classes,
)
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from tradesense.repository.crypto_repository import CryptoRepository
from tradesense.services.analytics_service import AnalyticsService
from tradesense.services.socket_service import SocketService
from tradesense.services.tradesense_service import TradeSenseService
from tradesense.utils import get_message

# Create your views here.
@api_view(["GET"])
@authentication_classes([SessionAuthentication, BasicAuthentication])
@permission_classes([IsAuthenticated])
def start_trading(request):
    crypto_id = int(request.GET["id"])
    if crypto_id is None:
        logging.error("crypto id null")
        raise ValueError("Please pass crypto's id to trade in")
    conn = SocketService.get_connection()

    # Start a separate thread to handle threshold setting
    threshold_thread = threading.Thread(target=handle_threshold, args=(conn, crypto_id))
    threshold_thread.start()

    while True:
        tradesense_service = TradeSenseService(crypto_id)
        arbitrage_dto = tradesense_service.start_trading()
        msg = get_message(arbitrage_dto)
        logging.info(msg)
        conn.send(str(msg).encode())  # send data to the client
        time.sleep(60)

def handle_threshold(conn, crypto_id):
    while True:
        data = conn.recv(1024).decode()
        if data:
            # set_threshold:400
            try:
                threshold = int(data.split(":")[1])
                CryptoRepository.update_crypto_threshold(crypto_id, threshold)
                conn.send("Threshold successfully updated!".encode())
            except Exception as ex:
                logging.error(str(ex))
                conn.send(str(ex).encode())

@api_view(["GET"])
@authentication_classes([SessionAuthentication, BasicAuthentication])
@permission_classes([IsAuthenticated])
def analytics_view(request):
    analytics_dto = AnalyticsService().get_trade_analytics(request.GET)
    return Response(analytics_dto.to_json())


# Programmers 힙(Heap) 2. 디스크 컨트롤러

# 시간복잡도: O(NlogN)
import heapq

def solution(jobs):
    answer = 0 # 작업하는데 걸린 총시간
    start = -1 # 이전에 완료한 작업의 시작 시간
    now = 0 # 현재 시간(시점)
    i = 0 # 처리된 작업의 개수

    heap = [] # 현재 처리 가능한 jobs를 담는 힙

    while i < len(jobs):
        for job in jobs:
            if start < job[0] <= now: # 작업 요청 시점이 이전에 끝낸 작업보다 크고 현재 시간보다 작을 경우 작업 가능함
                heapq.heappush(heap, [job[1], job[0]]) # (처리 시간, 요청 시간) 형태로 힙에 저장함

        if len(heap) > 0: # 힙에 처리할 작업이 남은 경우
            current = heapq.heappop(heap) #cur은 현재 처리 중인 작업
            start = now
            now += current[0]
            answer += (now - current[1]) # 작업 요청 시간으로부터 처리 완료까지의 시간을 계산하여 answer에 저장함
            i += 1

        else: # 처리할 작업이 없는 경우
            now += 1

    return answer // len(jobs) # 평균 처리 시간 계산


n,m = map(int,input().split())
ac_list = [0] * (n + 1)
wa_list = [0] * (n + 1)

for i in range(m):
    q_no_tmp,anser = input().split()
    q_no = int(q_no_tmp)
    if anser == "AC":
        ac_list[q_no] = 1
    else:
        if ac_list[q_no] != 1:
            wa_list[q_no] = wa_list[q_no] + 1

wa_num = 0
ac_num = 0
for i in range(n + 1):
    if ac_list[i] != 1:
        wa_list[i] = 0
    else:
        ac_num = ac_num + 1
    wa_num = wa_num + wa_list[i]

print(ac_num,wa_num)


#!/usr/bin/env python
# coding: utf-8

# In[7]:

# !pip install -q pandas
# !pip install -q streamlit
# !pip install -q matplotlib
# !pip install -q seaborn
# !pip install -q plotly
# !pip install -q geopandas

import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
import seaborn as sns
import locale
import geopandas as gpd
import numpy as np
import altair as alt
import plotly.graph_objects as go

df = pd.read_csv('global-data-on-sustainable-energy (1).csv')
df.rename(columns={"Value_co2_emissions_kt_by_country":"CO2 Emissions"}, inplace=True)
df2 = df.dropna(subset=['Land Area(Km2)'])

# In[9]:

# Streamlit WebApp

# Set the theme settings
st.set_page_config(
    page_title="Sustainable Energy",
    page_icon="🌍♻",
    layout="wide",  # You can set the layout as per your preference
)

# Define your theme
st.markdown(
    f"""

    """,
    unsafe_allow_html=True
)

# # Set page config to wide layout
# st.set_page_config(layout="wide")

# Set the title of your Streamlit app
st.markdown("
Sustainable Energy
", unsafe_allow_html=True)

st.markdown(" ")
st.markdown(" ")
st.markdown(" ")
st.markdown(" ")
st.markdown(" ")
st.markdown(" ")
st.markdown(" ")

# Add a title to the sidebar
st.sidebar.markdown("
2022 Stats
", unsafe_allow_html=True)
st.sidebar.markdown(" ")
st.sidebar.markdown(" ")
st.sidebar.markdown(" ")
st.sidebar.markdown(" ")

# CO₂ Emissions Metric
st.sidebar.metric(label="Gloabl CO₂ Emissions", value="36.8 gigatons", delta="+0.9%")

st.sidebar.markdown(" ")
st.sidebar.markdown(" ")
st.sidebar.markdown(" ")

# Largest CO₂ Emissions Metric
st.sidebar.metric(label="Top Contributar to CO₂ Emissions", value="China")

st.sidebar.markdown(" ")
st.sidebar.markdown(" ")
st.sidebar.markdown(" ")

# Renewable Energy Electricity Generation Metric
st.sidebar.metric(label="Renewable Energy Electricity Generation", value="90%")

st.sidebar.markdown(" ")
st.sidebar.markdown(" ")
st.sidebar.markdown(" ")

# Visualization 1: Scatter Plot
st.markdown("
Renewable Energy Share in Consumption vs GDP
", unsafe_allow_html=True)

# Define the scatter plot
fig1 = px.scatter(
    df2,
    x='gdp_per_capita',
    y='Renewable energy share in the total final energy consumption (%)',
    size='Land Area(Km2)',
    size_max=50,
    hover_name='Entity',
    color='Continent',
    animation_frame='Year',
    animation_group='Entity',
    log_x=True,
    range_y=[0, 100],
    range_x=[100, 120000]
)

# Customize the layout
fig1.update_layout(
    width=1700,
    height=750,
)

# Display the scatter plot
st.plotly_chart(fig1)

st.markdown(" ")
st.markdown(" ")
st.markdown(" ")
st.markdown(" ")

# Visualization: Choropleth Map
st.markdown("
CO₂ Emissions per Capita
", unsafe_allow_html=True)

# Define custom colorscale
custom_colorscale = [
    [0.0, 'blue'],
    [0.0005, 'lightblue'],
    [0.001, 'lightcyan'],
    [0.08, 'lightgray'],
    [0.15, 'lightpink'],
    [0.3, 'lightcoral'],
    [0.5, 'salmon'],
    [0.75, 'orangered'],
    [0.9, 'red'],
    [1.0, 'darkred']
]

# Create the choropleth map
fig = px.choropleth(
    df,
    locations="Entity",
    locationmode="country names",
    color="CO2 Emissions",
    hover_name="Entity",
    animation_frame='Year',
    color_continuous_scale=custom_colorscale,
    projection='natural earth',
)

# Customize the color axis
fig.update_coloraxes(colorbar_title="CO₂ Emissions", cmin=0, cmax=10_000_000)

# Customize the layout
fig.update_layout(
    width=1700,
    height=750,
)

# Display the choropleth map
st.plotly_chart(fig)

st.markdown(" ")
st.markdown(" ")
st.markdown(" ")
st.markdown(" ")

# Visualization: Electricity Generation Over Time
st.markdown("
Global Electricity Generation Mix Over Time
", unsafe_allow_html=True)

# Group the data by year and aggregate the columns
grouped_df = df.groupby('Year').agg({
    'Electricity from fossil fuels (TWh)': 'sum',
    'Electricity from nuclear (TWh)': 'sum',
    'Electricity from renewables (TWh)': 'sum'
}).reset_index()

# Create a Figure
fig = go.Figure()

# Define distinct colors for each energy source
colors = {
    'Fossil Fuels': 'green',
    'Nuclear': 'red',
    'Renewables': 'blue'
}

# Add traces for each energy source
fig.add_trace(go.Scatter(x=grouped_df['Year'], y=grouped_df['Electricity from fossil fuels (TWh)'], fill='tozeroy', mode='none', name='Fossil Fuels', fillcolor=colors['Fossil Fuels']))
fig.add_trace(go.Scatter(x=grouped_df['Year'], y=grouped_df['Electricity from nuclear (TWh)'], fill='tonexty', mode='none', name='Nuclear', fillcolor=colors['Nuclear']))
fig.add_trace(go.Scatter(x=grouped_df['Year'], y=grouped_df['Electricity from renewables (TWh)'], fill='tonexty', mode='none', name='Renewables', fillcolor=colors['Renewables']))

# Customize the layout of the chart
fig.update_layout(xaxis_title="Year",
                  yaxis_title="Electricity Generation (TWh)",
                  showlegend=True)

fig.update_layout(
    width=1700,  # Set the width of the figure in pixels
    height=750,  # Set the height of the figure in pixels
)

# Display the chart in the Streamlit app
st.plotly_chart(fig)

st.markdown(" ")
st.markdown(" ")
st.markdown(" ")
st.markdown(" ")

st.markdown("
Access to Electricity Over Time (% of population)
", unsafe_allow_html=True)

# Create a filter for the continent
selected_continent = st.selectbox('Select Continent:', df['Continent'].unique())

# Filter the data based on the selected Continent
continent_filtered_df = df[df['Continent'] == selected_continent]

# Create a selectbox for filtering by Entity within the selected Continent
selected_entity = st.selectbox(f'Select Entity in {selected_continent}:', continent_filtered_df['Entity'].unique())

# Filter the data based on the selected Entity
filtered_df = continent_filtered_df[continent_filtered_df['Entity'] == selected_entity]

# Create the line chart
fig = px.line(filtered_df, x="Year", y="Access to electricity (% of population)", title=f"{selected_entity} ({selected_continent})")
fig.update_layout(xaxis_title="Year", yaxis_title="Access to Electricity (%)", width=1700, height=750)

# Display the line chart
st.plotly_chart(fig)


import argparse
import torch
import numpy as np
import pandas as pd
import os
import random

def normalize(array, axis=0):
    _min = array.min(axis=axis, keepdims=True)
    _max = array.max(axis=axis, keepdims=True)
    factor = _max - _min
    return (array - _min) / np.where(factor != 0, factor, 1)

def parse_click_history(history_list):
    clicks = list(map(lambda user_click: list(map(lambda item: item.split(':')[0],
                                                  user_click.split(','))),
                      history_list))
    _max_len = max(len(items) for items in clicks)
    clicks = [items + [0] * (_max_len - len(items)) for items in clicks]
    clicks = torch.tensor(np.array(clicks, dtype=np.long)) - 1
    return clicks

def parse_user_protrait(protrait_list):
    return torch.tensor(normalize(np.array(list(map(lambda x: x.split(','),
                                                    protrait_list)),
                                           dtype=np.float32)))

def process_item(filename, outdir):
    item_info = pd.read_csv(filename, ' ')
    item2id = np.array(item_info['item_id']) - 1
    item2loc = torch.tensor(np.array(item_info['location'], dtype=np.float32)[item2id])
    item2price = torch.tensor(normalize(np.array(item_info['price'], dtype=np.float32)[item2id]) * 10, dtype=torch.float32)
    item2feature = torch.tensor(normalize(np.array(list(map(lambda x: x.split(','),
                                               item_info['item_vec'])),
                                      dtype=np.float32)[item2id]))
    item2info = torch.cat([item2feature, item2price[:, None], item2loc[:, None]], dim=-1)
    torch.save([item2info, item2price, item2loc], os.path.join(outdir, 'items_info.pt'))

def process_data(filename, outdir, savename):
    dataset = pd.read_csv(filename, ' ')
    click_items = parse_click_history(dataset['user_click_history'])
    user_protrait = parse_user_protrait(dataset['user_protrait'])
    exposed_items = None
    if 'exposed_items' in dataset.columns:
        exposed_items = torch.tensor(np.array(list(map(lambda x: x.split(','),
                                                       dataset['exposed_items'])),
                                              dtype=np.long) - 1)
    torch.save([user_protrait, click_items, exposed_items],
               os.path.join(outdir, savename))

def main(args):
    print('processing items info ...')
    process_item(args.itemset, args.outdir)
    print('processing trainset ...')
    process_data(args.trainset, args.outdir, 'train.pt')
    print('processing devset ...')
    process_data(args.devset, args.outdir, 'dev.pt')
    print('processing testset ...')
    process_data(args.testset, args.outdir, 'test.pt')

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--trainset', required=True, type=str)
    parser.add_argument('--devset', required=True, type=str)
    parser.add_argument('--testset', required=True, type=str)
    parser.add_argument('--itemset', required=True, type=str)
    parser.add_argument('--outdir', required=True, type=str)
    args = parser.parse_args()

    if not os.path.exists(args.outdir):
        os.makedir(args.outdir, exists_ok=True)

    main(args)


import os
import csv

# Let's create a function that:
#   accepts the following parameters:
#       a base directory string
#       a recursion level to say how deep we can search through the directory structure
#   runs through the base directory and generates an list of directories held within
#   passes back a list once complete

#Let's define a new class to store our directory objects
class directory:
    def __init__(self, directoryPath, accessibility):
        self.directoryPath = directoryPath
        self.accessibility = accessibility

def getDirectories(baseDirectory, recursionLevel):
    """
    This function generates a list of directories.
    It also returns some useful information about each directory.
    """

    # We need a list for the directories
    directories = []

    # We also need to keep in mind how deep down the rabbit hole we are allowed to go
    recursionLevel -= 1

    # For each object, only store it if it's a directory
    for entry in os.scandir(baseDirectory):
        if entry.is_dir():
            # Replace the directory path backslash with a forward slash
            directoryPath = entry.path.replace('\\', '/')
            # If we've found a directory, store it and assume it's accessible for now
            directories.append(directory(directoryPath, 'accessible'))
            # Try to open the directory if we're not at the end of our recursion yet
            if recursionLevel > 0:
                try:
                    directories = directories + getDirectories(directoryPath, recursionLevel)
                except PermissionError as e:
                    # If we can't gain access, store that fact
                    directories[-1].accessible = 'inaccessible'
            else:
                # If we never try accessing, let's store that fact too because it could be important
                directories[-1].accessible = 'untested'

    return directories

# Output a list of directories to a csv for processing
directories = getDirectories('C:/', 2)

with open('C:/data/data.list.directories.csv', 'w', newline= '') as f:
    write = csv.writer(f)
    write.writerow(['directoryPath','accessibility'])
    for i in directories:
        write.writerow([i.directoryPath, i.accessibility])


from time import  sleep
valor_1 = int(input('Primeiro valor: '))
valor_2 = int(input('Segundo valor: '))
opcao = 0
resultado = 0
while opcao != 5:
    print('=-' * 10)
    print('{:^20}'.format('''MENU'''))
    print('=-' * 10)
    print('''[ 1 ] SOMA
[ 2 ] MULTIPLICAR
[ 3 ] MAIOR VALOR
[ 4 ] NOVOS VALORES
[ 5 ] SAIR ''')
    opcao = int(input('Qual sua opção? '))
    if opcao == 1:
        resultado = valor_1 + valor_2
        print('A soma entre {} + {} é {}'.format(valor_1, valor_2, resultado))
    elif opcao == 2:
        resultado = valor_1 * valor_2
        print('O resultado de {} x {} é {}'.format(valor_1, valor_2, resultado))
    elif opcao == 3:
        if valor_1 == valor_2:
            print(' Os dois valores são iguais')

        elif valor_1 > valor_2:
            resultado = valor_1
        else:
            resultado = valor_2
        print('Entre {} e {} o maior valor é {}'.format(valor_1, valor_2, resultado))
    elif opcao == 4:
        print('Informe os numeros novamente: ')
        valor_1 = int(input('Informe um novo valor: '))
        valor_2 = int(input('Informe outro valor: '))
    elif opcao == 5:
        sair = str(input('Tem certeza que deseja sair? [S/N]')).strip().upper()
        if sair == 'S':
            opcao = 5
    else:
        print('Opção inválida. Escolha novamente.')
    print('FINALIZANDO...')
    sleep(1)
    print('=-' * 15)
    print('Fim do programa... Volte sempre!')


import os

from FileServerApp.file_services.file_service_signed import FileServiceSigned

def test_fileservice_single_obj(file_service_signed):
    fs_obj = FileServiceSigned()
    assert fs_obj is file_service_signed

def test_file_service_signed_creation_keys_directory(change_root_dir):
    # Needed to reset default fields in FileServiceSinged class
    FileServiceSigned._FileServiceSigned__instance = None
    FileServiceSigned._FileService__instance = None

    # Act
    new_fs_signed = FileServiceSigned()

    assert os.path.isdir(new_fs_signed.key_folder)


"""Unit tests for Wikipedia Sourcelist Generator."""
from absl import flags
from absl.testing import absltest
from absl.testing import flagsaver
import wikipedia_sourcelist_generator as scraper

FLAGS = flags.FLAGS

class WikipediaSourcelistGeneratorTests(absltest.TestCase):
  def testChunkPageIds(self):
    results = scraper._chunk_page_ids([1, 2, 3, 4, 5, 6, 7], chunk_size=3)
    self.assertSameElements(results,
                              [[1, 2, 3], [4, 5, 6], [7]])

  def testChunkPageIdsEmptyList(self):
    results = scraper._chunk_page_ids([], chunk_size=3)
    self.assertEqual(results, [])

if __name__ == '__main__':
  # Pass flags to pass initial required flags check.
  FLAGS.num_images = 10
  FLAGS.outputdir = 'somedir'
  absltest.main()