class employee:
    def __init__(self, first, last, pay):
        self.first= first
        self.last= last
        self.pay= pay

    def fullname(self):
        return '{} {}'.format(self.first, self.last)

emp1= employee('Corey', 'Schefer', 5000)
emp2= employee('Zafor', 'Saadik', 6000)
print(emp1)
print(emp2)
print(emp1.first)
print(emp2.first)
print(emp1.fullname())
print(emp2.fullname())


from cdpcli.compat import json
import dateutil.parser

class ResponseParserFactory(object):

    def create_parser(self):
        return ResponseParser()

class ResponseParser(object):
    DEFAULT_ENCODING = 'utf-8'

    def parse(self, response, shape):
        if response['status_code'] >= 301:
            return self._parse_error(response)
        elif 'Content-Type' in response['headers'] and \
             not self._is_json_response(response['headers']['Content-Type']):
            return response['body']
        elif shape is None:
            return {}
        else:
            return self._parse_shape(shape, self._decode_body(response))

    def _is_json_response(self, content_type):
        if not content_type:
            return False
        if content_type == 'application/json':
            return True
        if content_type.startswith('application/json;'):
            return True
        return False

    def _decode_body(self, response):
        body = response['body']
        if not body:
            return {}
        return json.loads(body.decode(self.DEFAULT_ENCODING))

    def _parse_error(self, response):
        try:
            body = self._decode_body(response)
        except Exception:
            # In the case that we hit a completely dead endpoint, etc, the
            # response might not be valid JSON, but we still want to return
            # a structured error to the caller.
            message = response['body'].decode(self.DEFAULT_ENCODING).strip()
            body = dict(code='UNKNOWN_ERROR', message=message)
        error = {}
        error['code'] = body.get('code', '')
        if 'message' in body:
            error['message'] = body.get('message', '')
        elif 'error' in body:
            error['message'] = body.get('error', '')
        else:
            error['message'] = ' '.join(body.get('errorMessages', []))
        return {'error': error}

    def _parse_shape(self, shape, value):
        handle_method_name = '_handle_%s' % shape.type_name
        method = getattr(self, handle_method_name, self._handle_default)
        return method(shape, value)

    def _handle_array(self, shape, value):
        parsed = []
        for item in value:
            parsed.append(self._parse_shape(shape.member, item))
        return parsed

    def _handle_object(self, shape, value):
        parsed = {}
        for member_name in shape.members:
            member_shape = shape.members[member_name]
            member_value = value.get(member_shape.name)
            if member_value is not None:
                parsed[member_name] = self._parse_shape(
                    shape.members[member_name], member_value)
        return parsed

    def _handle_map(self, shape, values):
        parsed = {}
        for key, value in values.items():
            actual_key = self._parse_shape(shape.key, key)
            actual_value = self._parse_shape(shape.value, value)
            parsed[actual_key] = actual_value
        return parsed

    # Handles both ISO8601 format and RFC822 format.
    # However, server can only parse ISO8601 format as of now.
    def _handle_datetime(self, shape, value):
        try:
            return dateutil.parser.parse(value)
        except (TypeError, ValueError) as e:
            raise ValueError('Invalid timestamp "%s": %s' % (value, e))

    def _handle_default(self, shape, value):
        return value


# -*- coding: utf-8 -*-

from odoo import models, fields, api, _
from odoo.exceptions import AccessError, UserError, ValidationError
from odoo.tools.translate import html_translate

import logging

_logger = logging.getLogger(__name__)

class PurchaseOrder(models.Model):
    _name = 'purchase.order'
    _inherit = ['purchase.order', 'x.x_company_organization.org_mixin']

    @api.depends('trans_classify_id')
    def _compute_show_construction(self):
        for rec in self:
            rec.show_construction = True if self.trans_classify_id and self.trans_classify_id.code == 'construction' else False

    @api.depends('order_line', 'order_line.product_id')
    def _compute_is_dropshipping(self):
        for record in self:
            record.is_dropshipping = False
            if record.order_line:
                route_id = self.env.ref('stock_dropshipping.route_drop_shipping', raise_if_not_found=False)
                record.is_dropshipping = True if route_id in record.mapped('product_id').mapped('route_ids') else False

    trans_classify_id = fields.Many2one('x.transaction.classification', "Transaction classification")
    type = fields.Selection([
        ('normal', 'Normal purchase'),
        ('tank_lorry', 'Truck delivery'),
    ], string='Purchase type', copy=False, default='normal')
    desired_delivery = fields.Selection([
        ('full', 'Full payment request'),
        ('separated', 'Can be paid in installments'),
    ], string="Desired delivery", copy=False, default='full')
    date_response = fields.Datetime("Response date", copy=False)
    date_issuance = fields.Date("Issuance date", copy=False, default=fields.Date.context_today)
    jurisdiction_id = fields.Many2one('crm.team', "Jurisdiction")
    dest_address_infor = fields.Html("Direct shipping information", copy=False)
    # Displayed only when the transaction classification item of the slip is "Construction"
    show_construction = fields.Boolean("Show Construction", compute='_compute_show_construction')
    construction_name = fields.Char("Construction name")
    construction_site = fields.Char("Construction site")
    construction_period_start = fields.Date('Scheduled construction period', copy=False)
    construction_period_end = fields.Date('Scheduled construction period (end)', copy=False)
    pres_abs_supplies = fields.Selection([
        ('none', 'Nothing'),
        ('having', 'Yes'),
    ], string="Presence/absence of supplies", copy=False, default='none')
    construction_supplies = fields.Char("Supplies")
    construction_payment_term = fields.Char("Payment terms", readonly=True, default=_("Dealine at the end of the month, payment at the end of the following month according to our regulations"))
    construction_cash = fields.Float("Cash")
    construction_bills = fields.Float("Bills")
    pres_abs_current_theory = fields.Selection([
        ('none', 'No'),
        ('explanation', 'Yes'),
    ], string='Presence/absence of the current theory', copy=False, default='none')
    construction_current_date = fields.Date('Date of the current theory', copy=False)
    construction_current_place = fields.Char('Current theory place', copy=False)
    construction_others = fields.Text('others', copy=False)
    notes_construction_contract = fields.Html("Notes on construction contract", related="company_id.notes_construction_contract")
    estimated_subcontracting_work = fields.Html("Estimated price and estimated period for subcontracting work", related="company_id.estimated_subcontracting_work")

    # Rename fields standard
    name = fields.Char(string="Slip No.")
    origin = fields.Char(string="Reference source")
    partner_id = fields.Many2one('res.partner', string="Supplier")
    user_id = fields.Many2one('res.users', string="Purchasing person")
    create_date = fields.Datetime(string="Create date", default=fields.Datetime.now, copy=False)
    create_uid = fields.Many2one('res.users', string='Slip creator',)
    picking_type_id = fields.Many2one('stock.picking.type', string='Delivery destination',)
    dest_address_id = fields.Many2one('res.partner', string='Direct delivery',)
    fiscal_position_id = fields.Many2one('account.fiscal.position', string='Accounting position',)
    date_planned = fields.Datetime(string="Requested delivery date", copy=False)
    is_dropshipping = fields.Boolean('Is dropship', compute='_compute_is_dropshipping',)

    # TODO: Hide print with state
    @api.model
    def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
        res = super(PurchaseOrder, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar,
                                                         submenu=submenu)
        _logger.info('111111111111111 fields_view_get toolbar print: %s', res.get('toolbar', {}).get('print', []))
        return res

    @api.onchange('partner_id')
    def _onchange_partner_id_sgvn(self):
        self.trans_classify_id = self.partner_id.x_transaction_classification and self.partner_id.x_transaction_classification[0].id
        x_organization_id = self.x_organization_id and self.x_organization_id.id
        if self.partner_id and not (self.partner_id.x_organization_id and self.partner_id.x_organization_id.id == x_organization_id):
            return {
                'warning': {
                    'title': _("Alert: Insufficient supplier transaction information"),
                    'message': _("""The purchasing information for [Login User's Organization Name] does not exist for the selected supplier.\nPlease complete the purchase information input / approval of the relevant supplier from the supplier application screen.""")
                },
            }

    @api.onchange('x_organization_id')
    def _onchange_x_organization_id(self):
        x_organization_id = self.x_organization_id and self.x_organization_id.id
        if self.partner_id and not (self.partner_id.x_organization_id and self.partner_id.x_organization_id.id == x_organization_id):
            return {
                'warning': {
                    'title': _("Alert: Insufficient supplier transaction information"),
                    'message': _("""The purchasing information for [Login User's Organization Name] does not exist for the selected supplier.\nPlease complete the purchase information input / approval of the relevant supplier from the supplier application screen.""")
                },
            }

    @api.onchange('construction_cash')
    def _onchange_construction_cash(self):
        if self.construction_cash and self.clamp(self.construction_cash):
            self.construction_bills = 100 - self.construction_cash

    @api.onchange('construction_bills')
    def _onchange_construction_bills(self):
        if self.construction_bills and self.clamp(self.construction_bills):
            self.construction_cash = 100 - self.construction_bills

    @api.constrains("construction_cash", "construction_bills")
    def _check_sum_construction_payment(self):
        for record in self:
            cash = record.construction_cash
            bills = record.construction_bills
            if cash or bills:
                if sum([cash, bills]) != 100 or not(self.clamp(cash) or self.clamp(cash)):
                    raise ValidationError(_('Total payment must be 100%%: Cash %s%% - Bills %s%%' % (cash, bills)))

    # Update file attachment for mail template with trans_classify_id in <![CDATA[]]>
    def action_rfq_send(self):
        res = super(PurchaseOrder, self).action_rfq_send()
        if self.env.context.get('send_rfq', False):
            if self.show_construction:
                res['context'].update({
                    'default_template_id': self.env.ref("x_purchase_quotation.email_template_edi_purchase_construction").id
                })
            else:
                res['context'].update({
                    'default_template_id': self.env.ref("x_purchase_quotation.email_template_edi_purchase").id
                })
        res['context'].update({
            'partner_email_field': 'email_quote_request',
        })
        return res

    def print_quotation(self):
        res = super(PurchaseOrder, self).print_quotation()
        if self.show_construction:
            return self.env.ref('x_purchase_quotation.action_report_estimate_request').report_action(self)
        else:
            return self.env.ref('x_purchase_quotation.action_report_purchasequotation').report_action(self)
        return res

    @api.model
    def clamp(self, number):
        if number:
            if number < 0:
                return False
            elif number > 100:
                return False
            else:
                return number

class PurchaseOrderLine(models.Model):
    _inherit = 'purchase.order.line'

    location_dest_id = fields.Many2one('stock.location', "Delivery destination", domain=[("usage", "in", ["internal", "transit"])])
    # Rename fields standard
    product_uom_id = fields.Many2one('uom.uom', string='Unit',)
    taxes_id = fields.Many2many('account.tax', string='Tax',)

    @api.model
    def default_get(self, fields):
        rec = super(PurchaseOrderLine, self).default_get(fields)
        params = self._context.get('params')
        if params and params.get('id'):
            order_id = self.env['purchase.order'].browse(params.get('id'))
            rec['location_dest_id'] = order_id.x_organization_id.x_purchase_stock_location_id.id if order_id.x_organization_id and order_id.x_organization_id.x_purchase_stock_location_id else False
        else:
            x_organization_id = self.env.user.x_organization_id
            rec['location_dest_id'] = x_organization_id.x_purchase_stock_location_id.id if x_organization_id and x_organization_id.x_purchase_stock_location_id else False
        return rec

    # @api.onchange('order_id', 'order_id.x_organization_id')
    # def _onchange_partner_id_sgvn(self):
    #     self.location_dest_id = self.order_id.x_organization_id.x_purchase_stock_location_id.id if self.order_id.x_organization_id.x_purchase_stock_location_id else False


import torch
import torch.nn as nn
import torch.nn.functional as F
import os
import sys
import gc
sys.path.append("..")
from utils import data_loader,utils
import argparse
import random
import pickle as pkl
from tqdm import tqdm
import datetime
from time import time
from algo import GraphHINGE_FFT,GraphHINGE_Conv,GraphHINGE_Cross,GraphHINGE_CrossConv,GraphHINGE_ALL, GraphHINGE_ConvALL, GraphHINGE_CNN
from tensorboardX import SummaryWriter
import numpy as np
from sklearn.metrics import average_precision_score, roc_auc_score

class dummy_context_mgr():
    def __enter__(self):
        return None
    def __exit__(self, exc_type, exc_value, traceback):
        return False

def train(model, device, optimizer, train_loader, eval_loader, save_dir, epochs, writer, model_name, patience):
    best_val_acc = 0.0
    cnt = 0
    inference = eval_loader is None
    for epoch in range(epochs):
        #train
        model.train()
        train_loss = []
        pbar = tqdm(train_loader)
        train_acc = []
        for i, data in enumerate(pbar):
            UI, IU, UIUI, IUIU, UIAI1, IAIU1, UIAI2, IAIU2, UIAI3, IAIU3, labels = data
            optimizer.zero_grad()
            pred = model(UI.to(device), IU.to(device),\
            UIUI.to(device), IUIU.to(device), \
            UIAI1.to(device), IAIU1.to(device), \
            UIAI2.to(device), IAIU2.to(device), \
            UIAI3.to(device), IAIU3.to(device))

            loss = criterion(pred, labels.to(device))
            acc = utils.evaluate_acc(pred.detach().cpu().numpy(), labels.numpy())
            train_acc.append(acc)
            loss.backward()
            optimizer.step()

            train_loss.append(loss.item())
            pbar.set_description('Epoch {:d} | Loss {:.4f}'.format(epoch + 1, loss))
            train_iter= epoch * len(train_loader) + i
            if train_iter%10 ==0:
                writer.add_scalar('Loss/train', loss.item(), train_iter)

            '''
            if i%500==0:
                print('Epoch {:d} | Batch {:d} | Train Loss {:.4f} | '.format(epoch + 1, i+1,loss))

            del UI, IU, UIUI, IUIU, UIAI1, IAIU1, UIAI2, IAIU2, UIAI3, IAIU3, labels, pred
            gc.collect()
            with torch.cuda.device(device):
                torch.cuda.empty_cache()
            '''
        train_acc = np.mean(train_acc)
        writer.add_scalar('Acc/Train', train_acc, train_iter)
        #eval
        if inference:
            continue
        model.eval()
        eval_loss = []
        eval_acc = []
        eval_auc = []
        eval_logloss = []
        eval_f1 = []
        with torch.no_grad():
            pbar = tqdm(eval_loader)
            for i, data in enumerate(pbar):
                UI, IU, UIUI, IUIU, UIAI1, IAIU1, UIAI2, IAIU2, UIAI3, IAIU3, labels = data

                pred = model(UI.to(device), IU.to(device),\
                UIUI.to(device), IUIU.to(device), \
                UIAI1.to(device), IAIU1.to(device), \
                UIAI2.to(device), IAIU2.to(device), \
                UIAI3.to(device), IAIU3.to(device))

                loss = criterion(pred, labels.to(device))
                acc = utils.evaluate_acc(pred.detach().cpu().numpy(), labels.numpy())
                eval_loss.append(loss.item())
                eval_acc.append(acc)
                pbar.set_description('Epoch {:d} | Loss {:.4f}'.format(epoch + 1, loss))

                '''
                del UI,IU, UIUI, IUIU, UIAI1, IAIU1, UIAI2, IAIU2, UIAI3, IAIU3, labels, pred
                gc.collect()
                with torch.cuda.device(device):
                    torch.cuda.empty_cache()
                '''

            eval_loss = np.mean(eval_loss)
            eval_acc = np.mean(eval_acc)

            print('Epoch {:d} | Eval Acc {:.4f} | '.format(epoch + 1, eval_acc))
            writer.add_scalar('Loss/Eval', eval_loss, train_iter)
            writer.add_scalar('Acc/Eval', eval_acc, train_iter)
            if eval_acc > best_val_acc:
                print(f"Prev best Acc {best_val_acc:.4f}, new best {eval_acc:.4f}. Saving best weights...")
                best_val_acc = eval_acc
                best_epoch = epoch
                torch.save(model.state_dict(), os.path.join(save_dir,model_name))
                cnt = 0
            else:
                cnt = cnt + 1
                if cnt >= patience:
                    print("Early stopping")
                    print("best epoch:{}".format(best_epoch))
                    break
    if inference:
        torch.save(model.state_dict(), os.path.join(save_dir,model_name))

def test(model, device, test_loader, writer, inference_output = None):
    test_loss = []
    test_logloss = []
    pred_list = None
    label_list = None
    model.eval()
    with torch.no_grad():
        for i, data in enumerate(tqdm(test_loader, desc = 'Infer')):
            UI, IU, UIUI, IUIU, UIAI1, IAIU1, UIAI2, IAIU2, UIAI3, IAIU3, labels = data
            pred = model(UI.to(device), IU.to(device),\
            UIUI.to(device), IUIU.to(device), \
            UIAI1.to(device), IAIU1.to(device), \
            UIAI2.to(device), IAIU2.to(device), \
            UIAI3.to(device), IAIU3.to(device))

            loss = criterion(pred, labels.to(device))

            pred = pred.detach().cpu().numpy()
            labels = labels.numpy()
            users = UI.detach().cpu().numpy()[:, 0, 0]
            items = IU.detach().cpu().numpy()[:, 0, 0]
            if pred_list is None:
                pred_list = pred
                label_list = labels
            else:
                pred_list = np.vstack([pred_list, pred])
                label_list = np.vstack([label_list, labels])
            if inference_output is not None:
                for user, item, logit, label in zip(users, items, pred, labels):
                    print(user, item, logit[0].item(), sep = '\t', file = inference_output)
            logloss = utils.evaluate_logloss(pred, labels)
            test_loss.append(loss.item())
            test_logloss.append(logloss)
            writer.add_scalar('Loss/Test', loss.item(), i)
            writer.add_scalar('Logloss/Test', logloss, i)
            '''

            del UI, IU, UIUI, IUIU, UIAI1, IAIU1, UIAI2, IAIU2, UIAI3, IAIU3, labels, pred
            gc.collect()

            with torch.cuda.device(device):
                torch.cuda.empty_cache()
            '''
        test_auc = utils.evaluate_auc(pred_list, label_list)
        test_acc = utils.evaluate_acc(pred_list, label_list)
        test_aupr = average_precision_score(label_list, pred_list)

        test_f1 = utils.evaluate_f1_score(pred_list, label_list)

        test_loss = np.mean(test_loss)
        test_logloss = np.mean(test_logloss)
        writer.add_scalar('AUC/Test', test_auc, i)
        writer.add_scalar('Acc/Test', test_acc, i)
        writer.add_scalar('F1/Test', test_f1, i)
        print('Test Loss {:.4f} | Test AUC {:.4f} | Test ACC {:.4f} | Test F1 {:.4f} | AUPR {:.4f} | Test Logloss {:.4f} |'.format(test_loss, test_auc, test_acc, test_f1, test_aupr, test_logloss))

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Parameters.')
    parser.add_argument('-cuda', type=str, default='cpu' ,help='Cuda number.')
    parser.add_argument('-hidden', type=int, default=128, help='Hidden Units.')
    parser.add_argument('-heads', type=int, default=3, help='Attention heads.')
    parser.add_argument('-lr', type=float, default=0.001, help='Learning rate.')
    parser.add_argument('-wd', type=float, default=0.0009, help='Weight decay.')
    parser.add_argument('-epochs', type=int, default=500,help='Maximum Epoch.')

    parser.add_argument('-model', type=str, default='GraphHINGE_FFT',help='Model.')
    parser.add_argument('-save_dir', type=str, default='../out',help='Trained models to be saved.')
    parser.add_argument('-pretrained', type=str, default='pretrained.pth',help='Load a model from breakpoint.')

    parser.add_argument('-d', type=str,help='Dataset.')
    parser.add_argument('-p', type=str,help='Dataset path.')
    parser.add_argument('-o', type=str,default='../data/data_out',help='Output path.')
    parser.add_argument('-b', type=int, default=128, help='Batch size.')
    parser.add_argument('-s', type=int,default=0, help='Sample path to be saved.')
    parser.add_argument('-n', type=int, default=16,help='Num of walks per node.')
    parser.add_argument('-w', type=int, default=1,help='Scale of walk length.')
    parser.add_argument('-temp1', type=float, default=0.2, help='Temperature factor for node att.')
    parser.add_argument('-temp2', type=float, default=0.2, help='Temperature factor for path att.')
    parser.add_argument('-ratio', type=float, default=1, help='Sample ratio.')
    parser.add_argument('-train', action= "store_true", default= False,help='If false, model will be loaded from the latest saved one.')
    parser.add_argument('-usersid', type=int, action="append", default=None, help='Specify users id to inference. Default all users.')
    parser.add_argument('-itemsid', type=int, action="append", default=None, help='Specify items id to inference. Default all items.')
    parser.add_argument('-inference', action= "store_true", default=False,help='Inference stage. (Train All data and inference new links between users and items)')
    parser.add_argument('-model_state_file', type=str,default = None, help='Load model state file to infer')
    parser.add_argument('-use_tensorboard', action= "store_true",default = False)
    parser.add_argument('-kfold', action= "store_true",default = False)
    args = parser.parse_args()
    device = torch.device(args.cuda)

    fold_idx = -1 if args.kfold else None
    args.o += "_fold" if args.kfold else ""
    args.o += "_inference" if args.inference else ""

    for user_metas, item_metas, train_loader, eval_loader, test_loader, user_num, item_num, attr1_num, attr2_num, attr3_num in \
        data_loader.Dataloader(args.p, args.d, args.o, args.s, args.n, args.w, args.b, args.inference,ratio=args.ratio, usersid = args.usersid, itemsid = args.itemsid, kfold = args.kfold).load_data():
        print('Data Loaded!')
        if args.kfold:
            fold_idx += 1
        if args.model == 'GraphHINGE_FFT':
            model = GraphHINGE_FFT.GraphHINGE(
                user_num, item_num, attr1_num, attr2_num, attr3_num, args.hidden, args.hidden, args.hidden, args.heads, args.temp1, args.temp2, output_attentions = False
                ).to(device)
        elif args.model == 'GraphHINGE_Conv':
            model = GraphHINGE_Conv.GraphHINGE(
                user_num, item_num, attr1_num, attr2_num, attr3_num, args.hidden, args.hidden, args.hidden, args.heads, args.temp1, args.temp2
                ).to(device)
        elif args.model == 'GraphHINGE_Cross':
            model = GraphHINGE_Cross.GraphHINGE(
                user_num, item_num, attr1_num, attr2_num, attr3_num, args.hidden, args.hidden, args.hidden, args.heads, args.temp1, args.temp2
                ).to(device)
        elif args.model == 'GraphHINGE_CrossConv':
            model = GraphHINGE_CrossConv.GraphHINGE(
                user_num, item_num, attr1_num, attr2_num, attr3_num, args.hidden, args.hidden, args.hidden, args.heads, args.temp1, args.temp2
                ).to(device)
        elif args.model == 'GraphHINGE_ALL':
            model = GraphHINGE_ALL.GraphHINGE(
                user_num, item_num, attr1_num, attr2_num, attr3_num, args.hidden, args.hidden, args.hidden, args.heads, args.temp1, args.temp2
                ).to(device)
        elif args.model == 'GraphHINGE_ConvALL':
            model = GraphHINGE_ConvALL.GraphHINGE(
                user_num, item_num, attr1_num, attr2_num, attr3_num, args.hidden, args.hidden, args.hidden, args.heads, args.temp1, args.temp2
                ).to(device)
        elif args.model == 'GraphHINGE_CNN':
            model = GraphHINGE_CNN.GraphHINGE_CNN(
                user_num, item_num, attr1_num, attr2_num, attr3_num, args.hidden, args.hidden, args.hidden, args.heads, args.temp1, args.temp2
                ).to(device)
        else:
            raise NotImplementedError
        print('Model Created!')

        if (os.path.exists(os.path.join(args.save_dir, args.pretrained))):
            model.load_state_dict(torch.load(os.path.join(args.save_dir, args.pretrained)))
            print("Model loaded!")

        criterion = nn.BCELoss()
        optimizer = torch.optim.Adam(model.parameters(), lr=args.lr, weight_decay=args.wd)
        if args.model_state_file is None:
            model_name = "NotFFT" + '_'.join([args.model,
                                        args.d, ("inference" if args.inference else "train"),
                                        f"Fold{fold_idx}" if args.kfold else "Nofold",
                                        "lr_"+str(args.lr), "bs_"+str(args.b), "wd_"+str(args.wd)]) \
                                    + '.pth'
        else:
            model_name = args.model_state_file

        save_dir = args.save_dir
        startDateTime = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        log_dir = save_dir+'/Logs/'+ startDateTime + model_name
        print("Args ", args)
        if not os.path.exists(log_dir):
            os.mkdir(log_dir)
        with  SummaryWriter(log_dir = log_dir) as writer:
            if args.train:
                train(model, device, optimizer, train_loader, eval_loader, args.save_dir, args.epochs, writer, model_name,patience=50)
                pass
            model.load_state_dict(torch.load(os.path.join(args.save_dir, model_name)))
            if args.inference:
                if not os.path.exists(os.path.join(save_dir, "inference")):
                    os.mkdir(os.path.join(save_dir, "inference"))
                with open(os.path.join(save_dir, "inference", f"{startDateTime}.csv"), 'w') as infer_out:
                    test(model, device, test_loader, writer, infer_out)
            else:
                test(model, device, test_loader, writer)


from _external import *
from SCons.Script import *
from glew import *
import os

def unique(list):
	return dict.fromkeys(list).keys()

def subdirs(files):
	dirs = unique(map(os.path.dirname, files))
	dirs.sort()
	return dirs

def locateQt3Command(env, command, bindir):
	#print 'locateQt3Command:', command
	suffixes = [
		'-qt3',
		'3',
		'',
	]
	progs = [command+s for s in suffixes]
	for prog in progs:
		path = env.WhereIs(prog, path=bindir)
		if path:
			return path

	msg = 'Qt3 command "' + command + '" not found. Tried: ' + str(progs) + '.'
	#raise Exception(msg)
	#print 'Warning: ', msg
	return command

class Qt3Checker(LibWithHeaderChecker):
	'''
	Qt3 checker
	'''
	allUiFiles = []

	def __init__( self,
				  modules = [
					  'qt-mt',
					  'qui',
				],
				  uiFiles = [],
				  defines = ['QT_NO_KEYWORDS','QT_THREAD_SUPPORT'],
				  useLocalIncludes = True ):
		self.name  = 'qt3'
		self.libs = modules[:]
		self.uiFiles = self.getAbsoluteCwd(uiFiles)
		self.defines = defines[:]
		self.dependencies = [glew]
		self.useLocalIncludes = useLocalIncludes

	def setModules(self, modules):
		self.libs = modules[:]

	def declareUiFiles(self, uiFiles):
		self.uiFiles.extend( self.getAbsoluteCwd(uiFiles) )

	def initEnv(self, project, env):
		# use qt scons tool
		env.Tool('qt')

	def initOptions(self, project, opts):
		LibWithHeaderChecker.initOptions(self, project, opts)
		opts.Add( 'bindir_'+self.name,   'Base directory for '+self.name, '${_join_if_basedir_not_empty( dir_'+self.name+ ', "bin" )}' )
		return True

	def configure(self, project, env):
		env.EnableQtEmmitters()

		bindir = '$bindir_'+self.name
		moc = locateQt3Command(env, 'moc', bindir)
		uic = locateQt3Command(env, 'uic', bindir)
		rcc = locateQt3Command(env, 'rcc', bindir)
		lupdate = locateQt3Command(env, 'lupdate', bindir)
		lrelease = locateQt3Command(env, 'lrelease', bindir)
		#print 'moc', moc
		env.SetDefault(
				QT_MOC = moc,
				QT_UIC = uic,
				QT_RCC = rcc,
				QT_LUPDATE = lupdate,
				QT_LRELEASE = lrelease,
			)
		# depends the developper syntax used
		# maybe we need to expose these values as parameters (in initOptions)
		env.Replace(
				QT_UICDECLPREFIX = '', # this is the standard value for qt3
				QT_UICDECLSUFFIX = '.h',
			)

		return BaseLibChecker.configure(self, project, env)

	def check(self, project, conf):
		conf.env.AppendUnique( CPPDEFINES = self.defines )
		result = self.CheckLibWithHeader( conf, self.getLibs(conf.env), header=['qapplication.h'], language='c++' )
		return result

	def postconfigure(self, project, env, level):
		'''
		Add things for ui files after all libs check.
		'''
		if len(self.uiFiles):
			for ui in self.uiFiles:
				# do not redeclare a ui file
				if ui not in Qt3Checker.allUiFiles:
					env.Uic( ui )
					Qt3Checker.allUiFiles.append( ui )
			if self.useLocalIncludes:
				env.AppendUnique( CPPPATH=subdirs(self.uiFiles) )
		return True

qt3 = Qt3Checker


import scrapy
from pbl.items import PblSpider
from pbl.items import ShopCard
import json

class SpiderasortiSpider(scrapy.Spider):
    name = 'spiderAsorti'
    allowed_domains = ['www.assorti.lt']
    start_urls = ['https://www.assorti.lt/katalogas/maistas/']
    item = []
    list = [{
        'sid': 1,
        'name': 'Assorti',
        'domain': 'https://www.assorti.lt',
        'imageurl': 'https://www.assorti.lt/images/logo_white.png',
        'product': item
        }]

    def __init__(self):
        self.declare_xpath()

    def declare_xpath(self):
        self.getAllItemsXpath = '//*[@id="products_wrapper"]/div[2]/div/a/@href'
        self.TitleXpath  = '//*[@id="products_detailed"]/div[1]/div/div/div[2]/h1/text()'
        self.ImageXpath = '//*[@id="products_photos"]/div[1]/img/@src'
        self.PriceXpath = '//*[@id="products_add2cart"]/form/div/div[1]/div/div[1]/span/span[1]/text()'

    def parse(self, response):

        for href in response.xpath(self.getAllItemsXpath):
            url = response.urljoin(href.extract())
            yield scrapy.Request(url,callback=self.parse_item)

        next_page = response.xpath('//*[@id="products_wrapper"]/div[3]/div[2]/ul/li/a[contains(@class, "pagination_link")]/@href').extract()
        if next_page[1] is not '#':
            print('-' * 70)
            print(next_page[1])
            print('-' * 70)
            url = response.urljoin(next_page[1])
            yield scrapy.Request(url, callback=self.parse)

    def parse_item(self, response):

            shop = ShopCard()

            Title = response.xpath(self.TitleXpath).extract_first()
            Link = response.url
            Image = response.xpath(self.ImageXpath).extract_first()
            Price = response.xpath(self.PriceXpath).extract_first()
            Price = Price.replace(',', '.')
            Price = float(Price.split(' ')[0])

            shop['item'] = {
                'title': Title,
                'link': Link,
                'image': Image,
                'price': Price
            }

            self.item.append(shop['item'])

    def closed(self, reason):
        with open("spiderAsorti.json", "w") as final:
            json.dump(self.list, final, indent=2, ensure_ascii=False)


# Load packages
import numpy as np
import pandas as pd
import plotly.express as px
import matplotlib.pyplot as plt
from sklearn.ensemble import IsolationForest
from sklearn.model_selection import train_test_split

# Load data from the csv file
df = pd.read_csv("housing.csv", index_col=False)
df.head()

CONTAMINATION=.2    # The expected outliers to real data ratio
BOOTSTRAP = False   # True if you want to use the bootstrap method;

# Exctract the data without column names from the dataframe
data = df.values

# We will start by splitting the data into X/y train/test data
X, y = data[:, :-1], data[:, -1]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)

# Next, we will set up the Isolation Forest classifier that will detect the outliers
i_forest = IsolationForest(contamination=CONTAMINATION, bootstrap=BOOTSTRAP)
is_inlier = i_forest.fit_predict(X_train)    # +1 if inlier, -1 if outlier

# Finally, we will select the rows without outliers
mask = is_inlier != -1
# and remove these from the train data
X_train, y_train = X_train[mask, :], y_train[mask]

df_wo_outliers=pd.DataFrame(X_train, columns=df.columns[:-1])
df_boxplot = pd.DataFrame(data={'With outliers':df['RM'], 'Without outliers':df_wo_outliers['RM']})
fig = px.box(df_boxplot)
fig.show()


import pydantic
from box import ConfigBox
import os
from pathlib import Path

from mlengine.common.logger import logger
from mlengine.common.utils import create_directories
from mlengine.common.exceptions import MissingCriticalFileException
from mlengine.data_read.read import read_csv_file

class StudentDataTypesValidator(pydantic.BaseModel):
    gender: pydantic.StrictStr
    race_ethnicity: pydantic.StrictStr
    parental_level_of_education: pydantic.StrictStr
    lunch: pydantic.StrictStr
    test_preparation_course: pydantic.StrictStr
    math_score: pydantic.StrictInt
    reading_score: pydantic.StrictInt
    writing_score: pydantic.StrictInt

class StudentTransformedDataTypesValidator(pydantic.BaseModel):
    gender: pydantic.StrictStr
    race_ethnicity: pydantic.StrictStr
    parental_level_of_education: pydantic.StrictStr
    lunch: pydantic.StrictStr
    test_preparation_course: pydantic.StrictStr
    math_score: pydantic.StrictInt
    reading_score: pydantic.StrictInt
    writing_score: pydantic.StrictInt
    total_score: pydantic.StrictInt
    average: pydantic.StrictFloat

class StudentDataValidator:
    def __init__(self, config: ConfigBox):
        self.config: ConfigBox = config
        self.data_file: Path = self.config.req_files[0]

    def validate_data(self):
        try:
            df = read_csv_file(self.data_file)
            data_list = [StudentDataTypesValidator(**row) for _, row in df.iterrows()]
            logger.info(f'Successful validation of data file {self.data_file} via Pydantic strict types')
        except Exception as e:
            raise e

class StudentTransformedDataValidator:
    def __init__(self, config: ConfigBox):
        self.config: ConfigBox = config
        self.data_file: Path = self.config.req_files[0]

    def validate_data(self):
        try:
            df = read_csv_file(self.data_file)
            data_list = [StudentDataTypesValidator(**row) for _, row in df.iterrows()]
            logger.info(f'Successful validation of data file {self.data_file} via Pydantic strict types')
        except Exception as e:
            raise e

class FileValidator:
    def __init__(self, config: ConfigBox):
        self.config: ConfigBox = config
        self._create_dirs()

    def _create_dirs(self):
        create_directories([self.config.root_dir])
        if hasattr(self.config, 'models_dir'):
            create_directories([self.config.models_dir])

    def validate_all_files_exist(self):
        try:
            statuses = []
            messages = []

            for file in self.config.req_files:
                validation_status = os.path.isfile(file)
                statuses.append(validation_status)

                msg = f"Validation status: {validation_status} for file: {file}"
                messages.append(msg)

                logger.info(msg)

            status = all(statuses)

            with open(os.path.join(self.config.root_dir, self.config.status_file), 'w') as f:
                for msg in messages:
                    f.write(msg + "\n")
                f.write(f"Overall status: {status}")

            if not status:
                raise MissingCriticalFileException('VLD_EX_001', 'Validation failed for critical file(s). Check the logged status file for more information.')

        except Exception as e:
            raise e


from cs50 import get_int
i, r, sum1, sum2, n, m, t = 0, 0, 0, 0, 1, 1, 1
n = get_int("Card Number: ")
m = n
r = m % 10
# Luhn’s Algorithm and counting number of digits
while (m != 0):
    r = m % 10
    m = int(m / 10)
    if (i % 2 == 0):
        sum1 += r
    else:
        sum2 += int(((2 * r) % 10 + (2 * r) / 10))
    i += 1

if (((sum1 + sum2) % 10) == 0):
    # finding the first two digits (twod)
    # checking length as well the starting two digits
    for j in range(1, i):
        t *= 10
    twod = int(n / (t / 10))

    if (i == 15):
        if (twod == 34 or twod == 37):
            print("AMEX")
        else:
            print("INVALID")
    elif (i == 16):
        if (51 <= twod and twod <= 55):
            print("MASTERCARD")
        elif (40 <= twod and twod <= 49):
            print("VISA")
        else:
            print("INVALID")
    elif (i == 13):
        if (40 <= twod and twod <= 49):
            print("VISA")
        else:
            print("INVALID")
    else:
        print("INVALID")

else:
    print("INVALID")


from hako.bricks.boxbase import BoxBase
from hako.codegen import register_constants

class Dict(BoxBase):
    @classmethod
    def __specialize__(cls, arg):
        if arg is None:
            return VariadicDict, arg
        elif arg.__class__ in {tuple, list}:
            arg = tuple(arg)
            return MultiItemsDict, arg
        else:
            return SingleItemDict, arg

    @classmethod
    def __guess__(cls, v):
        return Dict[list(v)]

    @classmethod
    def __pick_element__(cls, v):
        return next(iter(v.values()))

register_constants(
    dict_values=dict.values,
    dict_keys=dict.keys,
)

class VariadicDict(Dict):
    ...

GET_INDICES = "dict_keys({VAL})"
VariadicDict.Primitives.ISNOTA("({VAL}.__class__ is not dict)")
VariadicDict.Primitives.ISNOTA2(
    "({VAL}.__class__ is not dict or not dict_keys({VAL}) >= {PROOF})"
)
VariadicDict.Primitives.ISNOTA2_PROOF(GET_INDICES)
VariadicDict.Primitives.ITER("dict_values({VAL})")
VariadicDict.Primitives.ITER2("map({VAL}.__getitem__, {PROOF})")
VariadicDict.Primitives.ITER2_PROOF(GET_INDICES)
VariadicDict.Primitives.NEW_FROM_ITER2("dict(zip({PROOF}, {VAL}))")
VariadicDict.Primitives.NEW_FROM_ITER2_PROOF(GET_INDICES)
VariadicDict.Primitives.GET_INDICES(GET_INDICES)
VariadicDict.Primitives.GET_DUMMY("{{}}")
VariadicDict.Primitives.PICK("next(iter({VAL}.values()))")
VariadicDict.Primitives.GET_LENGTH("len({VAL})")

VariadicDict.Heuristics.SHAPE_IMPLIES_LENGTH(True)

class SingleItemDict(Dict):
    @classmethod
    def __prepare_constants__(cls, mdata):
        return dict(MDATA=mdata, MDATA_TUPLE=(mdata,))

SingleItemDict.Primitives.ISNOTA(
    "({VAL}.__class__ is not dict or {MDATA} not in {VAL})"
)
SingleItemDict.Primitives.ITER("({VAL}[{MDATA}],)")
SingleItemDict.Primitives.NEW("{{{MDATA}: {VAL}}}")
SingleItemDict.Primitives.NEW_FROM_ITER("dict(zip({MDATA_TUPLE}, {VAL}))")
SingleItemDict.Primitives.GET_INDICES("{MDATA_TUPLE}")
SingleItemDict.Primitives.GET_DUMMY("{{{MDATA}: ...}}")
SingleItemDict.Primitives.PICK("{VAL}[{MDATA}]")
SingleItemDict.Primitives.GET_LENGTH("1")

SingleItemDict.Heuristics.SHAPE_IMPLIES_LENGTH(True)

class MultiItemsDict(Dict):
    @classmethod
    def __prepare_constants__(cls, mdata):
        return dict(MDATA=mdata, MDATA_SET=frozenset(mdata), MDATA_LENGTH=len(mdata))

MultiItemsDict.Primitives.ISNOTA(
    "({VAL}.__class__ is not dict or not dict_keys({VAL}) >= {MDATA_SET})"
)
MultiItemsDict.Primitives.ITER("map({VAL}.__getitem__, {MDATA})")
MultiItemsDict.Primitives.NEW_FROM_ITER("dict(zip({MDATA}, {VAL}))")
MultiItemsDict.Primitives.GET_INDICES("{MDATA}")
MultiItemsDict.Primitives.GET_DUMMY("{{I: ... for I in {MDATA}}}")
MultiItemsDict.Primitives.PICK("{VAL}[{MDATA}[0]]")
MultiItemsDict.Primitives.GET_LENGTH("{MDATA_LENGTH}")

MultiItemsDict.Heuristics.SHAPE_IMPLIES_LENGTH(True)


from django.db import models
from django.contrib import admin
try:
    import json
except ImportError:
    import simplejson as json

class Card(models.Model):
    card_id = models.CharField(max_length=16)

    def __unicode__(self):
        return self.card_id

    @classmethod
    def load_json(cls, json_data):
        json_obj = json.loads(json_data)
        card_id = json_obj['card_id']
        cards = Card.objects.filter(card_id=card_id)
        if cards:
            card = cards[0]
        else:
            card = Card()

        for key, value in json_obj.items():
            setattr(card, key, value)

        return card

admin.site.register(Card)


import gym
import sys
import torch
import numpy as np
from PIL import Image

class DeepMindControl:

    def __init__(self, name, seed, size=(64, 64), camera=None):

        domain, task = name.split('-', 1)
        if domain == 'cup':  # Only domain with multiple words.
          domain = 'ball_in_cup'
        if isinstance(domain, str):
          from dm_control import suite
          self._env = suite.load(domain, task, task_kwargs={'random':seed})
        else:
          assert task is None
          self._env = domain()
        self._size = size
        if camera is None:
          camera = dict(quadruped=2).get(domain, 0)
        self._camera = camera

    @property
    def observation_space(self):
        spaces = {}
        for key, value in self._env.observation_spec().items():
          spaces[key] = gym.spaces.Box(
              -np.inf, np.inf, value.shape, dtype=np.float32)
        spaces['image'] = gym.spaces.Box(
            0, 255, (3,) + self._size , dtype=np.uint8)
        return gym.spaces.Dict(spaces)

    @property
    def action_space(self):
        spec = self._env.action_spec()
        return gym.spaces.Box(spec.minimum, spec.maximum, dtype=np.float32)

    def step(self, action):
        time_step = self._env.step(action)
        obs = dict(time_step.observation)
        obs['image'] = self.render().transpose(2, 0, 1).copy()
        reward = time_step.reward or 0
        done = time_step.last()
        info = {'discount': np.array(time_step.discount, np.float32)}
        return obs, reward, done, info

    def reset(self):
        time_step = self._env.reset()
        obs = dict(time_step.observation)
        obs['image'] = self.render().transpose(2, 0, 1).copy()
        return obs

    def render(self, *args, **kwargs):
        if kwargs.get('mode', 'rgb_array') != 'rgb_array':
          raise ValueError("Only render mode 'rgb_array' is supported.")
        return self._env.physics.render(*self._size, camera_id=self._camera)

class TimeLimit:

    def __init__(self, env, duration):
        self._env = env
        self._duration = duration
        self._step = None

    def __getattr__(self, name):
        return getattr(self._env, name)

    def step(self, action):
        assert self._step is not None, 'Must reset environment.'
        obs, reward, done, info = self._env.step(action)
        self._step += 1
        if self._step >= self._duration:
          done = True
          if 'discount' not in info:
            info['discount'] = np.array(1.0).astype(np.float32)
          self._step = None
        return obs, reward, done, info

    def reset(self):
        self._step = 0
        return self._env.reset()

class ActionRepeat:

    def __init__(self, env, amount):
        self._env = env
        self._amount = amount

    def __getattr__(self, name):
        return getattr(self._env, name)

    def step(self, action):
        done = False
        total_reward = 0
        current_step = 0
        while current_step < self._amount and not done:
          obs, reward, done, info = self._env.step(action)
          total_reward += reward
          current_step += 1
        return obs, total_reward, done, info

class NormalizeActions:

    def __init__(self, env):
        self._env = env
        self._mask = np.logical_and(
            np.isfinite(env.action_space.low),
            np.isfinite(env.action_space.high))
        self._low = np.where(self._mask, env.action_space.low, -1)
        self._high = np.where(self._mask, env.action_space.high, 1)

    def __getattr__(self, name):
        return getattr(self._env, name)

    @property
    def action_space(self):
        low = np.where(self._mask, -np.ones_like(self._low), self._low)
        high = np.where(self._mask, np.ones_like(self._low), self._high)
        return gym.spaces.Box(low, high, dtype=np.float32)

    def step(self, action):
        original = (action + 1) / 2 * (self._high - self._low) + self._low
        original = np.where(self._mask, original, action)
        return self._env.step(original)

class ObsDict:

    def __init__(self, env, key='obs'):
        self._env = env
        self._key = key

    def __getattr__(self, name):
        return getattr(self._env, name)

    @property
    def observation_space(self):
        spaces = {self._key: self._env.observation_space}
        return gym.spaces.Dict(spaces)

    @property
    def action_space(self):
        return self._env.action_space

    def step(self, action):
        obs, reward, done, info = self._env.step(action)
        obs = {self._key: np.array(obs)}
        return obs, reward, done, info

    def reset(self):
        obs = self._env.reset()
        obs = {self._key: np.array(obs)}
        return obs

class OneHotAction:

    def __init__(self, env):
        assert isinstance(env.action_space, gym.spaces.Discrete)
        self._env = env

    def __getattr__(self, name):
        return getattr(self._env, name)

    @property
    def action_space(self):
        shape = (self._env.action_space.n,)
        space = gym.spaces.Box(low=0, high=1, shape=shape, dtype=np.float32)
        space.sample = self._sample_action
        return space

    def step(self, action):
        index = np.argmax(action).astype(int)
        reference = np.zeros_like(action)
        reference[index] = 1
        if not np.allclose(reference, action):
          raise ValueError(f'Invalid one-hot action:\n{action}')
        return self._env.step(index)

    def reset(self):
        return self._env.reset()

    def _sample_action(self):
        actions = self._env.action_space.n
        index = self._random.randint(0, actions)
        reference = np.zeros(actions, dtype=np.float32)
        reference[index] = 1.0
        return reference

class RewardObs:

    def __init__(self, env):
        self._env = env

    def __getattr__(self, name):
        return getattr(self._env, name)

    @property
    def observation_space(self):
        spaces = self._env.observation_space.spaces
        assert 'reward' not in spaces
        spaces['reward'] = gym.spaces.Box(-np.inf, np.inf, dtype=np.float32)
        return gym.spaces.Dict(spaces)

    def step(self, action):
        obs, reward, done, info = self._env.step(action)
        obs['reward'] = reward
        return obs, reward, done, info

    def reset(self):
        obs = self._env.reset()
        obs['reward'] = 0.0
        return obs

class ResizeImage:

    def __init__(self, env, size=(64, 64)):
        self._env = env
        self._size = size
        self._keys = [
            k for k, v in env.obs_space.items()
            if len(v.shape) > 1 and v.shape[:2] != size]
        print(f'Resizing keys {",".join(self._keys)} to {self._size}.')
        if self._keys:
          from PIL import Image
          self._Image = Image

    def __getattr__(self, name):
        if name.startswith('__'):
          raise AttributeError(name)
        try:
          return getattr(self._env, name)
        except AttributeError:
          raise ValueError(name)

    @property
    def obs_space(self):
        spaces = self._env.obs_space
        for key in self._keys:
          shape = self._size + spaces[key].shape[2:]
          spaces[key] = gym.spaces.Box(0, 255, shape, np.uint8)
        return spaces

    def step(self, action):
        obs = self._env.step(action)
        for key in self._keys:
          obs[key] = self._resize(obs[key])
        return obs

    def reset(self):
        obs = self._env.reset()
        for key in self._keys:
          obs[key] = self._resize(obs[key])
        return obs

    def _resize(self, image):
        image = self._Image.fromarray(image)
        image = image.resize(self._size, self._Image.NEAREST)
        image = np.array(image)
        return image

class RenderImage:

    def __init__(self, env, key='image'):
        self._env = env
        self._key = key
        self._shape = self._env.render().shape

    def __getattr__(self, name):
        if name.startswith('__'):
          raise AttributeError(name)
        try:
          return getattr(self._env, name)
        except AttributeError:
          raise ValueError(name)

    @property
    def obs_space(self):
        spaces = self._env.obs_space
        spaces[self._key] = gym.spaces.Box(0, 255, self._shape, np.uint8)
        return spaces

    def step(self, action):
        obs = self._env.step(action)
        obs[self._key] = self._env.render('rgb_array')
        return obs

    def reset(self):
        obs = self._env.reset()
        obs[self._key] = self._env.render('rgb_array')
        return obs


def myAtoi(s):
    if s == '': return 0
    i = 0
    while i < len(s):
        if s[i] != ' ':
            break
        i+= 1
    if i == len(s):
        return 0
    ret = '0'
    isNegative = False
    if s[i] == '-':
        isNegative = True
        i+=1
    elif s[i] == '+':
        i+=1

    for char in s[i:]:
        if not char.isnumeric():
            break
        else:
            ret += char

    if isNegative: ret = -int(ret)
    else: ret = int(ret)
    if ret > 2**31-1:
        return 2**31-1
    if ret < -2**31:
        return -2**31
    return ret

def main():
    test = 0
    if test:
        print(function(test))
    tests = ['1234','-1234','   52ABC',str(2**32)]
    if tests:
        for test in tests:
            print(test,'->',myAtoi(test))

if __name__ == "__main__":
    main()


#!/usr/bin/env python3

# === IMPORTS ===
# Utils
import os
import json

# === FUNCTIONS ===
def obtain_json_data():
    file_directory = os.path.dirname(os.path.abspath(__file__))
    json_path = os.path.join(file_directory, "posts.json")
    with open(json_path, "r") as json_file:
        data = json.load(json_file)
    return data

# === CLASSES ===
class Post:
    def __init__(
        self,
        type,
        id,
        url,
        user,
        totalLikes,
        isBlocked,
        isActive,
        totalViews,
        location,
        date,
    ):
        self.type = type
        self.oid = id
        self.url = url
        self.user = user
        self.totalLikes = totalLikes
        self.isBlocked = isBlocked
        self.isActive = isActive
        self.totalViews = totalViews
        self.location = location
        self.date = date

    def __str__(self):
        return f"{self.oid}: {self.user}"

    def to_dict_custom(self, field):
        return {"id": self.oid, "total": getattr(self, field)}

class Posts:
    def __init__(self):
        data = obtain_json_data()
        self.posts = [
            Post(
                type=item.get("type"),
                id=item.get("id"),
                url=item.get("url"),
                user=item.get("user"),
                totalLikes=item.get("totalLikes"),
                isBlocked=item.get("isBlocked"),
                isActive=item.get("isActive"),
                totalViews=item.get("totalViews"),
                location=item.get("location"),
                date=item.get("date"),
            )
            for item in data
        ]

    def get_top_n_of_total_likes(self, n=None):
        posts_with_likes = [post for post in self.posts if post.totalLikes is not None]
        sorted_objects = sorted(
            posts_with_likes, key=lambda x: getattr(x, "totalLikes"), reverse=True
        )
        result = [post.to_dict_custom("totalLikes") for post in sorted_objects]

        return result[:n]

    def get_top_n_of_total_views(self, n: int):
        posts_with_views = [post for post in self.posts if post.totalViews is not None]
        sorted_objects = sorted(
            posts_with_views, key=lambda x: getattr(x, "totalViews"), reverse=True
        )
        top_list = [post.to_dict_custom("totalViews") for post in sorted_objects[:n]]

        return top_list

    def get_top_n_of_writers(self, n: int):
        posts_with_user = [post for post in self.posts if post.totalViews is not None]
        result = {}
        for post in posts_with_user:
            if post.user in result:
                result[post.user] += 1
            else:
                result[post.user] = 1
        sorted_items = sorted(result.items(), key=lambda x: x[1], reverse=True)
        top_list = [{"id": key, "total": value} for key, value in sorted_items[:n]]

        return top_list


import os

import aiohttp
from aiohttp import ClientResponseError, ServerTimeoutError, TooManyRedirects

from userge import Config, Message, userge

DOGBIN_URL = "https://del.dog/"
NEKOBIN_URL = "https://nekobin.com/"

@userge.on_cmd(
    "paste",
    about={
        "header": "Pastes text or text_file to dogbin",
        "flags": {"-n": "use nekobin"},
        "usage": "{tr}paste [flags] [file_type] [text | reply to msg]",
        "examples": "{tr}paste -py import os",
    },
    del_pre=True,
)
async def paste_(message: Message) -> None:
    """pastes the text directly to dogbin or nekobin"""
    await message.edit("`Processing...`")
    text = message.filtered_input_str
    replied = message.reply_to_message
    use_neko = False
    file_ext = ".txt"
    if not text and replied:
        if replied.document and replied.document.file_size < 2 ** 20 * 10:
            file_ext = os.path.splitext(replied.document.file_name)[1]
            path = await replied.download(Config.DOWN_PATH)
            with open(path, "r") as d_f:
                text = d_f.read()
            os.remove(path)
        elif replied.text:
            text = replied.text
    if not text:
        await message.err("input not found!")
        return
    flags = list(message.flags)
    if "n" in flags:
        use_neko = True
        flags.remove("n")
    if flags and len(flags) == 1:
        file_ext = "." + flags[0]
    await message.edit("`Pasting text ...`")
    async with aiohttp.ClientSession() as ses:
        if use_neko:
            async with ses.post(
                NEKOBIN_URL + "api/documents", json={"content": text}
            ) as resp:
                if resp.status == 201:
                    response = await resp.json()
                    key = response["result"]["key"]
                    final_url = NEKOBIN_URL + key + file_ext
                    reply_text = f"**Nekobin** [URL]({final_url})"
                    await message.edit(reply_text, disable_web_page_preview=True)
                else:
                    await message.err("Failed to reach Nekobin")
        else:
            async with ses.post(
                DOGBIN_URL + "documents", data=text.encode("utf-8")
            ) as resp:
                if resp.status == 200:
                    response = await resp.json()
                    key = response["key"]
                    final_url = DOGBIN_URL + key
                    if response["isUrl"]:
                        reply_text = (
                            f"**Shortened** [URL]({final_url})\n"
                            f"**Dogbin** [URL]({DOGBIN_URL}v/{key})"
                        )
                    else:
                        reply_text = f"**Dogbin** [URL]({final_url}{file_ext})"
                    await message.edit(reply_text, disable_web_page_preview=True)
                else:
                    await message.err("Failed to reach Dogbin")

@userge.on_cmd(
    "getpaste",
    about={
        "header": "Gets the content of a del.dog paste",
        "usage": "{tr}getpaste [del.dog or nekobin link]",
    },
)
async def get_paste_(message: Message):
    """fetches the content of a dogbin or nekobin URL"""
    link = message.input_str
    if not link:
        await message.err("input not found!")
        return
    await message.edit("`Getting paste content...`")
    format_view = f"{DOGBIN_URL}v/"
    if link.startswith(format_view):
        link = link[len(format_view) :]
        raw_link = f"{DOGBIN_URL}raw/{link}"
    elif link.startswith(DOGBIN_URL):
        link = link[len(DOGBIN_URL) :]
        raw_link = f"{DOGBIN_URL}raw/{link}"
    elif link.startswith("del.dog/"):
        link = link[len("del.dog/") :]
        raw_link = f"{DOGBIN_URL}raw/{link}"
    elif link.startswith(NEKOBIN_URL):
        link = link[len(NEKOBIN_URL) :]
        raw_link = f"{NEKOBIN_URL}raw/{link}"
    elif link.startswith("nekobin.com/"):
        link = link[len("nekobin.com/") :]
        raw_link = f"{NEKOBIN_URL}raw/{link}"
    else:
        await message.err("Is that even a paste url?")
        return
    async with aiohttp.ClientSession(raise_for_status=True) as ses:
        try:
            async with ses.get(raw_link) as resp:
                text = await resp.text()
        except ServerTimeoutError as e_r:
            await message.err(f"Request timed out -> {e_r}")
        except TooManyRedirects as e_r:
            await message.err(
                "Request exceeded the configured "
                f"number of maximum redirections -> {e_r}"
            )
        except ClientResponseError as e_r:
            await message.err(f"Request returned an unsuccessful status code -> {e_r}")
        else:
            await message.edit_or_send_as_file(
                "--Fetched Content Successfully!--" f"\n\n**Content** :\n`{text}`"
            )


import random
number = random.randint(1,9)
chance = 0
print("Guess a number(between 1 and 9):")
while chance<5:
    guess = int(input("Enter your Guess"))
    if guess == number:
        print("Congratulations,You won!!")
        break
    elif guess<number:
        print("Guess was too low,guess a number higher than that!!")

    else :
        print("Guess was too high,guess a number lower than that!!")

    chance+=1


# -*- coding: utf-8 -*-

from odoo import models, fields, api
from odoo.exceptions import AccessError, UserError, ValidationError
import logging

_logger = logging.getLogger(__name__)

class PurchaseOrder(models.Model):
    _inherit = ['purchase.order']

#     can_send_po = fields.Boolean(compute = '_can_send_po')
    user_access_level = fields.Integer(compute='_compute_user_access', default=0)
    is_approve_visible = fields.Boolean(compute='_is_approve_visible', default=False)

    pre_approved = fields.Float(store=True, default=False)
    final_approved = fields.Float(store=True, default=False)

    # Overriding original action_cancel to ask for approval if user is not assistant nor manager
    def button_cancel(self):
        if not self.env.user.has_group('po_approval.group_purchase_assistant') and self.state not in ('draft'):
            # Getting all assistant/manager users
            all_users = self.env['res.users'].search([('active', '=', True)])
            my_users_group = all_users.filtered(lambda user: user.has_group('po_approval.group_purchase_assistant'))

            partner_ids = []
            for user in my_users_group:
                partner_ids.append(user.partner_id.id)

            _logger.info(f"Action cancel - po approval assistants {partner_ids}")
            view = self.env.ref('log_wizard.log_message_wizard_view')
            wiz = self.env['log.message.wizard'].create({})
            wiz_name = "PO cancellation request"

            ctx = {
                'subject': wiz_name,
                'partner_ids': partner_ids,
                'parent_model': self._name,
                'parent_id': self.id,
            }

            return {
                'name': wiz_name,
                'type': 'ir.actions.act_window',
                'view_type': 'form',
                'view_mode': 'form',
                'res_model': 'log.message.wizard',
                'views': [(view.id, 'form')],
                'view_id': view.id,
                'target': 'new',
                'res_id': wiz.id,
                'context': ctx
            }
        else:
            for order in self:
                for inv in order.invoice_ids:
                    if inv and inv.state not in ('cancel', 'draft'):
                        raise UserError("Unable to cancel this purchase order. You must first cancel the related vendor bills.")

            view = self.env.ref('log_wizard.log_message_wizard_view')
            wiz = self.env['log.message.wizard'].create({})
            wiz_name = "RFQ cancellation reason"

            ctx = {
                'subject': wiz_name,
                'to_state': 'cancel',
                'parent_model': self._name,
                'parent_id': self.id,
            }

            return {
                'name': wiz_name,
                'type': 'ir.actions.act_window',
                'view_type': 'form',
                'view_mode': 'form',
                'res_model': 'log.message.wizard',
                'views': [(view.id, 'form')],
                'view_id': view.id,
                'target': 'new',
                'res_id': wiz.id,
                'context': ctx
            }

    @api.depends('user_id')
    def _compute_user_access(self):
        # If user is manager - access level = 2
        # If user is assistant - access level = 1
        # If user is user - access level = 0
        _logger.info("_compute_user_access")
        if self.env.user.has_group('purchase.group_purchase_manager'):
            self.user_access_level = 2
            _logger.info("level 2")
        elif self.env.user.has_group('po_approval.group_purchase_assistant'):
            self.user_access_level = 1
            _logger.info("level 1")
        else:
            self.user_access_level = 0
            _logger.info("level 0")

#     @api.depends('user_access_level')
#     def _can_send_po(self):
#         _logger.info("_can_send_po")

#         user_access_level = self.user_access_level
#         env_lock_conf_po = self.company_id.po_lock == 'lock'

#         _logger.info(f"user level -> {user_access_level}")
#         _logger.info(f"lock conf PO -> {env_lock_conf_po}")
#         if env_lock_conf_po:
#             if user_access_level > 0 and self.state in ('done', 'purchase'):
#                 self.can_send_po = True
#                 _logger.info(f"can send -> True")
#             else:
#                 self.can_send_po = False
#                 _logger.info(f"can send -> False")
#         else:
#             self.can_send_po = True
#             _logger.info(f"can send -> True")

    @api.depends('user_id')
    def _is_approve_visible(self):

        if self.env.user.has_group('purchase.group_purchase_manager'):
            is_user_manager = True
            is_user_assistant = False
        else:
            is_user_manager = False
            if self.env.user.has_group('po_approval.group_purchase_assistant'):
                is_user_assistant = True
            else:
                is_user_assistant = False

        if self.state in ('to approve'):
            if (is_user_assistant and not self.pre_approved) or (is_user_manager):
                self.is_approve_visible = True
            else:
                self.is_approve_visible = False
        else:
            self.is_approve_visible = False

    # Overriding original method to allow two-people approval
    def button_approve(self, force=False, override=False):
        # all_users = self.env['res.users'].search([('active', '=', True)])

        if self.env.user.has_group('purchase.group_purchase_manager') or override:
            self.write({'pre_approved':True, 'final_approved':True})
            self.write({'state': 'purchase', 'date_approve': fields.Datetime.now()})
            self.filtered(lambda p: p.company_id.po_lock == 'lock').write({'state': 'done'})
            return {}
        else:
            self.pre_approved = True
            po_number = self.name

            msg = f"
The Purchase Order {po_number} needs final approval.
"
            msg += f"
Vendor: {self.partner_id.name}
"
            try:
                msg += f"
End Customer: {self.end_customer_id.name}
"
            except:
                pass

            all_users = self.env['res.users'].search([('active', '=', True)])

            my_users_group = all_users.filtered(lambda user: user.has_group('purchase.group_purchase_manager'))

            partner_ids = []
            for user in my_users_group:
                partner_ids.append(user.partner_id.id)

            self.message_post(
                subject='Purchase Order pending for Approval',
                body=msg,
                partner_ids=tuple(partner_ids),
            )
            return {}


import math
import numpy as np
import scipy.optimize as optimize

import mlak.LinearAlgebra as la
import mlak.MathTools as mt
import mlak.ModelAnalyzer as ma

def apply_topology( topology, theta_ ):
	theta = []
	offset = 0
	for i in range( 1, len( topology ) ):
		rows = topology[i]
		cols = topology[i - 1] + 1
		s = rows * cols
		t = np.array( theta_[offset:offset + s] )
		t.shape = ( rows, cols )
		theta.append( t )
		offset += s
	return theta

def flatten_nn( theta ):
	return np.concatenate( list( map( lambda x : x.flatten(), theta ) ) )

def randomize_weights( topology, theta ):
	offset = 0
	ss = math.sqrt( 6 )
	for i in range( 1, len( topology ) ):
		rows = topology[i]
		cols = topology[i - 1] + 1
		s = rows * cols
		epsilon = ss / math.sqrt( rows + cols )
		theta[offset:offset + s] = np.random.rand( s ) * epsilon * 2 - epsilon
		offset += s

def compute_cost( theta, *args ):
	X, y, topology, classCount, Lambda, debug = args
	theta = apply_topology( topology, theta )

	for l in range( len( theta ) ):
		X = la.add_ones_column( X )
		X = np.dot( X, theta[l].T )
		X = mt.sigmoid( X )

	m = len( y )
	yp = np.zeros( ( m, classCount ) )
	yp[np.arange( m ), y.flatten()] = 1
	cost = np.sum( -( yp * mt.log( X ) + ( 1 - yp ) * mt.log( 1 - X ) ) )
	r = 0
	for t in theta:
		r += np.sum( t[:,1:] ** 2 )
	cost /= m
	cost += Lambda * r / ( m * 2 )
	if debug: # pragma: no cover
		print( "cost = {}                                \r".format( cost ), end = "" )
	return cost

def activation_derivative( a ):
	return a * ( 1 - a )

def compute_grad( theta, *args ):
	X, y, topology, classCount, Lambda, debug = args
	theta = apply_topology( topology, theta )
	thetaT = []
	for t in theta:
		thetaT.append( t.T )
	gradient = []
	for t in theta:
		gradient.append( np.zeros( t.shape ) )
	activation = []
	for t in thetaT:
		X = la.add_ones_column( X )
		activation.append( X )
		X = np.dot( X, t )
		X = mt.sigmoid( X )
	m = len( y )
	yp = np.zeros( ( m, classCount ) )
	yp[np.arange( m ), y.flatten()] = 1
	delta = ( X - yp ).T
	for g, t, a in zip( reversed( gradient ), reversed( thetaT ), reversed( activation ) ):
		g += np.dot( delta, a )
		delta = np.dot( t, delta ) * activation_derivative( a.T )
		delta = delta[1:]
	for g, t in zip( gradient, theta ):
		t[:, 0] = 0
		g += t * Lambda
		g /= m
	return flatten_nn( gradient )

def predict_one_vs_all( X, topoTheta ):
	topology, theta = topoTheta
	theta = apply_topology( topology, theta )
	y = []
	for i, x in enumerate( X ):
		for l in range( len( theta ) ):
			x = np.concatenate( ( [1], x ) )
			x = np.dot( theta[l], x )
			x = mt.sigmoid( x )
		y.append( x )
	return np.array( y )

class NeuralNetworkSolver:
	def __initial_theta( shaper, y, solution, nnTopology = None, **kwArgs ):
		if solution is None:
			shaper.learn_labels( y )
			topology = list( map( int, nnTopology.split( "," ) ) ) if nnTopology else []
			topology = [shaper.feature_count()] + topology + [shaper.class_count()]
			s = 0
			for i in range( 1, len( topology ) ):
				s += topology[i] * ( topology[i - 1] + 1 )
			theta = np.zeros( s )
			randomize_weights( topology, theta )
			return topology, theta
		return solution.model()

	def type( self_ ):
		return ma.SolverType.CLASSIFIER

	def train( self_, X, y, solution = None, Lambda = 0, iterations = 50, **kwArgs ):
		shaper = solution.shaper() if solution else ma.DataShaper( X, **kwArgs )
		debug = kwArgs.get( "debug", False )
		topology, theta = NeuralNetworkSolver.__initial_theta( shaper, y, solution, **kwArgs )
		y = shaper.map_labels( y )
		X = shaper.conform( X, addOnes = False )
		theta = optimize.fmin_cg(
			compute_cost,
			theta, fprime = compute_grad,
			args = ( X, y, topology, shaper.class_count(), Lambda, debug ),
			maxiter = iterations,
			disp = False
		)
		return ma.Solution( model = ( topology, theta ), shaper = shaper )

	def verify( self_, solution, X, y ):
		accuracy = np.mean( 1.0 * ( y.flatten() == self_.predict( solution, X ) ) )
		return 1 - accuracy

	def predict( self_, solution, X ):
		X = solution.shaper().conform( X, addOnes = False )
		yp = predict_one_vs_all( X, solution.model() )
		yp = np.argmax( yp, axis = 1 )
		return solution.shaper().labels( yp )

	def examine( self_, solution, X ):
		X = solution.shaper().conform( X, addOnes = False )
		yp = predict_one_vs_all( X, solution.model() )
		return ma.label_confidence( solution.shaper(), yp )


class Solution(object):
    def numWays(self, n, k):
        """
        :type n: int
        :type k: int
        :rtype: int
        """
        if n==0 or k==0:
            return 0
        else:
            way={0:1,1:k,2:k**2}
            for i in range(3,n+1):
                way[i]=(k-1)*way[i-1]+(k-1)*way[i-2]
            return way[n]