#! /usr/bin/python3
import random

import iota.harness.api as api
import iota.test.apulu.config.api as config_api
import iota.test.apulu.config.bringup_workloads as wl_api
import iota.test.apulu.utils.learn as learn_utils
import iota.test.apulu.utils.misc as misc_utils
import iota.test.apulu.config.add_routes as add_routes
import iota.test.apulu.utils.move as move_utils
import iota.harness.infra.store as store
import iota.test.utils.arping as arp

intf_client   = config_api.GetObjClient('interface')

def Setup(tc):
    # select one of the LearnIP objects from dictionary
    tc.node = random.choice(api.GetNaplesHostnames())
    tc.learn_mac_obj = random.choice(learn_utils.GetLearnMACObjects(tc.node))
    tc.subnet = tc.learn_mac_obj.SUBNET
    tc.hostifidx = tc.subnet.HostIfIdx
    tc.wload = config_api.FindWorkloadByVnic(tc.learn_mac_obj)
    api.Logger.debug("Chosen subnet %s" % tc.subnet)
    return api.types.status.SUCCESS

def __modify_workload_interface(tc):
    wl_api.DeleteWorkload(tc.wload)
    if api.IsDryrun():
        tc.wload.parent_interface = 'dryrun'
    else:
        tc.wload.parent_interface = intf_client.FindHostInterface(tc.subnet.Node, tc.subnet.HostIfIdx).GetInterfaceName()
    tc.wload.interface = tc.wload.parent_interface
    store.SetWorkloadRunning(tc.wload.workload_name)
    wl_api.ReAddWorkload(tc.wload)
    add_routes.AddRoutes(tc.learn_mac_obj)
    arp.SendGratArp([tc.wload])
    return

def Trigger(tc):
    ret = tc.subnet.ModifyHostInterface()
    if not ret:
        api.Logger.error("Failed to modify host interface association for subnet")
        return api.types.status.FAILURE

    if api.IsDryrun():
        old_intf = new_intf = 'dryrun'
    else:
        old_intf = intf_client.FindHostInterface(tc.subnet.Node, tc.hostifidx).GetInterfaceName()
        new_intf = intf_client.FindHostInterface(tc.subnet.Node, tc.subnet.HostIfIdx).GetInterfaceName()
    api.Logger.debug(f"Subnet moved from HostInterface {old_intf} to {new_intf}")
    ret = tc.subnet.VerifyDepsOperSt('Delete')
    if not ret:
        return api.types.status.FAILURE
    __modify_workload_interface(tc)
    return api.types.status.SUCCESS

def __validate_trigger():
    misc_utils.Sleep(40) # letting metaswitch sync data
    learn_utils.DumpLearnData()
    if move_utils.ValidateEPMove() != api.types.status.SUCCESS:
        return api.types.status.FAILURE
    return api.types.status.SUCCESS

def Verify(tc):
    return __validate_trigger()

def Teardown(tc):
    ret = tc.subnet.ModifyHostInterface(tc.hostifidx)
    if not ret:
        api.Logger.error("Failed to revert host interface modification made to subnet")
        return api.types.status.FAILURE
    __modify_workload_interface(tc)
    return __validate_trigger()


"""
Advent of Code 2017 :: Day 22
Sporifica Virus
"""
from collections import namedtuple, defaultdict
import tqdm
import pyperclip

Position = namedtuple('Position', ['row', 'col'])
Position.__add__ = lambda s, o: Position(s.row + o.row, s.col + o.col)
Position.move = lambda s, cmplx: Position(s.row + cmplx.imag, s.col + cmplx.real)

DirectionsT = namedtuple('Directions', ['up', 'down', 'right', 'left'])
Directions = DirectionsT(Position(-1, 0), Position(1, 0),
                        Position(0, 1), Position(0, -1))

StateT = namedtuple('StateT', ['Clean', 'Weakened', 'Infected', 'Flagged'])
State = StateT(0, 1, 2, 3)

class Sporifica:
    """Represents the virus."""
    def __init__(self, init_pos):
        self.pos = init_pos
        self.direction = Directions.up

    def turn_right(self):
        """Turn"""
        turns = {Directions.up: Directions.right,
                 Directions.left: Directions.up,
                 Directions.down: Directions.left,
                 Directions.right: Directions.down}
        self.direction = turns[self.direction]

    def turn_left(self):
        """Turn"""
        turns = {Directions.up: Directions.left,
                 Directions.left: Directions.down,
                 Directions.down: Directions.right,
                 Directions.right: Directions.up}
        self.direction = turns[self.direction]

    def turn(self, state):
        if state == State.Clean:
            self.turn_left()
        elif state == State.Infected:
            self.turn_right()
        elif state == State.Flagged:
            self.direction = Position(self.direction.row * -1, self.direction.col * -1)

    def move(self):
        """Move"""
        self.pos = self.pos + self.direction

class Cluster:
    """Represents cluster."""
    def __init__(self, memory_string):
        self.infected = defaultdict(int)
        self.infections_caused = 0
        self.init_memory_dim = 0
        self.read_memory(memory_string)
        self.center = self.init_memory_dim // 2
        self.virus = Sporifica(Position(self.center, self.center))

    def read_memory(self, memory_string):
        lines = memory_string.strip().split('\n')
        self.init_memory_dim = len(lines)
        for rindex, row in enumerate(lines):
            for cindex, col in enumerate(row):
                if col == '#':
                    pos = Position(rindex, cindex)
                    self.infected[pos] = State.Infected

    def next_state(self, pos):
        """Changes state of position."""
        if self.infected[pos] == State.Infected:
            self.infected[pos] = State.Clean
        else:
            self.infected[pos] = State.Infected
        if self.infected[pos] == State.Infected:
            self.infections_caused += 1

    def burst(self):
        """Perform one burst."""
        self.virus.turn(self.infected[self.virus.pos])
        self.next_state(self.virus.pos)
        self.virus.move()

class EvolvedCluster(Cluster):
    def __init__(self, memory_string):
        super(EvolvedCluster, self).__init__(memory_string)

    def next_state(self, pos):
        """Changes state of position."""
        self.infected[pos] = (self.infected[pos] + 1) % 4
        if self.infected[pos] == State.Infected:
            self.infections_caused += 1

def solve_a(bursts, memory_string):
    """Solve first part of puzzle."""
    cluster = Cluster(memory_string)
    for _ in tqdm.tqdm(range(bursts)):
       cluster.burst()
    return cluster.infections_caused

def solve_b(bursts, memory_string):
    """Solve first part of puzzle."""
    cluster = EvolvedCluster(memory_string)
    for _ in tqdm.tqdm(range(bursts)):
       cluster.burst()
    return cluster.infections_caused

def solve_a0(bursts, memory_string):
    """Alternate solution for a."""
    infection_count = 0
    rot_left = 1j
    rot_right = -1j
    lines = memory_string.strip().split('\n')
    center = len(lines) // 2
    grid = defaultdict(int)
    for row, line in enumerate(lines):
        for col, char in enumerate(line):
            if char == '#':
                posn = col - (row * 1j)
                grid[posn] = 1
    virus_posn = center - (center * 1j)
    virus_dirn = 1j
    for _ in range(bursts):
        # turn
        curr_state = grid[virus_posn]
        if curr_state == 0: # clean
            virus_dirn *= rot_left
            infection_count += 1  # will be infected
        elif curr_state == 1: # infected
            virus_dirn *= rot_right
        # infect
        new_state = (curr_state + 1) % 2
        grid[virus_posn] = new_state
        # move
        virus_posn += virus_dirn
    return infection_count

def solve_b0(bursts, memory_string):
    """Alternate solution for b."""
    infection_count = 0
    rot_left = 1j
    rot_right = -1j
    lines = memory_string.strip().split('\n')
    center = len(lines) // 2
    grid = defaultdict(int)
    for row, line in enumerate(lines):
        for col, char in enumerate(line):
            if char == '#':
                posn = col - (row * 1j)
                grid[posn] = 2
    virus_posn = center - (center * 1j)
    virus_dirn = 1j
    for _ in tqdm.tqdm(range(bursts)):
        # turn
        curr_state = grid[virus_posn]
        if curr_state == 0: # clean
            virus_dirn *= rot_left
        elif curr_state == 1: # weakened
            infection_count += 1 # will be infected
        elif curr_state == 2: # infected
            virus_dirn *= rot_right
        elif curr_state == 3: # flagged
            virus_dirn *= -1
        # infect
        new_state = (curr_state + 1) % 4
        grid[virus_posn] = new_state
        # move
        virus_posn += virus_dirn
    return infection_count

def main():
    """Main program."""
    import sys
    memory_string = sys.stdin.read()
    solution_a = solve_a0(10000, memory_string)
    print('The solution to Part A is', solution_a)
    solution_b = solve_b0(10000000, memory_string)
    print('The solution to Part B is', solution_b)
    pyperclip.copy(str(solution_b))

if __name__ == '__main__':
    main()


from django.contrib import admin
from django.contrib.auth.models import User
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from jinja2 import Template
from .tokens import account_activation_token
from .models import Account
import datetime
from multiprocessing import Process, Queue, Pool

# Register your models here.
def send(queryset_user):
    template = Template("""
    Date/time: {{ now() }}
    Hi {{ user.username }} ({{ user.email }}),
    Please click the following link to confirm your registration:
    http://127.0.0.1:8002/activate/{{ uid }}/{{ token }}
    """)

    template.globals['now'] = datetime.datetime.utcnow
    template.globals['user'] = queryset_user.user
    template.globals['uid'] = urlsafe_base64_encode(force_bytes(queryset_user.user.pk))
    template.globals['token'] = account_activation_token.make_token(queryset_user.user)

    subject = 'Please Activate Your Account'
    # return subject, template.render()
    queryset_user.user.email_user(subject, template.render())

q = Queue()

def putUserInQ(queryset):
    for quser in queryset:
        q.put(quser)

def sendQuser():
    while not q.empty():
        send(q.get())

def send_signup_confirmation(modeladmin, request, queryset):
    process_one = Process(target = putUserInQ, args = (queryset, ))
    process_two = Process(target = sendQuser, args = (None, ))

    process_one.start()
    process_two.start()

    q.close()
    q.join_thread()

    process_one.join()
    process_two.join()

send_signup_confirmation.short_description = "Send signup confirmation"

class AccountAdmin(admin.ModelAdmin):
    list_display = ['user', 'verification']
    ordering = ['user']
    actions = [send_signup_confirmation]

admin.site.register(Account, AccountAdmin)


#!/usr/bin/env python
import yaml
import os

def splitToYamls(yamlFile):
    with open(yamlFile, 'r') as file:
        fybrik_list = yaml.load_all(file, Loader=yaml.FullLoader)
        for yml in fybrik_list:
            if yml:
                filename = yml['kind'].lower()
                resourceName = yml['metadata']['name']
                apiVersion = yml['apiVersion'].split('/')[0]
                kind = yml['kind'].lower()+'s'
                outputPath = os.path.join(apiVersion, kind, resourceName, filename + ".yaml")
                os.makedirs(os.path.dirname(outputPath), exist_ok = True)
                with open(outputPath,'w') as f:
                    yaml.dump(yml, f)

def createKustomizations():
    dirs = [name for name in os.listdir(".") if os.path.isdir(name)]
    apiVersions = []
    for folder in dirs:
        apiVersions.append(os.path.join(".", folder))
    for apiVersion in apiVersions:
        resourceKinds = os.listdir(apiVersion)
        for resourceKind in resourceKinds:
            resourceNames = os.listdir(os.path.join(apiVersion, resourceKind))
            for resource in resourceNames:
                resourcePath = os.path.join(apiVersion, resourceKind, resource)
                kustomizationString = "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization" + "\nresources:\n"
                yamlFile = resourceKind[:-1] + '.yaml'
                kustomizationString += "- " + yamlFile +'\n'
                outputPath = os.path.join(resourcePath,'kustomization.yaml')
                with open (outputPath, 'w') as f:
                    f.write(kustomizationString)

def main():
    splitToYamls('fybrik-crd.yaml')
    splitToYamls('fybrik-vault.yaml')
    print("Successfully split files into yamls and wrote to appropriate directories\n")

    createKustomizations()
    print("Successfully created kustomization files in each subdirectory\n")

if __name__ == "__main__":
    main()


import calendar

from collections import defaultdict, OrderedDict
from datetime import timedelta

from odoo import _, api, fields, models
from odoo.exceptions import UserError, ValidationError
from odoo.osv import expression
from odoo.tools.float_utils import float_compare

class Location(models.Model):
    _name = "stock.location"
    _description = "Inventory Locations"
    _parent_name = "location_id"
    _parent_store = True
    _order = 'complete_name, id'
    _rec_name = 'complete_name'
    _rec_names_search = ['complete_name', 'barcode']
    _check_company_auto = True

    @api.model
    def default_get(self, fields):
        res = super(Location, self).default_get(fields)
        if 'barcode' in fields and 'barcode' not in res and res.get('complete_name'):
            res['barcode'] = res['complete_name']
        return res

    name = fields.Char('Location Name', required=True)
    complete_name = fields.Char("Full Location Name", compute='_compute_complete_name', recursive=True, store=True)
    active = fields.Boolean('Active', default=True, help="By unchecking the active field, you may hide a location without deleting it.")
    usage = fields.Selection([
        ('supplier', 'Vendor Location'),
        ('view', 'View'),
        ('internal', 'Internal Location'),
        ('customer', 'Customer Location'),
        ('inventory', 'Inventory Loss'),
        ('production', 'Production'),
        ('transit', 'Transit Location')], string='Location Type',
        default='internal', index=True, required=True,
        help="* Vendor Location: Virtual location representing the source location for products coming from your vendors"
             "\n* View: Virtual location used to create a hierarchical structures for your warehouse, aggregating its child locations ; can't directly contain products"
             "\n* Internal Location: Physical locations inside your own warehouses,"
             "\n* Customer Location: Virtual location representing the destination location for products sent to your customers"
             "\n* Inventory Loss: Virtual location serving as counterpart for inventory operations used to correct stock levels (Physical inventories)"
             "\n* Production: Virtual counterpart location for production operations: this location consumes the components and produces finished products"
             "\n* Transit Location: Counterpart location that should be used in inter-company or inter-warehouses operations")
    location_id = fields.Many2one(
        'stock.location', 'Parent Location', index=True, ondelete='cascade', check_company=True,
        help="The parent location that includes this location. Example : The 'Dispatch Zone' is the 'Gate 1' parent location.")
    child_ids = fields.One2many('stock.location', 'location_id', 'Contains')
    child_internal_location_ids = fields.Many2many(
        'stock.location',
        string='Internal locations among descendants',
        compute='_compute_child_internal_location_ids',
        recursive=True,
        help='This location (if it\'s internal) and all its descendants filtered by type=Internal.'
    )
    comment = fields.Html('Additional Information')
    posx = fields.Integer('Corridor (X)', default=0, help="Optional localization details, for information purpose only")
    posy = fields.Integer('Shelves (Y)', default=0, help="Optional localization details, for information purpose only")
    posz = fields.Integer('Height (Z)', default=0, help="Optional localization details, for information purpose only")
    parent_path = fields.Char(index=True, unaccent=False)
    company_id = fields.Many2one(
        'res.company', 'Company',
        default=lambda self: self.env.company, index=True,
        help='Let this field empty if this location is shared between companies')
    scrap_location = fields.Boolean('Is a Scrap Location?', default=False, help='Check this box to allow using this location to put scrapped/damaged goods.')
    return_location = fields.Boolean('Is a Return Location?', help='Check this box to allow using this location as a return location.')
    replenish_location = fields.Boolean('Replenish Location', copy=False, compute="_compute_replenish_location", readonly=False, store=True,
                                        help='Activate this function to get all quantities to replenish at this particular location')
    removal_strategy_id = fields.Many2one(
        'product.removal', 'Removal Strategy',
        help="Defines the default method used for suggesting the exact location (shelf) "
             "where to take the products from, which lot etc. for this location. "
             "This method can be enforced at the product category level, "
             "and a fallback is made on the parent locations if none is set here.\n\n"
             "FIFO: products/lots that were stocked first will be moved out first.\n"
             "LIFO: products/lots that were stocked last will be moved out first.\n"
             "Closet location: products/lots closest to the target location will be moved out first.\n"
             "FEFO: products/lots with the closest removal date will be moved out first "
             "(the availability of this method depends on the \"Expiration Dates\" setting).")
    putaway_rule_ids = fields.One2many('stock.putaway.rule', 'location_in_id', 'Putaway Rules')
    barcode = fields.Char('Barcode', copy=False)
    quant_ids = fields.One2many('stock.quant', 'location_id')
    cyclic_inventory_frequency = fields.Integer("Inventory Frequency (Days)", default=0, help=" When different than 0, inventory count date for products stored at this location will be automatically set at the defined frequency.")
    last_inventory_date = fields.Date("Last Effective Inventory", readonly=True, help="Date of the last inventory at this location.")
    next_inventory_date = fields.Date("Next Expected Inventory", compute="_compute_next_inventory_date", store=True, help="Date for next planned inventory based on cyclic schedule.")
    warehouse_view_ids = fields.One2many('stock.warehouse', 'view_location_id', readonly=True)
    warehouse_id = fields.Many2one('stock.warehouse', compute='_compute_warehouse_id', store=True)
    storage_category_id = fields.Many2one('stock.storage.category', string='Storage Category', check_company=True)
    outgoing_move_line_ids = fields.One2many('stock.move.line', 'location_id') # used to compute weight
    incoming_move_line_ids = fields.One2many('stock.move.line', 'location_dest_id') # used to compute weight
    net_weight = fields.Float('Net Weight', compute="_compute_weight")
    forecast_weight = fields.Float('Forecasted Weight', compute="_compute_weight")

    _sql_constraints = [('barcode_company_uniq', 'unique (barcode,company_id)', 'The barcode for a location must be unique per company!'),
                        ('inventory_freq_nonneg', 'check(cyclic_inventory_frequency >= 0)', 'The inventory frequency (days) for a location must be non-negative')]

    @api.depends('outgoing_move_line_ids.quantity_product_uom', 'incoming_move_line_ids.quantity_product_uom',
                 'outgoing_move_line_ids.state', 'incoming_move_line_ids.state',
                 'outgoing_move_line_ids.product_id.weight', 'outgoing_move_line_ids.product_id.weight',
                 'quant_ids.quantity', 'quant_ids.product_id.weight')
    @api.depends_context('exclude_sml_ids')
    def _compute_weight(self):
        for location in self:
            location.net_weight = 0
            quants = location.quant_ids.filtered(lambda q: q.product_id.type != 'service')
            excluded_sml_ids = self._context.get('exclude_sml_ids', [])
            incoming_move_lines = location.incoming_move_line_ids.filtered(lambda ml: ml.product_id.type != 'service' and ml.state not in ['draft', 'done', 'cancel'] and ml.id not in excluded_sml_ids)
            outgoing_move_lines = location.outgoing_move_line_ids.filtered(lambda ml: ml.product_id.type != 'service' and ml.state not in ['draft', 'done', 'cancel'] and ml.id not in excluded_sml_ids)
            for quant in quants:
                location.net_weight += quant.product_id.weight * quant.quantity
            location.forecast_weight = location.net_weight
            for line in incoming_move_lines:
                location.forecast_weight += line.product_id.weight * line.quantity_product_uom
            for line in outgoing_move_lines:
                location.forecast_weight -= line.product_id.weight * line.quantity_product_uom

    @api.depends('name', 'location_id.complete_name', 'usage')
    def _compute_complete_name(self):
        for location in self:
            if location.location_id and location.usage != 'view':
                location.complete_name = '%s/%s' % (location.location_id.complete_name, location.name)
            else:
                location.complete_name = location.name

    @api.depends('cyclic_inventory_frequency', 'last_inventory_date', 'usage', 'company_id')
    def _compute_next_inventory_date(self):
        for location in self:
            if location.company_id and location.usage in ['internal', 'transit'] and location.cyclic_inventory_frequency > 0:
                try:
                    if location.last_inventory_date:
                        days_until_next_inventory = location.cyclic_inventory_frequency - (fields.Date.today() - location.last_inventory_date).days
                        if days_until_next_inventory <= 0:
                            location.next_inventory_date = fields.Date.today() + timedelta(days=1)
                        else:
                            location.next_inventory_date = location.last_inventory_date + timedelta(days=location.cyclic_inventory_frequency)
                    else:
                        location.next_inventory_date = fields.Date.today() + timedelta(days=location.cyclic_inventory_frequency)
                except OverflowError:
                    raise UserError(_("The selected Inventory Frequency (Days) creates a date too far into the future."))
            else:
                location.next_inventory_date = False

    @api.depends('warehouse_view_ids', 'location_id')
    def _compute_warehouse_id(self):
        warehouses = self.env['stock.warehouse'].search([('view_location_id', 'parent_of', self.ids)])
        warehouses = warehouses.sorted(lambda w: w.view_location_id.parent_path, reverse=True)
        view_by_wh = OrderedDict((wh.view_location_id.id, wh.id) for wh in warehouses)
        self.warehouse_id = False
        for loc in self:
            if not loc.parent_path:
                continue
            path = set(int(loc_id) for loc_id in loc.parent_path.split('/')[:-1])
            for view_location_id in view_by_wh:
                if view_location_id in path:
                    loc.warehouse_id = view_by_wh[view_location_id]
                    break

    @api.depends('child_ids.usage', 'child_ids.child_internal_location_ids')
    def _compute_child_internal_location_ids(self):
        # batch reading optimization is not possible because the field has recursive=True
        for loc in self:
            loc.child_internal_location_ids = self.search([('id', 'child_of', loc.id), ('usage', '=', 'internal')])

    @api.onchange('usage')
    def _onchange_usage(self):
        if self.usage not in ('internal', 'inventory'):
            self.scrap_location = False

    @api.depends('usage')
    def _compute_replenish_location(self):
        for loc in self:
            if loc.usage != 'internal':
                loc.replenish_location = False

    @api.constrains('replenish_location', 'location_id', 'usage')
    def _check_replenish_location(self):
        for loc in self:
            if loc.replenish_location:
                # cannot have parent/child location set as replenish as well
                replenish_wh_location = self.search([('id', '!=', loc.id), ('replenish_location', '=', True), '|', ('location_id', 'child_of', loc.id), ('location_id', 'parent_of', loc.id)], limit=1)
                if replenish_wh_location:
                    raise ValidationError(_('Another parent/sub replenish location %s exists, if you wish to change it, uncheck it first', replenish_wh_location.name))

    @api.constrains('scrap_location')
    def _check_scrap_location(self):
        for record in self:
            if record.scrap_location and self.env['stock.picking.type'].search([('code', '=', 'mrp_operation'), ('default_location_dest_id', '=', record.id)]):
                raise ValidationError(_("You cannot set a location as a scrap location when it assigned as a destination location for a manufacturing type operation."))

    def write(self, values):
        if 'company_id' in values:
            for location in self:
                if location.company_id.id != values['company_id']:
                    raise UserError(_("Changing the company of this record is forbidden at this point, you should rather archive it and create a new one."))
        if 'usage' in values and values['usage'] == 'view':
            if self.mapped('quant_ids'):
                raise UserError(_("This location's usage cannot be changed to view as it contains products."))
        if 'usage' in values or 'scrap_location' in values:
            modified_locations = self.filtered(
                lambda l: any(l[f] != values[f] if f in values else False
                              for f in {'usage', 'scrap_location'}))
            reserved_quantities = self.env['stock.move.line'].search_count([
                ('location_id', 'in', modified_locations.ids),
                ('quantity_product_uom', '>', 0),
            ])
            if reserved_quantities:
                raise UserError(_(
                    "You cannot change the location type or its use as a scrap"
                    " location as there are products reserved in this location."
                    " Please unreserve the products first."
                ))
        if 'active' in values:
            if not values['active']:
                for location in self:
                    warehouses = self.env['stock.warehouse'].search([('active', '=', True), '|', ('lot_stock_id', '=', location.id), ('view_location_id', '=', location.id)], limit=1)
                    if warehouses:
                        raise UserError(_(
                            "You cannot archive the location %s as it is used by your warehouse %s",
                            location.display_name, warehouses.display_name))

            if not self.env.context.get('do_not_check_quant'):
                children_location = self.env['stock.location'].with_context(active_test=False).search([('id', 'child_of', self.ids)])
                internal_children_locations = children_location.filtered(lambda l: l.usage == 'internal')
                children_quants = self.env['stock.quant'].search(['&', '|', ('quantity', '!=', 0), ('reserved_quantity', '!=', 0), ('location_id', 'in', internal_children_locations.ids)])
                if children_quants and not values['active']:
                    raise UserError(_(
                        "You can't disable locations %s because they still contain products.",
                        ', '.join(children_quants.mapped('location_id.display_name'))))
                else:
                    super(Location, children_location - self).with_context(do_not_check_quant=True).write({
                        'active': values['active'],
                    })

        res = super().write(values)
        self.invalidate_model(['warehouse_id'])
        return res

    @api.model_create_multi
    def create(self, vals_list):
        res = super().create(vals_list)
        self.invalidate_model(['warehouse_id'])
        return res

    @api.returns('self', lambda value: value.id)
    def copy(self, default=None):
        default = dict(default or {})
        if 'name' not in default:
            default['name'] = _("%s (copy)", self.name)
        return super().copy(default=default)

    def _get_putaway_strategy(self, product, quantity=0, package=None, packaging=None, additional_qty=None):
        """Returns the location where the product has to be put, if any compliant
        putaway strategy is found. Otherwise returns self.
        The quantity should be in the default UOM of the product, it is used when
        no package is specified.
        """
        self = self._check_access_putaway()
        products = self.env.context.get('products', self.env['product.product'])
        products |= product
        # find package type on package or packaging
        package_type = self.env['stock.package.type']
        if package:
            package_type = package.package_type_id
        elif packaging:
            package_type = packaging.package_type_id

        categ = products.categ_id if len(products.categ_id) == 1 else self.env['product.category']
        categs = categ
        while categ.parent_id:
            categ = categ.parent_id
            categs |= categ

        putaway_rules = self.putaway_rule_ids.filtered(lambda rule:
                                                       (not rule.product_id or rule.product_id in products) and
                                                       (not rule.category_id or rule.category_id in categs) and
                                                       (not rule.package_type_ids or package_type in rule.package_type_ids))

        putaway_rules = putaway_rules.sorted(lambda rule: (rule.package_type_ids,
                                                           rule.product_id,
                                                           rule.category_id == categs[:1],  # same categ, not a parent
                                                           rule.category_id),
                                             reverse=True)

        putaway_location = None
        locations = self.child_internal_location_ids
        if putaway_rules:
            # get current product qty (qty in current quants and future qty on assigned ml) of all child locations
            qty_by_location = defaultdict(lambda: 0)
            if locations.storage_category_id:
                if package and package.package_type_id:
                    move_line_data = self.env['stock.move.line']._read_group([
                        ('id', 'not in', self._context.get('exclude_sml_ids', [])),
                        ('result_package_id.package_type_id', '=', package_type.id),
                        ('state', 'not in', ['draft', 'cancel', 'done']),
                    ], ['location_dest_id'], ['result_package_id:count_distinct'])
                    quant_data = self.env['stock.quant']._read_group([
                        ('package_id.package_type_id', '=', package_type.id),
                        ('location_id', 'in', locations.ids),
                    ], ['location_id'], ['package_id:count_distinct'])
                    qty_by_location.update({location_dest.id: count for location_dest, count in move_line_data})
                    for location, count in quant_data:
                        qty_by_location[location.id] += count
                else:
                    move_line_data = self.env['stock.move.line']._read_group([
                        ('id', 'not in', self._context.get('exclude_sml_ids', [])),
                        ('product_id', '=', product.id),
                        ('location_dest_id', 'in', locations.ids),
                        ('state', 'not in', ['draft', 'done', 'cancel'])
                    ], ['location_dest_id'], ['quantity:array_agg', 'product_uom_id:recordset'])
                    quant_data = self.env['stock.quant']._read_group([
                        ('product_id', '=', product.id),
                        ('location_id', 'in', locations.ids),
                    ], ['location_id'], ['quantity:sum'])

                    qty_by_location.update({location.id: quantity_sum for location, quantity_sum in quant_data})
                    for location_dest, quantity_list, uoms in move_line_data:
                        quantity = sum(ml_uom._compute_quantity(float(qty), product.uom_id) for qty, ml_uom in zip(quantity_list, uoms))
                        qty_by_location[location_dest.id] += quantity

            if additional_qty:
                for location_id, qty in additional_qty.items():
                    qty_by_location[location_id] += qty
            putaway_location = putaway_rules._get_putaway_location(product, quantity, package, packaging, qty_by_location)

        if not putaway_location:
            putaway_location = locations[0] if locations and self.usage == 'view' else self

        return putaway_location

    def _get_next_inventory_date(self):
        """ Used to get the next inventory date for a quant located in this location. It is
        based on:
        1. Does the location have a cyclic inventory set?
        2. If not 1, then is there an annual inventory date set (for its company)?
        3. If not 1 and 2, then quants have no next inventory date."""
        if self.usage not in ['internal', 'transit']:
            return False
        next_inventory_date = False
        if self.next_inventory_date:
            next_inventory_date = self.next_inventory_date
        elif self.company_id.annual_inventory_month:
            today = fields.Date.today()
            annual_inventory_month = int(self.company_id.annual_inventory_month)
            # Manage 0 and negative annual_inventory_day
            annual_inventory_day = max(self.company_id.annual_inventory_day, 1)
            max_day = calendar.monthrange(today.year, annual_inventory_month)[1]
            # Manage annual_inventory_day bigger than last_day
            annual_inventory_day = min(annual_inventory_day, max_day)
            next_inventory_date = today.replace(
                month=annual_inventory_month, day=annual_inventory_day)
            if next_inventory_date <= today:
                # Manage leap year with the february
                max_day = calendar.monthrange(today.year + 1, annual_inventory_month)[1]
                annual_inventory_day = min(annual_inventory_day, max_day)
                next_inventory_date = next_inventory_date.replace(
                    day=annual_inventory_day, year=today.year + 1)
        return next_inventory_date

    def should_bypass_reservation(self):
        self.ensure_one()
        return self.usage in ('supplier', 'customer', 'inventory', 'production') or self.scrap_location or (self.usage == 'transit' and not self.company_id)

    def _check_access_putaway(self):
        return self

    def _check_can_be_used(self, product, quantity=0, package=None, location_qty=0):
        """Check if product/package can be stored in the location. Quantity
        should in the default uom of product, it's only used when no package is
        specified."""
        self.ensure_one()
        if self.storage_category_id:
            # check if enough space
            if package and package.package_type_id:
                # check weight
                package_smls = self.env['stock.move.line'].search([('result_package_id', '=', package.id), ('state', 'not in', ['done', 'cancel'])])
                if self.storage_category_id.max_weight < self.forecast_weight + sum(package_smls.mapped(lambda sml: sml.quantity_product_uom * sml.product_id.weight)):
                    return False
                # check if enough space
                package_capacity = self.storage_category_id.package_capacity_ids.filtered(lambda pc: pc.package_type_id == package.package_type_id)
                if package_capacity and location_qty >= package_capacity.quantity:
                    return False
            else:
                # check weight
                if self.storage_category_id.max_weight < self.forecast_weight + product.weight * quantity:
                    return False
                product_capacity = self.storage_category_id.product_capacity_ids.filtered(lambda pc: pc.product_id == product)
                # To handle new line without quantity in order to avoid suggesting a location already full
                if product_capacity and location_qty >= product_capacity.quantity:
                    return False
                if product_capacity and quantity + location_qty > product_capacity.quantity:
                    return False
            positive_quant = self.quant_ids.filtered(lambda q: float_compare(q.quantity, 0, precision_rounding=q.product_id.uom_id.rounding) > 0)
            # check if only allow new product when empty
            if self.storage_category_id.allow_new_product == "empty" and positive_quant:
                return False
            # check if only allow same product
            if self.storage_category_id.allow_new_product == "same":
                # In case it's a package, `product` is not defined, so try to get
                # the package products from the context
                product = product or self._context.get('products')
                if (positive_quant and positive_quant.product_id != product) or len(product) > 1:
                    return False
                if self.env['stock.move.line'].search([
                    ('product_id', '!=', product.id),
                    ('state', 'not in', ('done', 'cancel')),
                    ('location_dest_id', '=', self.id),
                ], limit=1):
                    return False
        return True

class StockRoute(models.Model):
    _name = 'stock.route'
    _description = "Inventory Routes"
    _order = 'sequence'
    _check_company_auto = True

    name = fields.Char('Route', required=True, translate=True)
    active = fields.Boolean('Active', default=True, help="If the active field is set to False, it will allow you to hide the route without removing it.")
    sequence = fields.Integer('Sequence', default=0)
    rule_ids = fields.One2many('stock.rule', 'route_id', 'Rules', copy=True)
    product_selectable = fields.Boolean('Applicable on Product', default=True, help="When checked, the route will be selectable in the Inventory tab of the Product form.")
    product_categ_selectable = fields.Boolean('Applicable on Product Category', help="When checked, the route will be selectable on the Product Category.")
    warehouse_selectable = fields.Boolean('Applicable on Warehouse', help="When a warehouse is selected for this route, this route should be seen as the default route when products pass through this warehouse.")
    packaging_selectable = fields.Boolean('Applicable on Packaging', help="When checked, the route will be selectable on the Product Packaging.")
    supplied_wh_id = fields.Many2one('stock.warehouse', 'Supplied Warehouse')
    supplier_wh_id = fields.Many2one('stock.warehouse', 'Supplying Warehouse')
    company_id = fields.Many2one(
        'res.company', 'Company',
        default=lambda self: self.env.company, index=True,
        help='Leave this field empty if this route is shared between all companies')
    product_ids = fields.Many2many(
        'product.template', 'stock_route_product', 'route_id', 'product_id',
        'Products', copy=False, check_company=True)
    categ_ids = fields.Many2many('product.category', 'stock_route_categ', 'route_id', 'categ_id', 'Product Categories', copy=False)
    packaging_ids = fields.Many2many('product.packaging', 'stock_route_packaging', 'route_id', 'packaging_id', 'Packagings', copy=False, check_company=True)
    warehouse_domain_ids = fields.One2many('stock.warehouse', compute='_compute_warehouses')
    warehouse_ids = fields.Many2many(
        'stock.warehouse', 'stock_route_warehouse', 'route_id', 'warehouse_id',
        'Warehouses', copy=False, domain="[('id', 'in', warehouse_domain_ids)]")

    def copy(self, default=None):
        self.ensure_one()
        default = dict(default or {})
        if 'name' not in default:
            default['name'] = _("%s (copy)", self.name)
        return super().copy(default=default)

    @api.depends('company_id')
    def _compute_warehouses(self):
        for loc in self:
            domain = [('company_id', '=', loc.company_id.id)] if loc.company_id else []
            loc.warehouse_domain_ids = self.env['stock.warehouse'].search(domain)

    @api.onchange('company_id')
    def _onchange_company(self):
        if self.company_id:
            self.warehouse_ids = self.warehouse_ids.filtered(lambda w: w.company_id == self.company_id)

    @api.onchange('warehouse_selectable')
    def _onchange_warehouse_selectable(self):
        if not self.warehouse_selectable:
            self.warehouse_ids = [(5, 0, 0)]

    def toggle_active(self):
        for route in self:
            route.with_context(active_test=False).rule_ids.filtered(lambda ru: ru.active == route.active).toggle_active()
        super().toggle_active()


from rest_framework.viewsets import ModelViewSet
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from django_filters import rest_framework as filters
from django_filters.rest_framework import DjangoFilterBackend
from .models import Farm, FarmPlants
from .serializers import FarmListSerializer, FarmDetailSerializer, PlantFarmsSerializer
from .filters import FarmFilter

class UPickPagination(PageNumberPagination):
    page_size = 20
    page_size_query_param = 'page_size'
    max_page_size = 100

class FarmViewSet(ModelViewSet):
    http_method_names = ['get']
    pagination_class = UPickPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = FarmFilter

    def get_queryset(self):
        if self.action == 'list':
            # Adjust the queryset for the list view
            return Farm.objects.prefetch_related('working_hours', 'address').all()
        elif self.action == 'retrieve':
            # Adjust the queryset for the detail view
            return Farm.objects.prefetch_related(
                'address',
                'working_hours',
                'plants__plant',
                'plants__plant__category'
            )

    def get_serializer_class(self):
        if self.action == 'list':
            return FarmListSerializer
        elif self.action == 'retrieve':
            return FarmDetailSerializer

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)
        serializer = self.get_serializer(page, many=True)
        results_count = self.paginator.page.paginator.count if page is not None else 0
        results_per_page = len(serializer.data) if page is not None else 0
        info = {
            'count': results_count,
            'next': self.paginator.get_next_link(),
            'previous': self.paginator.get_previous_link(),
            'results_per_page': results_per_page
        }
        response_data = {
            'info': info,
            'results': serializer.data
        }
        return Response(response_data)

class PlantViewSet(ModelViewSet):
    pagination_class = UPickPagination

    http_method_names = ['get']
    queryset = FarmPlants.objects.prefetch_related('plant', 'plant__category','farm','farm__working_hours', 'farm__address').all()
    serializer_class = PlantFarmsSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['plant__category', 'farm', 'plant']

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)
        serializer = self.get_serializer(page, many=True)
        results_count = self.paginator.page.paginator.count if page is not None else 0
        results_per_page = len(serializer.data) if page is not None else 0
        info = {
            'count': results_count,
            'next': self.paginator.get_next_link(),
            'previous': self.paginator.get_previous_link(),
            'results_per_page': results_per_page
        }
        response_data = {
            'info': info,
            'results': serializer.data
        }
        return Response(response_data)


# Definition for singly-linked list.
class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def deleteNode(self, node):
        """
        :type node: ListNode
        :rtype: void Do not return anything, modify node in-place instead.
        """
        if node == None:
            return node

        if node.next == None:
            node = None

        node.val = node.next.val
        node.next = node.next.next

def createList():
    head = ListNode(0)
    cur = head
    for i in range(1, 10):
        cur.next = ListNode(i)
        cur = cur.next
    return head

def printList(head):
    cur = head
    while cur != None:
        print(cur.val, '-->', end='')
        cur = cur.next

    print('NULL')

if __name__ == "__main__":
    head = createList()
    printList(head)
    res = Solution().deleteNode(head)
    printList(res)


from flask import Flask, request, render_template

app = Flask(__name__)

strings = []

@app.route("/", methods=["GET", "POST"])
def obter_strings():
    if request.method == "POST":
        string = request.form["string"]
        strings.append(string)

    resultado = verificar(strings)
    return render_template("verifica.html", strings=strings, resultado=resultado)

def verificar(strings):
    for i in range(1, len(strings)):
        if strings[i] < strings[i-1]:
            return False
    return True

if __name__ == "__main__":
    app.run(debug=True)


from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from django.contrib.auth import get_user_model
from django.db import models
from django.db.models import Q
from model_utils import FieldTracker

from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey

from transactions.models import Transaction

import uuid

channel_layer = get_channel_layer()

User = get_user_model()

# Thread Manager -> Manages thread object operations
class ThreadManager(models.Manager):
    def by_user(self, user):
        qlookup = Q(first=user) | Q(second=user)
        qlookup2 = Q(first=user) & Q(second=user)
        qs = self.get_queryset().filter(qlookup).exclude(qlookup2).distinct()
        return qs

    def get_or_new(self, user, other_id):
        # get_or_create -> Finds existing thread or creates new one
        user_id = user.public_id
        if user_id == other_id:
            return None
        qlookup1 = Q(first__public_id=user_id) & Q(second__public_id=other_id)
        qlookup2 = Q(first__public_id=other_id) & Q(second__public_id=user_id)
        qs = self.get_queryset().filter(qlookup1 | qlookup2).distinct()
        if qs.count() == 1:
            return qs.first(), False
        elif qs.count() > 1:
            return qs.order_by("timestamp").first(), False
        else:
            try:
                user2 = User.objects.get(public_id=other_id)
            except User.DoesNotExist:
                return None, False
            if user != user2:
                obj = self.model(first=user, second=user2)
                obj.save()
                return obj, True
            return None, False

# Each thread consist of 2 users
class Thread(models.Model):
    public_id = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
    first = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="chat_thread_first"
    )
    second = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="chat_thread_second"
    )
    updated = models.DateTimeField(auto_now=True)
    timestamp = models.DateTimeField(auto_now_add=True)

    objects = ThreadManager()

    class Meta:
        unique_together = ["first", "second"]

    @property
    def room_group_name(self):
        return f"chat_{self.id}"

    def __str__(self):
        return f"{self.first} - {self.second} Thread - ID: ${self.pk}"

class InboxManager(models.Manager):
    def set_inbox(self, user, other_user, msg, read=False):
        inbox_object, created_1 = self.get_or_create(user=user, second=other_user)
        inbox_object.last_message = msg
        inbox_object.read = read
        inbox_object.last_message_from = user
        inbox_object.save()
        from .serializers import InboxSerializer

        ib1 = InboxSerializer(instance=inbox_object).data
        ib1["last_message_from"] = str(ib1["last_message_from"])
        async_to_sync(channel_layer.group_send)(
            f"inbox_{inbox_object.user.public_id}",
            {"type": "update_inbox", "content": ib1},
        )

        return None

    # Not being used
    def read_inbox(self, user, other_user):
        inbox = self.get_queryset().filter(user=user, second=other_user)
        if inbox.count() == 1:
            inbox_obj = inbox.first()
            inbox_obj.read = True
            inbox_obj.save()
            from .serializers import InboxSerializer

            inbox_data = InboxSerializer(instance=inbox_obj).data
            async_to_sync(channel_layer.group_send)(
                f"inbox_{inbox_obj.user.public_id}",
                {
                    "type": "update_inbox",
                    "content": {"type": "read_update", "data": inbox_data},
                },
            )

            return None

class Inbox(models.Model):
    public_id = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="inbox_user")
    second = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="inbox_second_user"
    )
    updated = models.DateTimeField(auto_now=True)
    timestamp = models.DateTimeField(auto_now_add=True)
    last_message = models.TextField(max_length=2048, blank=True, default="")
    last_message_from = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        related_name="last_message_user",
        blank=True,
        null=True,
    )
    read = models.BooleanField(default=False)

    tracker = FieldTracker()
    objects = InboxManager()

    class Meta:
        unique_together = ["user", "second"]
        verbose_name = "User Inbox"
        verbose_name_plural = "User Inbox"

    def __str__(self):
        return f"{self.user} - {self.second} Inbox - ID: {self.pk}"

class ChatMessage(models.Model):
    public_id = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
    thread = models.ForeignKey(Thread, null=True, blank=True, on_delete=models.SET_NULL)
    user = models.ForeignKey(
        User,
        verbose_name="sender",
        related_name="message_sender",
        on_delete=models.CASCADE,
    )
    receiver = models.ForeignKey(
        User,
        related_name="message_receiver",
        verbose_name="receiver",
        on_delete=models.CASCADE,
    )
    inbox = models.ManyToManyField(to=Inbox, blank=True)
    message = models.TextField(max_length=2048, blank=True, default="")
    timestamp = models.DateTimeField(auto_now_add=True)

    message_type = models.CharField(
        max_length=12,
        null=False,
        blank=False,
        choices=[
            ("text", "Text"),
            ("photo", "Photo"),
            ("free_video", "Free video"),
            ("paid_video", "Premium video"),
        ],
    )

    media_type = models.ForeignKey(
        ContentType,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        limit_choices_to={"model__in": ("photo", "video")},
    )
    media_id = models.PositiveIntegerField(null=True, blank=True)
    media_item = GenericForeignKey("media_type", "media_id")

    purchase_cost_currency = models.CharField(
        max_length=3, choices=Transaction.currency_choices, default="usd", blank=True
    )
    purchase_cost_amount = models.DecimalField(
        max_digits=100, decimal_places=50, default=0.00, blank=True
    )

    is_special_request = models.BooleanField(default=False)

    is_tip_message = models.BooleanField(default=False)
    tip_currency = models.CharField(
        max_length=3, choices=Transaction.currency_choices, default="usd", blank=True
    )
    tip_amount = models.DecimalField(
        max_digits=100, decimal_places=50, default=0.00, blank=True
    )

    class Meta:
        indexes = [
            models.Index(fields=["media_type", "media_id"]),
        ]


import time

table_name = 'category_manager'

key_category_id = 'category_id'
key_category_name = 'categoryName'
key_create_date = 'createDate'
key_track_date = 'trackDate'

model_schema = [
    {
        "name": key_category_id,
        "type": "varchar(100)",
        "rule": "PRIMARY KEY"
    }, {
        "name": key_category_name,
        "type": "varchar(100)"
    }, {
        "name": key_create_date,
        "type": "bigint"
    }, {
        "name": key_track_date,
        "type": "bigint"
    }
]

def create_category(category_id, category_name):
    return {
        key_category_id: category_id,
        key_category_name: category_name,
        key_create_date: int(time.time())
    }


#!/usr/local/bin/python3
"""
时间处理工具
"""
import sys
from os.path import abspath, join, dirname

sys.path.insert(0, join(abspath(dirname(__file__)), "../"))

import time
import datetime

from bson.objectid import ObjectId

from public.base import QueryHandlerAbstract
from public.base import QueryBase

Second = int

class TimeQueryHandlerAbstract(QueryHandlerAbstract):
    """
    时间查询处理器
    """

    def __init__(self) -> None:
        super().__init__()

        self.NAME_FORMAT = {
            "完整": "%Y-%m-%d %H:%M:%S",
            "中文": "%Y年%m月%d日 %H时%M分%S秒",
            "日期": "%Y-%m-%d",
            "时间": "%H:%M:%S",
        }

        self.WEEK_NAMES = ["一", "二", "三", "四", "五", "六", "天"]

    def get_timestamp_result(self, timestamp: Second) -> list:
        """
        获取时间戳的结果

        :param Second timestamp: 时间戳
        :return list: 结果
        """
        items = list()
        for name, _format in self.NAME_FORMAT.items():
            format_time = time.strftime(_format, time.localtime(timestamp))
            item = {"arg": format_time, "title": format_time, "subtitle": name, "icon": ""}
            items.append(item)

        date = datetime.datetime.fromtimestamp(timestamp)
        week_name = f"星期{self.WEEK_NAMES[date.weekday()]}"
        items.append({"arg": week_name, "title": week_name, "subtitle": "星期", "icon": ""})

        month_name = f"{date.month}月"
        items.append({"arg": month_name, "title": month_name, "subtitle": "月份", "icon": ""})

        return items

    def get_other_result(self, timestamp: Second) -> list:
        """
        获取格式化时间的结果

        :param Second timestamp: 时间戳
        :return list: 结果
        """
        items = list()
        items.append({"arg": timestamp, "title": timestamp, "subtitle": "时间戳", "icon": ""})
        return items

    def build_result(self, items: list) -> dict:
        """
        构建结果

        :param list items: 数据列表
        :return dict: 结果
        """
        return {"items": items}

    def format_time_to_timestamp(self, format_time: str) -> Second:
        """
        格式化时间转时间戳

        :param str format_time: 格式化时间
        :return Second: 时间戳
        """
        _format = None
        if "-" in format_time and ":" in format_time:
            _format = self.NAME_FORMAT["完整"]
        elif "-" in format_time:
            _format = self.NAME_FORMAT["日期"]
        elif ":" in format_time:
            _format = self.NAME_FORMAT["时间"]

        timestamp = None
        if _format:
            timestamp = time.mktime(time.strptime(format_time, _format))

        return timestamp

class TimestampQueryHandler(TimeQueryHandlerAbstract):
    """
    处理时间戳的处理器
    """

    def is_available(self, query) -> bool:
        """
        判断是否是时间戳

        :param str query: 查询数据
        :return bool: 是否是时间戳
        """
        if query.isdigit() and len(query) in [10, 13]:
            return True
        return False

    def get_result(self, query: str):
        timestamp = int(query[:10])
        items = self.get_timestamp_result(timestamp)
        result = self.build_result(items)
        return result

class FormatTimeQueryHandler(TimeQueryHandlerAbstract):
    """
    处理格式化时间的处理器
    """

    def is_available(self, query: str) -> bool:
        """
        判断是否是格式化时间

        :param str query: 查询数据
        :return bool: 是否是格式化时间
        """
        if "-" in query or ":" in query:
            return True
        return False

    def get_result(self, query: str) -> dict:
        format_time = query.strip()
        timestamp = self.format_time_to_timestamp(format_time)

        items = self.get_other_result(timestamp)
        _items = self.get_timestamp_result(timestamp)
        items.extend(_items)

        result = self.build_result(items)
        return result

class ObjectIdQueryHandler(TimeQueryHandlerAbstract):
    """
    处理 ObjectId 的处理器
    """

    def is_available(self, query: str) -> bool:
        """
        判断是否是 ObjectId

        :param str query: 查询数据
        :return bool: 是否是 ObjectId
        """
        if len(query) == 24:
            return True
        return False

    def get_result(self, query: str) -> dict:
        object_id = ObjectId(query)
        timestamp = object_id.generation_time.timestamp()

        items = self.get_other_result(timestamp)
        _items = self.get_timestamp_result(timestamp)
        items.extend(_items)

        result = self.build_result(items)
        return result

class DateNameQueryHandler(TimeQueryHandlerAbstract):
    """
    处理昨天、今天的处理器
    """

    def __init__(self) -> None:
        super().__init__()

        self.name_format_time = {
            "今天": lambda: time.strftime("%Y-%m-%d"),
            "明天": lambda: time.strftime("%Y-%m-%d", time.localtime(int(time.time()) + 86400)),
            "昨天": lambda: time.strftime("%Y-%m-%d", time.localtime(int(time.time()) - 86400)),
            "这周": lambda: time.strftime(
                "%Y-%m-%d", time.localtime(int(time.time()) - datetime.datetime.now().weekday() * 86400)
            ),
            "这个月": lambda: time.strftime("%Y-%m-01"),
        }

    def is_available(self, query: str) -> bool:
        """
        判断是符合

        :param str query: 查询数据
        :return bool: 是否是 ObjectId
        """
        if query in self.name_format_time.keys():
            return True
        return False

    def get_result(self, query: str) -> dict:
        format_time = self.name_format_time[query]()
        timestamp = self.format_time_to_timestamp(format_time)

        items = self.get_other_result(timestamp)
        _items = self.get_timestamp_result(timestamp)
        items.extend(_items)

        result = self.build_result(items)
        return result

def main():
    time_tools = QueryBase()
    time_tools.add_handler(TimestampQueryHandler())
    time_tools.add_handler(FormatTimeQueryHandler())
    time_tools.add_handler(ObjectIdQueryHandler())
    time_tools.add_handler(DateNameQueryHandler())

    time_tools.main()

if __name__ == "__main__":
    main()


import json
import math
import os
import re
import subprocess
import time
import urllib

import parsel
import requests

'''
    目标网址   ->    腾讯视频 ：https://www.youku.com/
    功能      ->    根据 地址 下载优酷视频
'''

headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36',
    'referer': 'https://www.bilibili.com'
}

# 获取当前目录绝对路径
current_path = os.path.dirname(os.path.abspath(__file__))
video_download_path = "E:/video/"

class BiLi:

    # 获取电视剧信息
    def get_video_info(self, url):
        header = {
            'cookie': 'cna=gAXaGUK+3w8CAXAUXTWZcdbb'
        }
        response = requests.get(url=url, headers=header)
        selector = parsel.Selector(response.text)

        init_data_str = selector.re('window.__INITIAL_DATA__ =(.*);</script>')
        init_data = json.loads(init_data_str[0].replace('undefined', '""'))
        # 获取视频基本信息
        extra_data = init_data['data']['data']['data']['extra']
        video_title = extra_data['showName']
        video_second_title = extra_data['showSubtitle']
        video_type = extra_data['showCategory']
        video_pic_url = extra_data['showImgV']
        video_description = init_data['data']['data']['nodes'][0]['nodes'][0]['nodes'][0]['data']['desc']

        # 获取列表信息
        end_stage = extra_data['episodeFinalStage']
        video_id = extra_data['videoId']
        show_id = extra_data['showId']
        videos = self.get_video_list(show_id, video_id, end_stage)

        return {
            'title': video_title,
            'secondTitle': video_second_title,
            'picUrl': video_pic_url,
            'description': video_description,
            'type': video_type,
            'videos': videos,
            'definitions': []
        }

    def custom_download(self, url_list):
        for url in url_list:
            headers['range'] = 'bytes=112268-296136'
            response = requests.get(url, headers=headers)
            # print(response.text)
            with open(video_download_path + 'test/' + 't1.m4s', 'ab') as video:
                video.write(response.content)
            video.close()

    def get_download_list(self):
        url = 'https://valipl10.cp31.ott.cibntv.net/65731D34B763671755732370E/03000900006299ACCC8BB780000000726D6C89-58A4-4C09-BEF6-3D5C3CBC1A73-11-54247245.m3u8?ccode=0502&duration=2721&expire=18000&psid=0234e02b87701ed20969e4b8acf2337941346&ups_client_netip=2471915a&ups_ts=1661926416&ups_userid=999830345&utid=gAXaGUK%2B3w8CAXAUXTWZcdbb&vid=XNTg1MjcwNjQwNA%3D%3D&vkey=Bd4e75e70fbed600cf783b52c26ee85ed&s=bbfdcd5525264a2eb8fd&iv=1&eo=0&t=8cb8d34768c724b&cug=1&fms=ce0126c0343c302c&tr=2706&le=958e1be54f19b23c5c4541e95c6e2412&ckt=5&m_onoff=0&rid=20000000CD33CFD64E89FBA1E4026417683056A402000000&type=mp4hd3v3&bc=2&dre=u151&si=573&dst=1&sm=1&operate_type=1&hotvt=1'
        res = requests.get(url)
        download_url_list = re.findall('\nhttp(.*)\n', res.content.decode("utf-8"))
        for index in range(len(download_url_list)):
            download_url_list[index] = 'http' + download_url_list[index]
        return download_url_list

b = BiLi()
if __name__ == '__main__':
    url_list = [
        'https://cn-ahhn-cm-01-04.bilivideo.com/upgcxcode/67/10/803181067/803181067-1-100023.m4s?e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M=&uipk=5&nbs=1&deadline=1662106534&gen=playurlv2&os=bcache&oi=0&trid=0000fe757c01c11a4109845f8a663b185e40u&mid=64743288&platform=pc&upsig=0f5692916a2536e9060b355979e983eb&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,mid,platform&cdnid=10101&bvc=vod&nettype=0&orderid=0,3&agrr=1&bw=28648&logo=80000000']
    b.custom_download(url_list)


class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        minprice = float('inf')
        maxprofit = 0
        for price in prices:
            minprice = min(minprice, price)
            maxprofit = max(maxprofit, price - minprice)
        return maxprofit

    def maxProfit_dp(self, prices: List[int]) -> int:
        n = len(prices)
        if n == 0:
            return 0  # 边界条件
        # dp[i]表示前i天的最大利润
        dp = [0] * n
        minprice = prices[0]

        for i in range(1, n):
            minprice = min(minprice, prices[i])
            dp[i] = max(dp[i - 1], prices[i] - minprice)

        return dp[-1]

121.买卖股票的最佳时机.py


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

from functools import partial
from xmlrpc.client import Fault

from odoo.tests import common, tagged
from odoo.tools.misc import mute_logger

@tagged('-at_install', 'post_install')
class TestError(common.HttpCase):
    def setUp(self):
        super(TestError, self).setUp()
        uid = self.ref("base.user_admin")
        self.rpc = partial(self.xmlrpc_object.execute, common.get_db_name(), uid, "admin")

        # Reset the admin's lang to avoid breaking tests due to admin not in English
        self.rpc("res.users", "write", [uid], {"lang": False})

    def test_01_create(self):
        """ Create: mandatory field not provided """
        self.rpc("test_rpc.model_b", "create", {"name": "B1"})
        try:
            with mute_logger("odoo.sql_db"):
                self.rpc("test_rpc.model_b", "create", {})
            raise
        except Exception as e:
            self.assertIn("The operation cannot be completed:", e.faultString)
            self.assertIn("Create/update: a mandatory field is not set.", e.faultString)
            self.assertIn(
                "Delete: another model requires the record being deleted. If possible, archive it instead.",
                e.faultString,
            )
            self.assertIn("Model: Model B (test_rpc.model_b)", e.faultString)
            self.assertIn("Field: Name (name)", e.faultString)

    def test_02_delete(self):
        """ Delete: NOT NULL and ON DELETE RESTRICT constraints """
        b1 = self.rpc("test_rpc.model_b", "create", {"name": "B1"})
        b2 = self.rpc("test_rpc.model_b", "create", {"name": "B2"})
        self.rpc("test_rpc.model_a", "create", {"name": "A1", "field_b1": b1, "field_b2": b2})

        try:
            with mute_logger("odoo.sql_db"):
                self.rpc("test_rpc.model_b", "unlink", b1)
            raise
        except Exception as e:
            self.assertIn("The operation cannot be completed:", e.faultString)
            self.assertIn(
                "another model requires the record being deleted. If possible, archive it instead.",
                e.faultString,
            )
            self.assertIn("Model: Model A (test_rpc.model_a)", e.faultString)
            self.assertIn("Constraint: test_rpc_model_a_field_b1_fkey", e.faultString)

        # Unlink b2 => ON DELETE RESTRICT constraint raises
        try:
            with mute_logger("odoo.sql_db"):
                self.rpc("test_rpc.model_b", "unlink", b2)
            raise
        except Exception as e:
            self.assertIn("The operation cannot be completed:", e.faultString)
            self.assertIn(
                " another model requires the record being deleted. If possible, archive it instead.",
                e.faultString,
            )
            self.assertIn("Model: Model A (test_rpc.model_a)", e.faultString)
            self.assertIn("Constraint: test_rpc_model_a_field_b2_fkey", e.faultString)

    def test_03_sql_constraint(self):
        with mute_logger("odoo.sql_db"):
            with self.assertRaisesRegex(Fault, r'The operation cannot be completed: The value must be positive'):
                self.rpc("test_rpc.model_b", "create", {"name": "B1", "value": -1})


import tensorflow as tf
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

def norm(x):
  return (x - train_stats['mean']) / train_stats['std']

def build_model_3(train_data):
    layers = tf.keras.layers
    model = tf.keras.Sequential([
        layers.Dense(64, activation=tf.nn.relu, input_shape=[len(train_data.keys())]),
        layers.Dense(64, activation=tf.nn.relu),
        layers.Dense(64, activation=tf.nn.relu),
        layers.Dense(2)
    ])

    optimizer = tf.keras.optimizers.RMSprop(0.001)
    model.compile(loss='mse', optimizer=optimizer, metrics=['mae', 'mse', 'accuracy'])
    return model

def build_model_6(train_data):
    layers = tf.keras.layers
    model = tf.keras.Sequential([
        layers.Dense(64, activation=tf.nn.relu, input_shape=[len(train_data.keys())]),
        layers.Dense(64, activation=tf.nn.relu),
        layers.Dense(64, activation=tf.nn.relu),
        layers.Dense(64, activation=tf.nn.relu),
        layers.Dense(64, activation=tf.nn.relu),
        layers.Dense(64, activation=tf.nn.relu),
        layers.Dense(2)
    ])

    optimizer = tf.keras.optimizers.RMSprop(0.001)
    model.compile(loss='mse', optimizer=optimizer, metrics=['mae', 'mse', 'accuracy'])
    return model

# def plot_history(hist):
#     # hist = pd.DataFrame(history.history)
#     # hist['epoch'] = history.epoch
#
#     plt.figure()
#     plt.xlabel('Epoch')
#     plt.ylabel('Mean Abs Error')
#     plt.plot(hist['epoch'], hist['mean_absolute_error'],
#              label='Train Error')
#     plt.plot(hist['epoch'], hist['val_mean_absolute_error'],
#              label='Val Error')
#     plt.legend()
#     plt.ylim([0, 5])
#
#     plt.figure()
#     plt.xlabel('Epoch')
#     plt.ylabel('Mean Square Error')
#     plt.plot(hist['epoch'], hist['mean_squared_error'],
#              label='Train Error')
#     plt.plot(hist['epoch'], hist['val_mean_squared_error'],
#              label='Val Error')
#     plt.legend()
#     plt.ylim([0, 20])

dir = "sensor_data/LCA_Real_Life_Highway__511 sec/LCA_Real-Life_Highway_1_Ford_Fiesta_1/"
file_data = dir + "i_s_ground_truth.csv"
file_label = dir + "a_ground_truth.csv"
data_cols = ["range", "azimuth", "dist_left", "velocity"]
label_cols = ["acceleration", "steering"]

train_data = pd.read_csv(file_data, names=data_cols,
                      na_values = "?", comment='\t',
                      sep=",", skipinitialspace=True)
train_label = pd.read_csv(file_label, names=label_cols,
                      na_values = "?", comment='\t',
                      sep=",", skipinitialspace=True)

data = train_data.copy()
label = train_label.copy()

train_stats = data.describe()
train_stats = train_stats.transpose()

normed_train_data = norm(data)

# sns.pairplot(data[data_cols], diag_kind="kde")
# plt.show()
print(normed_train_data)
print(label)

model = build_model_6(normed_train_data)
# model.summary()

saver = tf.train.Saver()

with tf.Session() as sess:
    history = model.fit(
      x = normed_train_data, y = label,
      epochs=2000, validation_split = 0.2, verbose=0,
    )
    hist = pd.DataFrame(history.history)
    hist['epoch'] = history.epoch
    print(hist)
    hist.to_csv(dir+"control_model_6_hist.csv")
    save_path = saver.save(sess, dir + "control_model_6.ckpt")


import math

import globvars
import warnings

from PySide2.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QGridLayout, QLabel, QDesktopWidget, QLineEdit, QDialogButtonBox, QPushButton, QMessageBox
from PySide2.QtGui import QGuiApplication
from PySide2.QtCore import Qt

class material:
    def __init__(self, globvar, nr):

        self.nr = nr
        self.material_type = None

    def give_material_type(self):
        return self.material_type

class concrete_mat(material):

    def __init__(self, globvar, nr, fcm = None):
        super().__init__(globvar, nr)

        self.fcm = globvar.concretes[globvar.fcm]

        self.material_type = globvar.material_type[0]
        self.predict_concrete_parameters()

    def predict_concrete_parameters(self):

        # fcm = mean compressive strength on cylinders [MPa]

        # characteristic value of compressive strength [MPa]
        fck = self.fcm-8.;
        # mean tensile strength [MPa], math.log = natural logarithm
        if (fck>50.):
            self.fctm = 2.12*math.log(1.+self.fcm/10.);
        else:
            self.fctm = 0.3*fck**(2./3.);

        # fracture energy [N/m]
        self.Gf = 73.*self.fcm**0.18;
        # initial modulus [MPa]
        self.Eci = 21.5e3*(self.fcm/10.)**(1./3.);
        # critical crack opening [m]
        self.wf = 4.444*self.Gf/self.fctm*1.e-6;
        # Poisson's ratio
        self.nu = 0.2;
        # eccentricity
        self.ecc = 0.525;
        # initial value of hardening variable
        self.kinit = 0.3;
        # hardening modulus
        self.Hp = 0.01;
        # dilation factor
        self.dilation = 0.85;
        # hardening parameter Ahard
        self.Ahard = 0.08;
        # hardening parameter Ahard
        self.Bhard = 0.003;
        # hardening parameter Ahard
        self.Chard = 2.;
        # hardening parameter Ahard
        self.Dhard = 1.e-6;
        # softening parameter
        self.Asoft = 15;
        # softening parameter for compression
        self.efc = 1.e-4;
        # type of softening (1=bilinear)
        # stype = 1;
        # softening parameter for tension
        self.wf1 = 0.15;
        # softening parameter for tension
        self.ft1 = 0.3;

    def update_concrete_strength(self, s):

        try:
            strength = float(s)
        except ValueError:

            warnings.warn("unsupported value, using fcm = 30 MPa")
            strength = 30.

        self.fcm = strength

class window_CDPM2(QWidget):

    def __init__(self, cdpm2):
        super().__init__()

        self.setWindowTitle("CDPM2 material parameters")

        param_length = 8

        label_fcm = QLabel("fcm = ")
        self.label_edit_fcm = QLabel(str(cdpm2.fcm))
        label_fcm_unit = QLabel("[MPa]")

        label_number = QLabel("Definition of material number: " + str(cdpm2.nr) )

        label_fctm = QLabel("fctm = ")
        self.line_edit_fctm = QLineEdit()
        self.line_edit_fctm.setMaxLength(param_length)
        self.line_edit_fctm.setText(str(cdpm2.fctm))
        label_fctm_unit = QLabel("[MPa]")

        label_Gf = QLabel("Gf = ")
        self.line_edit_Gf = QLineEdit()
        self.line_edit_Gf.setMaxLength(param_length)
        self.line_edit_Gf.setText(str(cdpm2.Gf))
        label_Gf_unit = QLabel("[N/m]")

        label_Eci = QLabel("Eci = ")
        self.line_edit_Eci = QLineEdit()
        self.line_edit_Eci.setMaxLength(param_length)
        self.line_edit_Eci.setText(str(cdpm2.Eci))
        label_Eci_unit = QLabel("[MPa]")

        label_nu = QLabel("nu = ")
        self.line_edit_nu = QLineEdit()
        self.line_edit_nu.setMaxLength(param_length)
        self.line_edit_nu.setText(str(cdpm2.nu))
        label_nu_unit = QLabel("[-]")

        label_wf = QLabel("wf = ")
        self.line_edit_wf = QLineEdit()
        self.line_edit_wf.setMaxLength(param_length)
        self.line_edit_wf.setText(str(cdpm2.wf))
        label_wf_unit = QLabel("[m]")

        label_ecc = QLabel("ecc = ")
        self.line_edit_ecc = QLineEdit()
        self.line_edit_ecc.setMaxLength(param_length)
        self.line_edit_ecc.setText(str(cdpm2.ecc))
        label_ecc_unit = QLabel("[m]")

        label_kinit = QLabel("kinit = ")
        self.line_edit_kinit = QLineEdit()
        self.line_edit_kinit.setMaxLength(param_length)
        self.line_edit_kinit.setText(str(cdpm2.kinit))
        label_kinit_unit = QLabel("[-]")

        label_Hp = QLabel("Hp = ")
        self.line_edit_Hp = QLineEdit()
        self.line_edit_Hp.setMaxLength(param_length)
        self.line_edit_Hp.setText(str(cdpm2.Hp))
        label_Hp_unit = QLabel("[-]")

        label_dilation = QLabel("dilation = ")
        self.line_edit_dilation = QLineEdit()
        self.line_edit_dilation.setMaxLength(param_length)
        self.line_edit_dilation.setText(str(cdpm2.dilation))
        label_dilation_unit = QLabel("[-]")

        label_Ahard = QLabel("Ahard = ")
        self.line_edit_Ahard = QLineEdit()
        self.line_edit_Ahard.setMaxLength(param_length)
        self.line_edit_Ahard.setText(str(cdpm2.Ahard))
        label_Ahard_unit = QLabel("[-]")

        label_Bhard = QLabel("Bhard = ")
        self.line_edit_Bhard = QLineEdit()
        self.line_edit_Bhard.setMaxLength(param_length)
        self.line_edit_Bhard.setText(str(cdpm2.Bhard))
        label_Bhard_unit = QLabel("[-]")

        label_Chard = QLabel("Chard = ")
        self.line_edit_Chard = QLineEdit()
        self.line_edit_Chard.setMaxLength(param_length)
        self.line_edit_Chard.setText(str(cdpm2.Chard))
        label_Chard_unit = QLabel("[-]")

        label_Dhard = QLabel("Dhard = ")
        self.line_edit_Dhard = QLineEdit()
        self.line_edit_Dhard.setMaxLength(param_length)
        self.line_edit_Dhard.setText(str(cdpm2.Dhard))
        label_Dhard_unit = QLabel("[-]")

        label_Asoft = QLabel("Asoft = ")
        self.line_edit_Asoft = QLineEdit()
        self.line_edit_Asoft.setMaxLength(param_length)
        self.line_edit_Asoft.setText(str(cdpm2.Asoft))
        label_Asoft_unit = QLabel("[-]")

        label_efc = QLabel("efc = ")
        self.line_edit_efc = QLineEdit()
        self.line_edit_efc.setMaxLength(param_length)
        self.line_edit_efc.setText(str(cdpm2.efc))
        label_efc_unit = QLabel("[-]")

        label_wf1 = QLabel("wf1 = ")
        self.line_edit_wf1 = QLineEdit()
        self.line_edit_wf1.setMaxLength(param_length)
        self.line_edit_wf1.setText(str(cdpm2.wf1))
        label_wf1_unit = QLabel("[-]")

        label_ft1 = QLabel("ft1 = ")
        self.line_edit_ft1 = QLineEdit()
        self.line_edit_ft1.setMaxLength(param_length)
        self.line_edit_ft1.setText(str(cdpm2.ft1))
        label_ft1_unit = QLabel("[-]")

        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Close)
        self.buttonBox.accepted.connect(lambda: self.update_cdpm2_user_parameters(cdpm2) )
        self.buttonBox.accepted.connect(self.close)
        self.buttonBox.rejected.connect(self.close)

        cdpm2_layout = QGridLayout()

        row = 0
        cdpm2_layout.addWidget(label_number, row, 0, 1, 3)

        row += 1
        cdpm2_layout.addWidget(label_fcm, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.label_edit_fcm, row, 1)
        cdpm2_layout.addWidget(label_fcm_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_fctm, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_fctm, row, 1)
        cdpm2_layout.addWidget(label_fctm_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_Gf, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_Gf, row, 1)
        cdpm2_layout.addWidget(label_Gf_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_Eci, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_Eci, row, 1)
        cdpm2_layout.addWidget(label_Eci_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_nu, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_nu, row, 1)
        cdpm2_layout.addWidget(label_nu_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_wf, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_wf, row, 1)
        cdpm2_layout.addWidget(label_wf_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_ecc, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_ecc, row, 1)
        cdpm2_layout.addWidget(label_ecc_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_kinit, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_kinit, row, 1)
        cdpm2_layout.addWidget(label_kinit_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_Hp, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_Hp, row, 1)
        cdpm2_layout.addWidget(label_Hp_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_dilation, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_dilation, row, 1)
        cdpm2_layout.addWidget(label_dilation_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_Ahard, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_Ahard, row, 1)
        cdpm2_layout.addWidget(label_Ahard_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_Bhard, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_Bhard, row, 1)
        cdpm2_layout.addWidget(label_Bhard_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_Chard, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_Chard, row, 1)
        cdpm2_layout.addWidget(label_Chard_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_Dhard, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_Dhard, row, 1)
        cdpm2_layout.addWidget(label_Dhard_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_Asoft, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_Asoft, row, 1)
        cdpm2_layout.addWidget(label_Asoft_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_efc, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_efc, row, 1)
        cdpm2_layout.addWidget(label_efc_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_wf1, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_wf1, row, 1)
        cdpm2_layout.addWidget(label_wf1_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(label_ft1, row, 0, 1, 1, Qt.AlignRight)
        cdpm2_layout.addWidget(self.line_edit_ft1, row, 1)
        cdpm2_layout.addWidget(label_ft1_unit, row, 2)

        row += 1
        cdpm2_layout.addWidget(self.buttonBox, row, 0, 1, 3)

        self.setLayout(cdpm2_layout)

    def check_float_value(self, value):
        try:
            test = float(value)
            return True
        except:
            QMessageBox.warning(self, "Warning", "unsupported value:" + str(value), buttons=QMessageBox.Ok, defaultButton=QMessageBox.Ok)
            return False

    def update_text_fields(self, cdpm2):
        #self.line_edit_fctm.setText(str(cdpm2.fctm))
        self.line_edit_Gf.setText(str(cdpm2.Gf))
        self.line_edit_Eci.setText(str(cdpm2.Eci))
        self.line_edit_wf.setText(str(cdpm2.wf))
        self.line_edit_nu.setText(str(cdpm2.nu))
        self.line_edit_ecc.setText(str(cdpm2.ecc))
        self.line_edit_kinit.setText(str(cdpm2.kinit))
        self.line_edit_Hp.setText(str(cdpm2.Hp))
        self.line_edit_dilation.setText(str(cdpm2.dilation))
        self.line_edit_Ahard.setText(str(cdpm2.Ahard))
        self.line_edit_Bhard.setText(str(cdpm2.Bhard))
        self.line_edit_Chard.setText(str(cdpm2.Chard))
        self.line_edit_Dhard.setText(str(cdpm2.Dhard))
        self.line_edit_Asoft.setText(str(cdpm2.Asoft))
        self.line_edit_efc.setText(str(cdpm2.efc))
        self.line_edit_wf1.setText(str(cdpm2.wf1))
        self.line_edit_ft1.setText(str(cdpm2.ft1))

    def update_cdpm2_user_parameters (self, cdpm2):

        try:
            cdpm2.fctm = float( self.line_edit_fctm.text() )
            cdpm2.Gf = float( self.line_edit_Gf.text() )
            cdpm2.Eci = float( self.line_edit_Eci.text() )
            cdpm2.wf = float( self.line_edit_wf.text() )
            cdpm2.nu = float( self.line_edit_nu.text() )
            cdpm2.ecc = float( self.line_edit_ecc.text() )
            cdpm2.kinit = float( self.line_edit_kinit.text() )
            cdpm2.Hp = float( self.line_edit_Hp.text() )
            cdpm2.dilation = float( self.line_edit_dilation.text() )
            cdpm2.Ahard= float( self.line_edit_Ahard.text() )
            cdpm2.Bhard = float( self.line_edit_Bhard.text() )
            cdpm2.Chard = float( self.line_edit_Chard.text() )
            cdpm2.Dhard = float( self.line_edit_Dhard.text() )
            cdpm2.Asoft = float( self.line_edit_Asoft.text() )
            cdpm2.efc = float( self.line_edit_efc.text() )
            cdpm2.wf1 = float( self.line_edit_wf1.text() )
            cdpm2.ft1 = float( self.line_edit_ft1.text() )

        except ValueError:
            warnings.warn("incorrectly defined user value" )
            return

class rebar_mat(material):

    def __init__(self, globvar, nr, mat):
        super().__init__(globvar, nr)

        self.material_type = globvar.material_type[1]
        self.predict_steel_parameters(globvar,mat)
        self.sig_0 = 500;

    def predict_steel_parameters(self, globvar, mat = None):
        # TODO

        if ( mat == globvar.rebarmat[0]):
            self.E = 210.e3
            self.H = 0.;
            self.omega_c = 0.;
            self.a = 0.;

        elif ( mat == globvar.rebarmat[1]):
            self.E = 210.e3
            self.H = 7.5e3;
            self.omega_c = 1.;
            self.a = 6.;

        elif ( mat == globvar.rebarmat[2]):
            self.E = 210.e3
            self.H = 8.2e3;
            self.omega_c = 1.;
            self.a = 6.;

        elif ( mat == globvar.rebarmat[3]):
            self.sig_0 = 500;
            self.H = 9.e3;
            self.omega_c = 1.;
            self.a = 13.;

        elif ( mat == globvar.rebarmat[4]):
            self.E = 210.e3
            self.H = 5.5e3;
            self.omega_c = 1.;
            self.a = 7.25;

        elif ( mat == globvar.rebarmat[5]):
            self.E = 210.e3
            self.H = 5.5e3;
            self.omega_c = 1.;
            self.a = 6.15;

        elif ( mat == globvar.rebarmat[6]):
            self.E = 210.e3
            self.H = 0.;
            self.omega_c = 0.;
            self.a = 0.;

        else:
            warnings.warn("unknown material definition, using fy = 500 MPa")
            self.E = 210.e3
            self.sig_0 = 500;
            self.H = 0.;
            self.omega_c = 0.;
            self.a = 0.;

class tendon_mat(material):
    # TODO

    def __init__(self, globvar, nr, mat):
        super().__init__(globvar, nr)

        self.material_type = globvar.material_type[2]
        self.predict_steel_parameters(mat)

    def predict_steel_parameters(self, mat = None):

        if ( mat == globvar.tendonmat[0]):
            self.E = 200.e3
            self.sig_0 = 1800.;
            self.H = 0.;
            self.omega_c = 0.;
            self.a = 0.;

        else:
            warnings.warn("unknown material definition, using fy = 1800 MPa")
            self.E = 200.e3
            self.sig_0 = 1800.;
            self.H = 0.;
            self.omega_c = 0.;
            self.a = 0.;

class window_Mises(QWidget):

    def __init__(self, mises):
        super().__init__()

        self.setWindowTitle("Mises material parameters")

        param_length = 8

        label_number = QLabel("Definition of material number: " + str(mises.nr) )

        label_sig_0 = QLabel("sig_0 = ")
        self.label_edit_sig_0 = QLabel(str(mises.sig_0))
        label_sig_0_unit = QLabel("[MPa]")

        label_E = QLabel("E = ")
        self.line_edit_E = QLineEdit()
        self.line_edit_E.setMaxLength(param_length)
        self.line_edit_E.setText(str(mises.E))
        label_E_unit = QLabel("[MPa]")

        label_H = QLabel("H = ")
        self.line_edit_H = QLineEdit()
        self.line_edit_H.setMaxLength(param_length)
        self.line_edit_H.setText(str(mises.H))
        label_H_unit = QLabel("[MPa]")

        label_omega_c = QLabel("omega_c = ")
        self.line_edit_omega_c = QLineEdit()
        self.line_edit_omega_c.setMaxLength(param_length)
        self.line_edit_omega_c.setText(str(mises.omega_c))
        label_omega_c_unit = QLabel("[-]")

        label_a = QLabel("a = ")
        self.line_edit_a = QLineEdit()
        self.line_edit_a.setMaxLength(param_length)
        self.line_edit_a.setText(str(mises.a))
        label_a_unit = QLabel("[-]")

        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Close)
        self.buttonBox.accepted.connect(lambda: self.update_mises_user_parameters(mises) )
        self.buttonBox.accepted.connect(self.close)
        self.buttonBox.rejected.connect(self.close)

        mises_layout = QGridLayout()

        row = 0
        mises_layout.addWidget(label_number, row, 0, 1, 3)

        row += 1
        mises_layout.addWidget(label_sig_0, row, 0, 1, 1, Qt.AlignRight)
        mises_layout.addWidget(self.label_edit_sig_0, row, 1)
        mises_layout.addWidget(label_sig_0_unit, row, 2)

        row += 1
        mises_layout.addWidget(label_E, row, 0, 1, 1, Qt.AlignRight)
        mises_layout.addWidget(self.line_edit_E, row, 1)
        mises_layout.addWidget(label_E_unit, row, 2)

        row += 1
        mises_layout.addWidget(label_H, row, 0, 1, 1, Qt.AlignRight)
        mises_layout.addWidget(self.line_edit_H, row, 1)
        mises_layout.addWidget(label_H_unit, row, 2)

        row += 1
        mises_layout.addWidget(label_omega_c, row, 0, 1, 1, Qt.AlignRight)
        mises_layout.addWidget(self.line_edit_omega_c, row, 1)
        mises_layout.addWidget(label_omega_c_unit, row, 2)

        row += 1
        mises_layout.addWidget(label_a, row, 0, 1, 1, Qt.AlignRight)
        mises_layout.addWidget(self.line_edit_a, row, 1)
        mises_layout.addWidget(label_a_unit, row, 2)

        row += 1
        mises_layout.addWidget(self.buttonBox, row, 0, 1, 3)

        self.setLayout(mises_layout)

    def update_mises_user_parameters (self, mises):

        try:
            mises.E = float( self.line_edit_E.text() )
            mises.H = float( self.line_edit_H.text() )
            mises.omega_c = float( self.line_edit_omega_c.text() )
            mises.a = float( self.line_edit_a.text() )

        except ValueError:
            warnings.warn("incorrectly defined user value" )
            return


"""
Given an integer array nums, find a contiguous non-empty subarray within the array that has the largest product, and return the product.

It is guaranteed that the answer will fit in a 32-bit integer.

A subarray is a contiguous subsequence of the array.
"""

def max_product_subarray(nums):
    current_max, current_min = nums[0], nums[0]
    max_prod = nums[0]
    for i in range(1, len(nums)):
        temp = current_max * nums[i]
        current_max = max(nums[i], nums[i] * current_max, nums[i] * current_min)
        current_min = min(nums[i], temp, nums[i] * current_min)
        max_prod = max(max_prod, current_min, current_max)

    return max_prod

if __name__ == "__main__":
    nums = [2, 3, -2, 4]
    print(max_product_subarray(nums))


from pelican import signals
from datetime import datetime, timedelta
import logging

log = logging.getLogger(__name__)

def timedelta_duration(generator):
    """
    Replace `duration` article properties in '%H:%M' format with
    timedelta objects. Also add `end_date` as `date` + `duration`.
    """
    for article in generator.articles:
        if hasattr(article, 'duration'):
            log.debug('Event {} has duration: {}'.format(article.get_relative_source_path(), article.duration))
            time = datetime.strptime(article.duration, '%H:%M')
            article.duration = timedelta(hours=time.hour, minutes=time.minute)
            article.end_date = article.date + article.duration

def register():
    signals.article_generator_finalized.connect(timedelta_duration)


#******************************************************************************
#  This is a model for the sodoku.py board state
#  Text explain model
#
#
#
#
#
#******************************************************************************
import box

class board:
    def __init__(self) -> None:
        self.boxList = list()
        self.solved = False

    def addByString(self, sudokuString):
        # sudokuList = sudokuString.split()
        sudokuList = [num for num in sudokuString]
        self.boxList.append(box(sudokuList))

    def addByBox(self, aBox):
        self.boxList.append(aBox)

    def __str__(self) -> str:
        completeList = list()
        i = -1
        for box in self.boxList:
            i +=1
            tempStr = str(box)
            tempList = [tempStr[index : index + 3] for index in range(0, len(tempStr), 3)]

            completeList[i] = tempList[0]
            completeList[i+3] = tempList[1]
            completeList[i+6] = tempList[2]

            if  i == 2:
                i = 9
            if i == 11:
                i = 18
            return "".join(completeList)