"""Class for all Universal Embedding project classification models."""

import functools
from typing import Dict, Optional, Tuple, Union

from flax.training import common_utils
import jax
import jax.numpy as jnp
import ml_collections
from scenic.model_lib.base_models import base_model
from scenic.model_lib.base_models import model_utils
from scenic.model_lib.base_models import multilabel_classification_model

def _transform_logits(
    logits,
    one_hot,
    loss_config,
):
  '''
  Transformation of the logits for different softmax margin losses.
  Transform type can be one of : [arcface, normface, cosface].
  '''

  if loss_config.transform_logits_type == "arcface":

    theta_yi = jax.lax.acos(logits * one_hot)

    transformed_logits = jax.lax.cos(
        theta_yi + loss_config.m
    ) * one_hot + logits * (1 - one_hot)

  elif loss_config.transform_logits_type == "cosface":
    transformed_logits = (logits - loss_config.m) * one_hot + logits * (1 - one_hot)

  elif loss_config.transform_logits_type == "normface":
    transformed_logits = logits

  transformed_logits *= loss_config.scale

  return transformed_logits

def classification_metrics_function(
    logits: jnp.array,
    batch: base_model.Batch,
    loss_config: ml_collections.ConfigDict,
    target_is_multihot: bool = False,
    axis_name: Union[str, Tuple[str, ...]] = 'batch',
    classifier = "separate",
) -> Dict[str, Tuple[float, int]]:
  """Calculates metrics for the multi-label classification task.

  Currently we assume each metric_fn has the API:
    ```metric_fn(logits, targets, weights)```
  and returns an array of shape [batch_size]. We also assume that to compute
  the aggregate metric, one should sum across all batches, then divide by the
  total samples seen. In this way we currently only support metrics of the 1/N
  sum f(inputs, targets). Note, the caller is responsible for dividing by
  the normalizer when computing the mean of each metric.

  Args:
   logits: Output of model in shape [batch, length, num_classes].
   batch: Batch of data that has 'label' and optionally 'batch_mask'.
   loss_config: the configuration for the loss.
   target_is_multihot: If the target is a multi-hot vector.
   axis_name: List of axes on which we run the pmsum.

  Returns:
    A dict of metrics, in which keys are metrics name and values are tuples of
    (metric, normalizer).
  """

  if target_is_multihot:
    multihot_target = batch['label']
  else:
    # This is to support running a multi-label classification model on
    # single-label classification tasks:
    multihot_target = common_utils.onehot(batch['label'], logits.shape[-1])

  transformed_logits = _transform_logits(logits, multihot_target, loss_config)

  weights = batch.get('batch_mask')

  if classifier == "separate":
    #because they will be fed to softmax, make the values that you dont want to use
    #close to -inf, so they disappear and do not affect the loss
    transformed_logits = jnp.where(batch["domain_mask"],transformed_logits,jnp.finfo('float32').min)

  # This psum is required to correctly evaluate with multihost. Only host 0
  # will report the metrics, so we must aggregate across all hosts. The psum
  # will map an array of shape [n_global_devices, batch_size] -> [batch_size]
  # by summing across the devices dimension. The outer sum then sums across the
  # batch dim. The result is then we have summed across all samples in the
  # sharded batch.

  #logits for prec@1, transformed logits for loss
  evaluated_metrics = {

      'prec@1': model_utils.psum_metric_normalizer(
          (
              model_utils.weighted_top_one_correctly_classified(
                  logits, multihot_target, weights
              ),
              model_utils.num_examples(logits, multihot_target, weights),
          ),
          axis_name=axis_name,
      ),

      #the loss is masked if we use domain masks
      'loss': model_utils.psum_metric_normalizer(
          (
              model_utils.weighted_unnormalized_softmax_cross_entropy(
                  transformed_logits, multihot_target, weights
              ),
              model_utils.num_examples(
                  transformed_logits, multihot_target, weights
              ),
          ),
          axis_name=axis_name,
      ),
  }

  return evaluated_metrics

class UniversalEmbeddingClassificationModel(
    multilabel_classification_model.MultiLabelClassificationModel
):
  """Defines commonalities between all classification models.

  A model is class with three members: get_metrics_fn, loss_fn, & a flax_model.
  get_metrics_fn returns a callable function, metric_fn, that calculates the
  metrics and returns a dictionary. The metric function computes f(x_i, y_i) on
  a minibatch, it has API: ```metric_fn(logits, label, weights).``` The trainer
  will then aggregate and compute the mean across all samples evaluated. loss_fn
  is a function of API loss = loss_fn(logits, batch, model_params=None). This
  model class defines a softmax_cross_entropy_loss with weight decay, where the
  weight decay factor is determined by config.l2_decay_factor. flax_model is
  returned from the build_flax_model function. A typical usage pattern will be:
  ``` model_cls =
  model_lib.models.get_model_cls('fully_connected_classification') model =
  model_cls(config, dataset.meta_data) flax_model = model.build_flax_model
  dummy_input = jnp.zeros(input_shape, model_input_dtype) model_state, params =
  flax_model.init(

      rng, dummy_input, train=False).pop('params')
  ```
  And this is how to call the model:
  variables = {'params': params, **model_state}
  logits, new_model_state = flax_model.apply(variables, inputs, ...)
  ```
  """

  def get_metrics_fn(self, split: Optional[str] = None) -> base_model.MetricFn:
    """Returns a callable metric function for the model.

    Args:
      split: The split for which we calculate the metrics. It should be one of
        the ['train',  'validation', 'test'].
    Returns: A metric function with the following API: ```metrics_fn(logits,
      batch)```
    """
    del split  # For all splits, we return the same metric functions.
    return functools.partial(
        classification_metrics_function,
        target_is_multihot=self.dataset_meta_data.get(
            'target_is_onehot', False
        ),
        loss_config=self.config.loss,
    )

  def loss_function(
      self,
      logits: jnp.ndarray,
      batch: base_model.Batch,
      model_params: Optional[jnp.array] = None,
      classifier = "separate",
  ) -> float:
    """Returns the softmax loss.

    Args:
      logits: Output of model in shape [batch, length, num_classes].
      batch: Batch of data that has 'label' and optionally 'batch_mask'.
      model_params: Parameters of the model, for optionally applying
        regularization.

    Returns:
      Total loss.
    """

    # logits are cosine similarities at this point
    one_hot_targets = common_utils.onehot(batch['label'], logits.shape[-1])

    #transform based on type of softmax margin loss
    transformed_logits = _transform_logits(logits, one_hot_targets, self.config.loss)

    if classifier == "separate":

      transformed_masked_logits = jnp.where(batch["domain_mask"],transformed_logits,jnp.finfo('float32').min)
      sof_ce_loss = model_utils.weighted_softmax_cross_entropy(
          transformed_masked_logits,
          one_hot_targets,
          label_smoothing=self.config.get('label_smoothing'),
      )

      return sof_ce_loss

    elif classifier == "joint":

      sof_ce_loss = model_utils.weighted_softmax_cross_entropy(
          transformed_logits,
          one_hot_targets,
          label_smoothing=self.config.get('label_smoothing'),
      )

      return sof_ce_loss


# -*- coding: utf-8 -*-
import scrapy
import pickle
from bs4 import BeautifulSoup
from airlinescraper.items import PriceItem
import json
import re
import logging

# Guide:
# 0.
#    This is built on the scrapy framework. See below for explanation of the bug.
#    Other than that, works as expected.
#    The server may at times block the ip adress for a period of time if the requests
#    exceeds a certain number.
#
#
# 1. Bug : (On the scrapy version)
#          Sometimes, we end up with an empty page with a 200 code. Then it leads to to
#          wrong prices for subsequent request (somehow the prices are for another origin/dest?)
#          Are these two phenomenon related? Seems to be...
#
#   Solution: Use a custom script instead of relying on the scrapy framework.
#             Tried - Turning off cookies, turning off concurrent downloads, increasing download delay
#
#
# 2. For every requests, it returns 18 days worth of prices. So segment the dates into 18 days.
#
# 4. This program requires the use of a form payload .

class JetstarSpider(scrapy.Spider):
    VIEWSTATE = '''/wEPDwUBMGQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFJ01lbWJlckxvZ2luU2VhcmNoVmlldyRtZW1iZXJfUmVtZW1iZXJtZaXQj/rtlZ1hPS0zPQj+skvkM9qtml4xeXxQQ8y8k6xx'''
    name = 'jetstar'
    url_main = "https://book.jetstar.com"
    #URL to hit if we want to do the next page
    #url_next = "https://book.jetstar.com/CalendarSelect.aspx"
    dates = ['25/08/2018']
    #,'25/08/2018','10/09/2018','25/09/2018','10/10/2018','25/10/2018','10/11/2018','25/11/2018','10/12/2018','25/12/2018']

    # The origin_destination list is a tuple of two lists, the origin and destination respectively.
    # origin_destination_list = (['Singapore (SIN)'],["Nha Trang (CXR)","Da Nang (DAD)","Da Lat (DLI)","Hanoi (HAN)"])
    origin_destination_list = (['Singapore (SIN)'],["Phnom Penh (PNH)","Siem Reap (REP)","Jakarta (CGK)","Bali (Denpasar) (DPS)",
               "Medan - Kualanamu  (KNO)","Pekanbaru (PKU)","Palembang (PLM)","Surabaya (SUB)",
               "Kuala Lumpur (KUL)","Penang (PEN)","Yangon (RGN)","Clark (CRK)",
               "Manila (MNL)","Bangkok (BKK)","Hat Yai (HDY)","Phuket (HKT)",
               "Nha Trang (CXR)","Da Nang (DAD)","Da Lat (DLI)","Hanoi (HAN)",
               "Hai Phong (HPH)","Hue (HUI)","Phu Quoc (PQC)","Pleiku (PXU)",
               "Ho Chi Minh City (SGN)","Chu Lai (VCL)","Vinh (VII)"])

    def start_requests(self):
        """
        Ensure that the form (a dictionary object) that is required to make the POST request is available
        Returns all the formrequest that will be made
        """
        with open('post_form_jetstar.p','rb') as fp:
            form_payload = pickle.load(fp)
        #Nice piece of list comprehension generates all the combination of dates, origins and destination
        #for all sets of origin -> destination and destination -> origin
        payload_list = [self._format_payload(form_payload,origin=a,destination=b,date=d)
                            for d in self.dates
                                for i in range(2)
                                    for a in self.origin_destination_list[i]
                                        for b in self.origin_destination_list[1-i]]

        for p in payload_list:
             yield scrapy.FormRequest(url=self.url_main,formdata=p[0],dont_filter=True,callback=self.parse,meta={'origin':p[1],'destination':p[2],'payload':p[0]})

    def _format_payload(self,payload,origin,destination,date):
        """
        Sets the origin, destination and date for the payload
        Returns a tuple (*payload with settings*, *origin(abv.)*, *destination(abv.)*)
        """
        payload['__VIEWSTATE'] = self.VIEWSTATE
        payload['ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketOrigin1'] = origin
        payload['ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketDestination1'] = destination
        payload['ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDepartureDate1'] = date
        #Need to give a copy of the payload, otherwise it will reference the object which will be further modified...
        return (dict(payload),re.findall(r'\((.*?)\)',origin)[-1],re.findall(r'\((.*?)\)',destination)[-1])

    def parse(self, response):
        """
        Returns an item
        """
        soup = BeautifulSoup(response.text,'lxml')
        try:
            currency = soup.find('div',class_='legend-currency').text.split(':')[1].strip()
            li_list = soup.find('div',class_='low-fare-selector').findAll('li')
            for li in li_list:
                jitem = PriceItem()
                jitem['provider'] = self.name
                jitem['date'] = li['data-date']
                jitem['price'] = li['data-price']
                jitem['currency'] = currency
                jitem['origin'] = response.meta['origin']
                jitem['destination'] = response.meta['destination']
                yield jitem
        except AttributeError as e:
            print(e)
            print(response.meta['origin'] + ' to ' + response.meta['destination'])
            logging.error('NoneType issue for ' + response.meta['origin'] + ' to ' + response.meta['destination'])


#imports
from grp import struct_group
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
from regex import P
import xarray as xr
import h5py
import netCDF4
#import pdb

 #single file
#dataDIR = './OMI-Aura_L2-OMNO2_2004m1001t1810-o01143_v003-2019m0814t172958.he5'
#'/Users/madisonhonore/Documents/VS code/OMI-Aura_L2-OMNO2_2004m1001t1810-o01143_v003-2019m0814t172958-HDFEOS-SWATHS-ColumnAmountNO2-Data_Fields-AmfTropClear.nc'
#replace the above with the location of your OMI data
#DS = np.fromfile('./OMI-Aura_L2-OMNO2_2004m1001t1810-o01143_v003-2019m0814t172958.he5', dtype=float)

#f1= h5py.File('./OMI-Aura_L2-OMNO2_2004m1001t1810-o01143_v003-2019m0814t172958.he5', 'r')
#df= pd.read_hdf('./OMI-Aura_L2-OMNO2_2004m1001t1810-o01143_v003-2019m0814t172958.he5')

#datasetNames= [n for n in f1.keys()]
#for n in datasetNames:
    #print(n)

#pdb.set_trace()

#hf= h5py.File('./OMI-Aura_L2-OMNO2_2004m1001t1810-o01143_v003-2019m0814t172958.he5', 'r')
#print(hf.keys())
#n1= hf.get('HDFEOS INFORMATION')
#n1
#n1= np.array(n1)
#n1.shape
#print(np.array(n1))

#above was test code to get the names of groups in the .he5 file

#initalize file directory
filename = "./OMI-Aura_L2-OMNO2_2004m1001t1810-o01143_v003-2019m0814t172958.he5"

with h5py.File(filename, "r") as f:
    # Print all root level object names (aka keys)
    # these can be group or dataset names
    #print("Keys: %s" % f.keys())
    # get first object name/key; may or may NOT be a group
    a_group_key = list(f.keys())[0]

    # get the object type for a_group_key: usually group or dataset
    #print(type(f[a_group_key]))

    # If a_group_key is a group name,
    # this gets the object names in the group and returns as a list
    data = list(f[a_group_key])

    # If a_group_key is a dataset name,
    # this gets the dataset values and returns as a list
    data = list(f[a_group_key])
    # preferred methods to get dataset values:
    ds_obj = f[a_group_key]      # returns as a h5py dataset object
    #ds_arr = f[a_group_key][()]  # returns as a numpy array
    dataset= f.get('HDFEOS INFORMATION')
    print(dataset)
    G1= f.get('HDFEOS INFORMATION')
    G1_items= list(G1.items())
    print('items in group 1: ', G1_items)
    archmetadatagrp= np.array(G1.get('ArchivedMetadata.0'))
    print(archmetadatagrp)
    coremetadatagrp= np.array(G1.get('CoreMetadata.0'))
    print(coremetadatagrp)
    structmetadatagrp= np.array(G1.get('StructMetadata.0'))
    print(structmetadatagrp)

    print(np.array(dataset))
    dataset2= f.get('HDFEOS')
    print(dataset2)
    print(np.array(dataset2))
    additionalgrp= np.array(G1.get('ADDITIONAL'))
    print(additionalgrp)
    SWATHSgrp= np.array(G1.get('SWATHS'))
    print(SWATHSgrp)

    #plotting NO2 column data
    #imports
import os

import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import numpy as np
import h5py

FILE_NAME = "./OMI-Aura_L2-OMNO2_2004m1001t1810-o01143_v003-2019m0814t172958.he5"
path = '/HDFEOS/SWATHS/ColumnAmountNO2/Data Fields/'
DATAFIELD_NAME = path + 'CloudFraction'
with h5py.File(FILE_NAME, mode='r') as f:
    dset = f[DATAFIELD_NAME]
    data =dset[:].astype(np.float64)

    # Retrieve any attributes that may be needed later.
    # String attributes actually come in as the bytes type and should
    # be decoded to UTF-8 (python3).
    scale = f[DATAFIELD_NAME].attrs['ScaleFactor']
    offset = f[DATAFIELD_NAME].attrs['Offset']
    missing_value = f[DATAFIELD_NAME].attrs['MissingValue']
    fill_value = f[DATAFIELD_NAME].attrs['_FillValue']
    title = f[DATAFIELD_NAME].attrs['Title'].decode()
    units = f[DATAFIELD_NAME].attrs['Units'].decode()

    # Retrieve the geolocation data.
    path = '/HDFEOS/SWATHS/ColumnAmountNO2/Geolocation Fields/'
    latitude = f[path + 'Latitude'][:]
    longitude = f[path + 'Longitude'][:]

    data[data == missing_value] = np.nan
    data[data == fill_value] = np.nan
    data = scale * (data - offset)
    datam = np.ma.masked_where(np.isnan(data), data)

    # Draw an equidistant cylindrical projection using the low resolution
    # coastline database.
    m = Basemap(projection='cyl', resolution='l',
                llcrnrlat=-90, urcrnrlat = 90,
                llcrnrlon=-180, urcrnrlon = 180)
    m.drawcoastlines(linewidth=0.5)
    m.drawparallels(np.arange(-90., 120., 30.), labels=[1, 0, 0, 0])
    m.drawmeridians(np.arange(-180, 180., 45.), labels=[0, 0, 0, 1])
    m.scatter(longitude, latitude, c=datam, s=1, cmap=plt.cm.jet,
             edgecolors=None, linewidth=0)
    cb = m.colorbar()
    cb.set_label(units)

    basename = os.path.basename(FILE_NAME)
    plt.title('{0}\n{1}'.format(basename, title), fontsize=8)
    fig = plt.gcf()
    pngfile = "{0}.py.png".format(basename)
    fig.savefig(pngfile)


from tornado.httputil import HTTPServerRequest
from unittest import TestCase

from thr.http2redis.exchange import HTTPExchange
from thr.http2redis.rules import Criteria, Actions, Rules, add_rule

class TestRules(TestCase):

    def setUp(self):
        Rules.reset()

    def test_add_rule(self):
        add_rule(Criteria(), Actions())
        self.assertEqual(Rules.count(), 1)

    def test_execute_rules(self):
        add_rule(Criteria(path='/foo'),
                 Actions(set_input_header=('Header-Name', 'FOO')))
        add_rule(Criteria(path='/bar'),
                 Actions(set_input_header=('Header-Name', 'BAR')))
        request = HTTPServerRequest(method='GET', uri='/foo')
        Rules.execute_input_actions(HTTPExchange(request))
        self.assertEqual(request.headers['Header-Name'], 'FOO')

    def test_execute_multiple_rules(self):
        add_rule(Criteria(path='/foo'),
                 Actions(set_input_header=('Header-Name', 'FOO')))
        add_rule(Criteria(path='/foo'),
                 Actions(set_input_header=('Header-Name', 'BAR')))
        request = HTTPServerRequest(method='GET', uri='/foo')
        Rules.execute_input_actions(HTTPExchange(request))
        self.assertEqual(request.headers['Header-Name'], 'BAR')

    def test_stop_option(self):
        add_rule(Criteria(path='/foo'),
                 Actions(set_input_header=('Header-Name', 'FOO')), stop=True)
        add_rule(Criteria(path='/foo'),
                 Actions(set_input_header=('Header-Name', 'BAR')))
        request = HTTPServerRequest(method='GET', uri='/foo')
        Rules.execute_input_actions(HTTPExchange(request))
        self.assertEqual(request.headers['Header-Name'], 'FOO')

    def test_set_redis_queue_based_on_path(self):
        add_rule(Criteria(path='/foo'), Actions(set_redis_queue='test-queue'))
        request = HTTPServerRequest(method='GET', uri='/foo')
        exchange = HTTPExchange(request)
        Rules.execute_input_actions(exchange)
        self.assertEqual(exchange.redis_queue, 'test-queue')

    def test_set_redis_queue_based_on_callable(self):

        def callback_false(request):
            return False

        def callback_true(request):
            return True

        add_rule(Criteria(custom=callback_false),
                 Actions(set_redis_queue='not-this-one'), stop=1)
        add_rule(Criteria(custom=callback_true),
                 Actions(set_redis_queue='yes-this-one'))
        request = HTTPServerRequest(method='GET', uri='/foo')
        exchange = HTTPExchange(request)
        Rules.execute_input_actions(exchange)
        self.assertEqual(exchange.redis_queue, 'yes-this-one')


# A program that produces a drawing of a house
# that changes between day and night when clicked
# and increments a counter up to 100

from graphics import *

def main():
    win = GraphWin('Python House', 650, 400)
    win.setCoords(0, 0, 100, 100)

    grass = Rectangle(Point(0,0), Point(100, 15))
    grass.setFill('green3')
    grass.setOutline('green3')
    grass.draw(win)

    sky = Rectangle(Point(0, 15), Point(100, 100))
    sky.setFill('sky blue')
    sky.setOutline('sky blue')
    sky.draw(win)

    house = Rectangle(Point(25, 15), Point(75, 60))
    house.setFill('yellow2')
    house.draw(win)

    door = Rectangle(Point(46, 15), Point(54, 40))
    door.setFill('tan2')
    door.draw(win)

    leftWindow = Rectangle(Point(30, 30), Point(40, 45))
    leftWindow.setFill('light steel blue')
    leftWindow.draw(win)

    rightWindow = leftWindow.clone()
    rightWindow.move(30, 0)
    rightWindow.draw(win)

    roof = Polygon(Point(25, 60), Point(50, 85), Point(75, 60))
    roof.setFill('brown')
    roof.draw(win)

    leftWindowPane1 = Line(Point(30, 37.5), Point(40, 37.5))
    leftWindowPane2 = Line(Point(35, 30), Point(35, 45))
    leftWindowPane1.draw(win)
    leftWindowPane2.draw(win)

    rightWindowPane1 = leftWindowPane1.clone()
    rightWindowPane1.move(30, 0)
    rightWindowPane2 = leftWindowPane2.clone()
    rightWindowPane2.move(30, 0)
    rightWindowPane1.draw(win)
    rightWindowPane2.draw(win)

    doorKnob = Circle(Point(52.5, 27), 0.8)
    doorKnob.setFill('gold')
    doorKnob.draw(win)

    sun = Circle(Point(10, 90), 9.175)
    sun.setFill('yellow')
    sun.setOutline('yellow')
    sun.draw(win)

    clickNum = 0
    address = Text(Point(50, 45), clickNum)
    address.draw(win)

    current = 'day'
    for i in range(101):
        win.getMouse()
        clickNum += 1

        if current == 'day':
            sky.setFill('black')
            sky.setOutline('black')
            sun.setFill('white')
            sun.setOutline('white')
            grass.setFill('green4')
            grass.setOutline('green4')
            leftWindow.setFill('yellow')
            rightWindow.setFill('yellow')
            house.setFill('yellow4')
            door.setFill('tan3')

            current = 'night'
        else:
            sky.setFill('sky blue')
            sky.setOutline('sky blue')
            sun.setFill('yellow')
            sun.setOutline('yellow')
            grass.setFill('green3')
            grass.setOutline('green3')
            leftWindow.setFill('light steel blue')
            rightWindow.setFill('light steel blue')
            house.setFill('yellow2')
            door.setFill('tan2')

            current = 'day'

        address.setText(clickNum)

    win.close()

main()


from __future__ import absolute_import
import base64
import hashlib
import os
import random

import six

from st2common import log as logging
from st2common.persistence.auth import Token, ApiKey
from st2common.exceptions import auth as exceptions
from st2common.util import date as date_utils
from st2common.util import hash as hash_utils

__all__ = [
    "validate_token",
    "validate_token_and_source",
    "generate_api_key",
    "validate_api_key",
    "validate_api_key_and_source",
]

LOG = logging.getLogger(__name__)

def validate_token(token_string):
    """
    Validate the provided authentication token.

    :param token_string: Authentication token provided.
    :type token_string: ``str``

    :return: TokenDB object on success.
    :rtype: :class:`.TokenDB`
    """
    token = Token.get(token_string)

    if token.expiry <= date_utils.get_datetime_utc_now():
        # TODO: purge expired tokens
        LOG.audit('Token with id "%s" has expired.' % (token.id))
        raise exceptions.TokenExpiredError("Token has expired.")

    LOG.audit('Token with id "%s" is validated.' % (token.id))

    return token

def validate_token_and_source(token_in_headers, token_in_query_params):
    """
    Validate the provided authentication token.

    :param token_in_headers: Authentication token provided via headers.
    :type token_in_headers: ``str``

    :param token_in_query_params: Authentication token provided via query params.
    :type token_in_query_params: ``str``

    :return: TokenDB object on success.
    :rtype: :class:`.TokenDB`
    """
    if not token_in_headers and not token_in_query_params:
        LOG.audit("Token is not found in header or query parameters.")
        raise exceptions.TokenNotProvidedError("Token is not provided.")

    if token_in_headers:
        LOG.audit("Token provided in headers")

    if token_in_query_params:
        LOG.audit("Token provided in query parameters")

    return validate_token(token_in_headers or token_in_query_params)

def generate_api_key():
    """
    Generates an sufficiently large and random key.

    credit: http://jetfar.com/simple-api-key-generation-in-python/

    :rtype: ``str``
    """
    # 256bit seed from urandom
    seed = os.urandom(256)

    # since urandom does not provide sufficient entropy hash, base64encode and salt.
    # The resulting value is now large and should be hard to predict.
    hashed_seed = hashlib.sha256(seed).hexdigest()

    base64_encoded = base64.b64encode(
        six.b(hashed_seed),
        six.b(random.choice(["rA", "aZ", "gQ", "hH", "hG", "aR", "DD"])),
    ).rstrip(b"==")
    base64_encoded = base64_encoded.decode()
    return base64_encoded

def generate_api_key_and_hash():
    api_key = generate_api_key()
    api_key_hash = hash_utils.hash(api_key)
    return api_key, api_key_hash

def validate_api_key(api_key):
    """
    Validate the provided API key.

    :param api_key: API key provided.
    :type api_key: ``str``

    :return: TokenDB object on success.
    :rtype: :class:`.ApiKeyDB`
    """
    api_key_db = ApiKey.get(api_key)

    if not api_key_db.enabled:
        raise exceptions.ApiKeyDisabledError("API key is disabled.")

    LOG.audit('API key with id "%s" is validated.' % (api_key_db.id))

    return api_key_db

def validate_api_key_and_source(api_key_in_headers, api_key_query_params):
    """
    Validate the provided API key.

    :param api_key_in_headers: API key provided via headers.
    :type api_key_in_headers: ``str``

    :param api_key_query_params: API key provided via query params.
    :type api_key_query_params: ``str``

    :return: TokenDB object on success.
    :rtype: :class:`.ApiKeyDB`
    """
    if not api_key_in_headers and not api_key_query_params:
        LOG.audit("API key is not found in header or query parameters.")
        raise exceptions.ApiKeyNotProvidedError("API key is not provided.")

    if api_key_in_headers:
        LOG.audit("API key provided in headers")

    if api_key_query_params:
        LOG.audit("API key provided in query parameters")

    return validate_api_key(api_key_in_headers or api_key_query_params)


import pandas as pd
import numpy as np
from pprint import pprint

df = pd.DataFrame([[2009, 1, 15, 'City1', 'Housing'],  [2010, 2, np.nan, 'City2', 'Housing']], columns=['year', 'month', 'day', 'city', 'sector'])
pprint(df)

df['day'] = 15
df['date'] = pd.to_datetime(df[['year', 'month', 'day']])
ind = df.set_index(['date', 'sector', 'city'], drop=False).sort_index()
cols = ['month', 'year', 'sector']
per_city = ind.loc[(slice(None), slice(None), 'City1'), cols].dropna(how='any')
item = per_city.unstack()
pprint(item)

d = {
    'vote': [100, 50, 1, 23, 55, 67, 89, 44],
    'vote2': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
    'ballot1': [None, False, -1, True, 'b', 'a', 'c', ''],
    'voteId': [1, 2, 3, 4, 5, 6, 7, 8]}
d1 = {
    'vote': [100, 50, 1, 23, 55, 67, 89, 44],
    'vote2': [10, 'a', 18, 55, 77, 99, 9, 40],
    'ballot1': [1, None, 3, 4, 5, 6, 7, 8],
    'voteId': [1, 2, 3, {}, 5, 6, 7, 8]}
d2 = {
    'vote': [10, None, 2, 23, 55, 67, 89, 44],
    'vote2': [10, 2, 3, 55, 77, 99, 9, 40],
    'ballot1': [1, '', 3, 4, 5, 6, 7, 8],
    'voteId': ['a', True, 'a', 'a', 'c', 'a', 'c', 'a']}

pprint(d)
df1 = pd.DataFrame(d, dtype=np.float32)
df1 = df1.drop_duplicates(['voteId', 'ballot1'], keep='last')

print('df1 len {}'.format(len(df1)))
pprint(df1)
print(pd.__version__)
print('df1 is mixed type {}'.format(df1._is_mixed_type))
# index?
print('set maximum size to be :10 dfx')
s = df1[:6].set_index(['voteId', 'ballot1'], verify_integrity=True).unstack()
pprint(s)
print(pd.__version__)
print('s is mixed type {}'.format(s._is_mixed_type))

# s.columns = s.columns.map('(ballot1={0[1]}){0[0]}'.format)
# dflw = pd.DataFrame(s)
# print(type(dflw))

def foo_func_first():
    foo = pd.DataFrame(np.random.randn(2, 3), columns=['aaa', 'bbb', 'ccc'])
    pprint(foo)
    foo.to_hdf('foo.h5', 'foo')
    bar = pd.read_hdf('foo.h5', 'foo')
    pprint(bar)

class Col(object):

    def __init__(self, name, other_info):
        self.name = name
        self.other_info = other_info

    def __str__(self):
        return self.name

def foo_func():
    foo = pd.DataFrame(np.random.randn(2, 3), columns=[Col('aaa', {'z': 5}), Col('bbb', {'y': True}), Col('ccc', {})])
    pprint(foo)
    df = foo.unstack()
    pprint(df)
    foo.to_hdf('foo.h5', 'foo')
    bar = pd.read_hdf('foo.h5', 'foo')
    pprint(bar)

foo_func()


# encoding: utf-8
import json
import requests
import time
import os
import subprocess

from threading import Thread
from Queue import Queue, Empty

import logging
logger = logging.getLogger('videobooth.%s' % __name__)

URL_SUFFIX = ".url"
DONE_SUFFIX = ".done"

class UploadProxy(object):
    def __init__(self, config):
        self.conf = config
        self.is_running = False

        # file encoding + upload file thread
        self.process_req = Queue(maxsize=0)
        self.thread_process = Thread(target=self.process_worker)
        self.thread_process.setDaemon(True)

        if not self.conf['upload']['enabled']:
            return

        if self.conf['upload']['debug']:
            self.enable_debug()

        # create post thread
        self.create_req = Queue(maxsize=8)
        self.create_resp = Queue(maxsize=8)
        self.thread_create = Thread(target=self.create_worker)
        self.thread_create.setDaemon(True)

    def enable_debug(self):
        import httplib as http_client
        http_client.HTTPConnection.debuglevel = 1
        requests_log = logging.getLogger("requests.packages.urllib3")
        requests_log.setLevel(logging.DEBUG)
        requests_log.propagate = True

    def upload_pending_movies(self):
        """ searches for unuploaded movies and tries to upload them """
        files = os.listdir(self.conf['picam']['archive_dir'])
        for f in files:
            if os.path.splitext(f)[1] == ".mp4" and (f + DONE_SUFFIX) not in files:
                filepath = os.path.join(self.conf['picam']['archive_dir'], f)
                upload_url = None
                if os.path.exists(filepath + URL_SUFFIX):
                    with open(filepath + URL_SUFFIX) as f_url:
                        upload_url = f_url.read()

                logging.info("scheduling for upload: '%s' -> '%s'", filepath, upload_url)
                self.async_process(upload_url, filepath)

    def start(self):
        self.is_running = True
        self.thread_process.start()
        if self.conf['upload']['enabled']:
            self.thread_create.start()

            if self.conf['upload']['retrying']:
                self.upload_pending_movies()

    def async_create_post(self, mov_suffix):
        if not self.conf['upload']['enabled']:
            return

        self.create_req.put(mov_suffix)

    def async_create_post_result(self):
        if not self.conf['upload']['enabled']:
            return ("", "")

        try:
            return self.create_resp.get_nowait()
        except Empty:
            return None

    def async_process(self, upload_url, filename):
        self.process_req.put((upload_url, filename))

    def sync_create_post(self, mov_suffix):
        name = "%s%s" % (self.conf['upload']['atende']['title_prefix'], mov_suffix)
        logger.debug("name: %s", name)

        try:
            start = time.time()
            resp = requests.post(
                '%s/api/v1/videos/create/' % self.conf['upload']['atende']['api_endpoint'],
                {
                    'category': self.conf['upload']['atende']['category_id'],
                    'name': name,
                    'description': self.conf['upload']['atende']['description'],
                },
                headers={
                    'X-Token': self.conf['upload']['atende']['api_token']
                },
                timeout=self.conf['upload']['atende']['timeout_secs'])

            logger.debug("create time: %f seconds", (time.time() - start))
            resp_json = json.loads(resp.content)
            return (
                resp_json['uploadUri'],
                self.conf['upload']['atende']['api_endpoint'] + resp_json['frontendUri'])
        except requests.exceptions.RequestException:
            logger.exception("create: exception")
            return ("","")

    def create_worker(self):
        while self.is_running:
            mov_suffix = self.create_req.get()
            logger.debug("create_worker: START")

            ret = self.sync_create_post(mov_suffix)
            self.create_resp.put(ret)

            self.create_req.task_done()
            logger.debug("create_worker: END")

    def process_worker(self):
        while self.is_running:
            (upload_url, filepath) = self.process_req.get()
            logger.debug("process_worker: START")
            start = time.time()

            # (1) convert mpeg-ts to MP4:
            (tmp_filepath, ext) = os.path.splitext(filepath)
            if ext == ".ts":
                (_, filename) = os.path.split(tmp_filepath)
                new_filepath = os.path.join(self.conf['picam']['archive_dir'], filename + ".mp4")
                cmd = ['ffmpeg', '-i', filepath, '-c:v', 'copy', '-c:a', 'copy', '-bsf:a', 'aac_adtstoasc', new_filepath]
                logger.debug("CONVERT CMD: %s", cmd)
                subprocess.call(cmd)
                logger.debug("creating MP4 took %f seconds", (time.time() - start))
                os.unlink(filepath) # NOTE: removing original .ts file
                filepath = new_filepath

            if not self.conf['upload']['enabled']:
                logging.warn("not uploading file: uploading is disabled")
                self.process_req.task_done()
                continue

            # (2) only when reuploading at startup - create upload URL synchronously
            if upload_url is None:
                # generate mov_prefix similar to strftime
                fn = os.path.splitext(os.path.split(filepath)[1])[0]
                (fn_date, fn_time) = fn.split('_')
                mov_prefix = fn_date + " " + fn_time.replace("-", ":")

                logger.debug("upload uri is None, getting new one(mov_prefix='%s')", mov_prefix)
                (upload_url, _) = self.sync_create_post(mov_prefix)

            if len(upload_url) == 0:
                logging.warn("not uploading file: empty post url")
                continue

            # (3) save upload URL in case it wasn't done already
            if not os.path.exists(filepath + URL_SUFFIX):
                with open(filepath + URL_SUFFIX, "w") as f:
                    f.write(upload_url)

            # (4) upload
            try:
                logger.debug("uploading file '%s' to '%s'", filepath, upload_url)
                start = time.time()
                with open(filepath, 'rb') as file_obj:
                    resp = requests.put(
                        '%s%s' % (self.conf['upload']['atende']['api_endpoint'], upload_url),
                        data=file_obj,
                        headers={
                            'X-Token': self.conf['upload']['atende']['api_token'],
                            'Content-Type': 'video/mp4'
                        },
                        timeout=self.conf['upload']['atende']['timeout_secs'])

                if resp.status_code == 204:
                    logger.info("upload sucessful")
                else:
                    import pprint
                    logger.warn("Failed upload response: %s", pprint.pformat(resp.__dict__))
                    resp.raise_for_status()

                # (5) save upload URL in case it wasn't done already:
                with open(filepath + DONE_SUFFIX, "w") as f:
                    f.write("%f" % (time.time()-start))

                logger.debug("uploading took %f seconds", (time.time() - start))

            except requests.exceptions.RequestException:
                logger.exception("upload: exception")

            self.process_req.task_done()
            logger.debug("upload_worker: END")


# решение линейного уравнения a*x = b
# x = b/a
def linear_solve(a, b):
    return b / a

# 2*x = 9
print(linear_solve(2, 9))

# 0*x = 1
# print(linear_solve(0, 1))

# Модифицируем ее код, чтобы она могла учитывать такое поведение.

def linear_solve(a, b):
    if a:  # помним, что 0 интерпретируется как False, иначе — True
        return b / a
    else:
        return "Нет корней"

# a = 0 and b = 0
print(linear_solve(0, 0))

# Модифицируем нашу программу еще раз.
def linear_solve(a, b):
    if a:
        return b / a
    elif not a and not b:  # снова используем числа в логических выражениях
        return "Бесконечное количество корней"
    else:
        return "Нет корней"

print(linear_solve(0, 0))

# Реализуем функцию, решающую квадратные уравнения
# a*x**2 + b*x + c = 0 - общий вид уравнения
# D = b**2 - 4*a*c - дискриминант
# Если D<0, то уравнение не имеет вещественных корней
# Если D=0, то уравнение имеет один корень - x = -b/(2*a)
# Если D>0, то уравнение имеет два корня
# x1 = (-b - D**0.5)/(2*a)
# x2 = (-b + D**0.5)/(2*a)
#
# P.S. D**0.5 - равносильно извлечению квадратного корня

# Напишите функцию D(a,b,c), возвращающую дискриминант квадратного уравнения.
def D(a, b, c):
    return b ** 2 - 4 * a * c

print(D(1, 2, 3))

# Следующим этапом реализуем функцию, возвращающую «Нет вещественных корней», если дискриминант отрицательный.
def quadratic_solve(a, b, c):
    if D(a, b, c) < 0:
        return 'Нет вещественных корней'

print(D(1, 2, 3))

# Модифицируйте функцию quadratic_solve(a,b,c), чтобы она возвращала единственный корень при условии нулевого
# дискриминанта.
def quadratic_solve(a, b, c):
    if D(a, b, c) < 0:
        return 'Нет вещественных корней'
    elif D(a, b, c) == 0:
        return -b / (2 * a)

# И последним этапом нам нужно вернуть сразу два значения. Конечный вид функции будет выглядеть так:
def quadratic_solve(a, b, c):
    if D(a, b, c) < 0:
        return "Нет вещественных корней"
    elif D(a, b, c) == 0:
        return -b / (2 * a)
    else:
        return (-b - D(a, b, c) ** 0.5) / (2 * a), (-b + D(a, b, c) ** 0.5) / (2 * a)

# разбили строку из input и преобразовали к float
L = list(map(float, input().split()))
print(quadratic_solve(*L))  # * - функция распаковки списка

# Представим, что у нас теперь аргументы хранятся не в виде списка, а в виде словаря.
M = {'a': 1,
     'b': 0,
     'c': -1}
print(quadratic_solve(**M))  # ** - функция распаковки словаря


"""Example code from the PyQt Course for Beginners tutorial (YouTube).
------------------------------------------------------------------------
PyQt6 Course for Beginners - Parwiz Forogh (https://youtu.be/ot94H3-d5d8?t=5461)
Detailed notes: https://tinyurl.com/y5db3c5c

Demonstrates QTableWidget through code

Concepts introduced:
    - Create and style a table via the QTableWidget

Module/Class/Methods:
    QApplication        See detailed notes (linked above)
    QWidget             See detailed notes (linked above)
    QLabel              See detailed notes (linked above)
    QIcon               See detailed notes (linked above)
    QFont               See detailed notes (linked above)

    QTableWidget        Instantiates a table control
      setColumnCount    Sets the width of the table in columns
      setRowCount       Sets the height of the table in rows
      setItem           Sets the content at a cell location
      setStyleSheet     Defines the appearance of the table
      setFont           Defines the font and font size for text in the table

    QTableWidgetItem
      __init__

___________________________________________________________________________________________________

Created November 20, 2022
"""
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout
from PyQt6.QtWidgets import QTableWidget,QTableWidgetItem
from PyQt6.QtGui import QIcon, QFont

class Window(QWidget):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('PyQt6 TableWidget')
        self.setWindowIcon(QIcon("app_icon.png"))
        self.setGeometry(500, 200, 500, 400)

        self.create_widgets()

    def create_widgets(self):
        vbox = QVBoxLayout()

        # add a table
        tableWidget = QTableWidget(self)
        tableWidget.setColumnCount(3)
        tableWidget.setRowCount(3)
        tableWidget.setStyleSheet('background-color:yellow')
        tableWidget.setFont(QFont('Times New Roman', 14))

        tableWidget.setItem(0, 0, QTableWidgetItem("FName"))
        tableWidget.setItem(0, 1, QTableWidgetItem("LName"))
        tableWidget.setItem(0, 2, QTableWidgetItem("Email"))

        tableWidget.setItem(1, 0, QTableWidgetItem("Parwiz"))
        tableWidget.setItem(1, 1, QTableWidgetItem("Forogh"))
        tableWidget.setItem(1, 2, QTableWidgetItem("parwiz@gmail.com"))

        tableWidget.setItem(2, 0, QTableWidgetItem("John"))
        tableWidget.setItem(2, 1, QTableWidgetItem("Doe"))
        tableWidget.setItem(2, 2, QTableWidgetItem("john_doe@gmail.com"))

        vbox.addWidget(tableWidget)
        self.setLayout(vbox)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec())


#uses python3

import sys
import numpy as np

def oper(a,b,op):
    if op == '+':
        return a + b
    if op == '-':
        return a - b
    if op == '*':
        return a*b

def maxval(digs,ops):
    n = len(digs)
    M = np.zeros((n,n))
    m = np.zeros((n,n))
    for i in range(0,n):
        M[i,i] = digs[i]
        m[i,i] = digs[i]
    for s in range(1,n):
        for j in range(s,n):
            i = j-s
            maxk = oper(M[i,j-1], M[j,j], ops[j-1])
            mink = oper(M[i,j-1], M[j,j], ops[j-1])
            for k in range(1,s+1):
                a = oper(M[i,j-k], M[j-k+1,j], ops[j-k])
                b = oper(M[i,j-k], m[j-k+1,j], ops[j-k])
                c = oper(m[i,j-k], M[j-k+1,j], ops[j-k])
                d = oper(m[i,j-k], m[j-k+1,j], ops[j-k])
                maxk = max(maxk,a,b,c,d)
                mink = min(mink,a,b,c,d)
            M[i,j] = maxk
            m[i,j] = mink
    return int(M[0,n-1])

if __name__ == '__main__':
    input = sys.stdin.read()
    data = list(input)
    digs = data[0::2]
    ops = data[1::2]
    print(maxval(digs,ops))


import pytest
from selenium import webdriver
import configparser

from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager

from amazon.pages.LoginPage import LoginPage
from amazon.pages.MainPage import MainPage

config = configparser.ConfigParser()
config.read('config.ini')
config = config.defaults()

@pytest.fixture(scope="module")
def driver():
    driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
    driver.implicitly_wait(15)
    yield driver
    driver.close()

def test_01_amazon_login(driver):
    login_page = LoginPage(driver)
    main_page = MainPage(driver)

    main_page.\
        open_main_page(config["base_url"]).\
        click_on_sign_in()
    login_page.\
        input_login(config["username"]).\
        input_password(config["password"])
    main_page.\
        should_be_logged_in(config["first_name"])


import random
from typing import Counter

class roll_dice :
    # 주사위 굴리는 파트
    def Random_dice() :
        list = []
        for i in range(5) :
            dice = random.randrange(1,6)
            list.append(dice)
        return list

    # 주사위 교체 파트
    def Change_dice(query, dice_result) :
        while True :
            if query == 'y' or query == 'Y' :
                choice_list = []
                while True :
                    input_select = input("다시 굴릴 주사위 번호를 하나씩 입력 후 Enter(종료 F, 재입력 A) : ")
                    if input_select in ['1', '2', '3', '4', '5'] :
                        choice_list.append(input_select)
                        print("입력한 번호 : ", choice_list)
                        continue
                    elif input_select == 'a' or input_select == 'A':
                        print("번호 초기화!!")
                        choice_list = []
                    elif input_select == 'f' or input_select == 'F' :
                        print("주사위 선택 종료")
                        break
                    else :
                        print("유효하지 않은 값 입니다 !!")
                        continue

                # i가 choice_list를 쭈욱 훑음
                # 0번 인덱스부터 다시 굴려야하니까 -1
                for i in choice_list :
                    dice_result[int(i)-1] = random.randrange(1,6)
                return dice_result

            elif query == 'n' or query == 'N' :
                return dice_result

            else :
                print("유효하지 않은 값 입니다 !!")
                continue

class result_dice :
    #주사위 결과값 파트
    def Show_result(dice_result) :
        dice_list = {}
        dice_list['1번 주사위'] = dice_result[0]
        dice_list['2번 주사위'] = dice_result[1]
        dice_list['3번 주사위'] = dice_result[2]
        dice_list['4번 주사위'] = dice_result[3]
        dice_list['5번 주사위'] = dice_result[4]

        return dice_list

# main
print("프로그램을 시작합니다.")

print("1. 게임시작")
print("2. 게임설명")
input_start = input("입력 : ")
count = 0

while(count<3) :
    if input_start == "1" :
        #게임 시작 코드 추가 필요
        dice_result = roll_dice.Random_dice()
        print(dice_result)
        query = input("값을 바꾸시겠어요? (Y/N)")
        if query == 'y' or query == 'Y' :
            roll_dice.Change_dice(query, dice_result)
            show = result_dice.Show_result(dice_result)
            print(show)
        elif query == 'n' or query == 'N' :
            break
        else :
            print("유효하지 않은 값입니다 !! ")
            continue
        count+=1

    elif input_start == "2" :
    #게임 설명 코드 추가 필요
        pass


import board
import time
import digitalio
import storage
import keypad
from macrosengine import macroengine
import gc

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT

km = keypad.KeyMatrix(
    row_pins=(board.GP15, board.GP14, board.GP13, board.GP12),
    column_pins=(board.GP11, board.GP10, board.GP9, board.GP8),
    columns_to_anodes=False,
)

def getRamUsage():
    gc.collect()
    mem = gc.mem_free()
    print( "Available memory: {} bytes".format(mem))
    mem = (256000 - mem) / 256000 * 100
    print("RAM Used:{:.2f}%".format(mem))

def running_led(speed):
    led.value = True
    time.sleep(speed)
    led.value = False
    time.sleep(speed)

file = "macros.txt"
macros_sum = 0

with open("/"+file, "r") as f:
    fileLines = f.readlines()
    macros_sum = len(fileLines)

def parse_line(line_number,filename=file):
    with open("/"+filename, "r") as f:
        fileLines = f.readlines()
        for i,line in enumerate(fileLines):
            line =  line.replace("\r\n", "")
            if i == line_number:
                f.close()
                return line
        f.close()

macros = macroengine()

current_profile = 0
profiles = int(macros_sum / km.key_count)
remaining_macros = int(macros_sum % km.key_count )
if remaining_macros > 0:
    profiles += 1

print("Number of lines:"+str(macros_sum))
print("Profiles:"+str(profiles))

def keyToMacro(key_pressed: int):
    x = (current_profile * km.key_count) + key_pressed
    print("Pressed:"+str(x))
    if(key_pressed <= macros_sum - 1):
        macros.parseMacro(parse_line(x),True)
    else:
        getRamUsage()

while True:
    event = km.events.get()
    if event and event.pressed:
        keyToMacro(event.key_number)
    if km.events.overflowed:
        km.events.clear()    # Empty the event queue.
        km.reset()           # Forget any existing presses. Start over.
    running_led(0.05)


import time
import board
import busio
from i2c_button import I2C_Button

# initialize I2C
i2c = busio.I2C(board.SCL, board.SDA)

# scan the I2C bus for devices
while not i2c.try_lock():
    pass
devices = i2c.scan()
i2c.unlock()
print("I2C devices found:", [hex(n) for n in devices])
default_addr = 0x6F
if default_addr not in devices:
    print("warning: no device at the default button address", default_addr)

# addresses
ACK_ADDR = 0x6E
SNZ_ADDR = 0x6F

# initialize the buttons
ack = I2C_Button(i2c, ACK_ADDR, name="ack")
snz = I2C_Button(i2c, SNZ_ADDR, name="snz")

def button_values(button):
    """Print all public property values."""
    attrs = (
        "name",
        "i2c_addr",
        "dev_id",
        "version",
        "debounce_ms",
        #       "interrupts",
        "led_bright",
        "led_gran",
        "led_cycle_ms",
        "led_off_ms",
        "status",
        #       "press_queue",
        "last_press_ms",
        "first_press_ms",
        #       "click_queue",
        "last_click_ms",
        "first_click_ms",
    )
    for attr in attrs:
        print(attr, getattr(button, attr))
    print()

while True:
    ack.clear()
    snz.clear()
    time.sleep(2)
    button_values(ack)
    button_values(snz)


# manejo de cajero
datos={"clave":"1234","cbu":"0110253654125412367346","ayn":"Virili Omar Dario","saldo":25000,"saldoDolar":500,"plazofijo":[{"f_ini":"22-10-2022","f_fin":"22-11-2022","monto":30000},{"f_ini":"22-10-2023","f_fin":"22-11-2023","monto":50000}]}
movimientos =list()
listadoServicio = {"LUZ":(500,False)},{"AGUA":(500,False)},{"TELEFONO":(500,False)}
dolar = 215
def servicio():
    #tabajando en estas funcionalidades
    print("-------------MENU DE SERVICIOS------------")
    print("""
    1-NUEVO SERVICIO
    2-PAGAR SERVICIO
    3-ELIMNAR SERVICIO
    4-LISTAR SERVICIOS
    9-SALIR SIN CAMBIOS
    """)
    op = int(input("Ingrese opcion elegida: "))
    if op==1:
        nuevoSer=input("Ingrese nombre del Servicio")
        valor =int(input("Ingrese el monto del servicio"))
        nuevo = dict()
        nuevo[nuevoSer]=(valor,False)
        listadoServicio.append(nuevo)
        print(f"Servicio {nuevoSer} se agrego con Exito")
    elif op==2:
        pass
    elif op==3:
        pass
    elif op==4:
        pass
    elif op==9:
        print("No se realizaron cambios")
        salir = False

def menu():
    print(
        """
        MENU DE OPCIONES DEL CAJERO
        # 01-CONSULTA SALDO
        # 02-DEPOSITAR DINERO
        # 03-EXTRAER DINERO
        # 04-TRANSFERIR DINERO
        # 05-COMPRAR DOLARES
        # 06-VENDER DOLARES
        # 07-CREAR PLAZO FIJO
        # 08-ULTIMOS MOVIMIENTOS
        # 09-PAGAR SERVICIOS
        # 10-SALIR
        """
    )
    fin=True
    op=int(input("Ingrese una opcion: "))
    if op==1:
        print("------------------SALDO--------------------")
        print(f"Su saldo en Pesos es: {datos['saldo']}")
        print(f"Su saldo en Dolares: {datos['saldoDolar']}")
        total=0
        for x in datos['plazofijo']:
            total = total+x['monto']
            print(f"Plazo Fijo con Vencimiento el: {x['f_fin']} es: ${x['monto']}")
        print(f"El Saldo total acumulado en Plazo Fijos es: {total}")
        print("////////////////////////////////////////")
        movimientos.append("Consulta de Saldo")
    if op==2:
        print("--------------DEPOSITAR DINERO------------")
        caja = int(input(
                """Seleccione la cuenta a la cual depositara
                1-Pesos
                2-Dolares\n"""))
        if caja ==1:
            monto=int(input("Ingrese la cantidad de Pesos: $"))
            datos['saldo']=datos['saldo']+monto
            print(f"Su saldo en Pesos es: {datos['saldo']}")
            movimientos.append("Deposito de Pesos")
        elif caja ==2:
            monto=int(input("Ingrese la cantidad de Dolares: "))
            datos['saldo']=datos['saldoDolar']+monto
            print(f"Su saldo en Dolares es: {datos['saldoDolar']}")
            movimientos.append("Deposito de Dolare")

    if op==3:
        print("--------------EXTRACCION DINERO------------")
        print(f"Su saldo en Pesos es: {datos['saldo']}")
        monto = int(input("Ingrese el monto que desea extraer: $"))
        if(datos['saldo']>= monto):
            datos['saldo']=datos['saldo']-monto
            print(f"Su saldo en Pesos luego de la extraccion es : {datos['saldo']}")
            movimientos.append("Extraccion de Pesos")

    if op==4:
        print("--------------REALIZAR TRANSFERENCIA------------")
        divisa = int(input("Ingrese la divisa que transfiere 1-Pesos 2-Dolar: "))
        if divisa==1:
            cuenta=input("Ingrese el cbu de destino: ")

            if len(cuenta)==22:
                monto = int(input("Ingrese el monto a trasferir: "))
                if(datos['saldo']>= monto):
                    print(f"Transferencia de cbu origen: {datos['cbu']}\n a cbu destino: {cuenta}")
                    print(f"Por un monto de: {monto}")
                    print(f"Operación EXITOSA")
                    datos['saldo']=datos['saldo']-monto
                    movimientos.append("Transferencia de pesos a otra cuenta")
                else:
                    print("SALDO INSUFICIENTE para realizar la operación")
            else:
                print("Numero de cuenta incorrecta")

        elif divisa==2:

            cuenta=input("Ingrese el cbu de destino: ")
            if len(cuenta)==22:
                monto = int(input("Ingrese el monto a trasferir: "))
                if(datos['saldoDolar']>= monto):
                    print(f"Transferencia de cbu origen: {datos['cbu']}\n a cbu destino: {cuenta}")
                    print(f"Por un monto de: {monto}")
                    print(f"Operación EXITOSA")
                    datos['saldoDolar']=datos['saldoDolar']-monto
                    movimientos.append("Transferencia de dolares a cuenta de tercero")
                else:
                    print("SALDO INSUFICIENTE para realizar la operación")
            else:
                print("Numero de cuenta incorrecta")

        else:
            print("Opcioón no valida")
    if op==5:
        print("---------------COMPRA DE DOLARES-----------")
        print(f"Cotizacion del Dolar hoy: {dolar}")
        monto = int(input("Ingrese la cantidad de dolares que quiere comprar: "))
        if(datos['saldo']>= monto * dolar):
            datos['saldoDolar']+= monto
            datos['saldo']-=(monto * dolar)
            print("La Operación se completo con EXITO")
            movimientos.append("Compra de dolares")
        else:
            print("Los fondos no son suficiente")
    if op==6:
        print("---------------VENTA DE DOLARES-----------")
        print(f"Cotizacion del Dolar hoy: {dolar}")
        print(f"Su saldo en dolares actual es: {datos['saldoDolar']}")
        monto = int(input("Ingrese la cantidad de dolares que quiere vender: "))
        if(datos['saldoDolar']>= monto):
            datos['saldoDolar']-= monto
            datos['saldo']+=(monto * dolar)
            print("La Operación se completo con EXITO")
            movimientos.append("Venta de dolares")
        else:
            print("Los fondos no son suficiente")
    if op==7:
        print("------------CONSTITUIR PLAZO FIJO-----------")
        print("Constitucion de Plazo fijo")
        pf = {}
        pf['f_ini']="25-01-2023"
        pf['f_fin']="25-02-2023"
        pf['monto'] = int(input("Ingrese el monto destinado para el PF: $"))
        datos['plazofijo'].append(pf)
        print("Su plazo fijo fue conformado correctamente")
        movimientos.append("Constitucion de plazo fijo")
        # print(f"Su saldo en Plazo Fijo: {datos['plazofijo']['monto']}")
        print("////////////////////////////////////////")
    if op==8:
        print("------------ULTIMOS MOVIMIENTOS-----------")
        for x in movimientos:
            print(f"{x}")
    if op==9:
        servicio()
    if op==10:
        fin=False
    return fin

def cajero():
    flag= True
    print("*********************")
    if(input("Ingrese Clave: "))== datos["clave"]:
        while flag:
            flag=menu()

cajero()


#! ../venv/bin/python
# -*- coding: utf-8 -*-
from enlighten import create_app
from enlighten.models import *

class TestExtractSortParams:
    def setup(self):
        app = create_app('enlighten.settings.DevConfig', env='dev')
        self.app = app.test_client()
        db.app = app

    def test_basic_sort(self):
        res = Client.grep_sort_opt("sort_by_title", "asc_1")
        assert res == ("title", "asc", 1)

        res = Client.grep_sort_opt("sort_by_not_title", "asc_1")
        assert res == (None, None, None)

    def test_build_sort(self):
        params = { 'sort_by_title': 'asc_1' }
        res = Client.build_sort_clause(params)
        assert res == "title asc"

        params = { 'sort_by_title': 'asc' }
        res = Client.build_sort_clause(params)
        assert res == "title asc"

    def test_not_build_sort(self):
        params = { 'sort_by_not_column_in_client': 'asc' }
        res = Client.build_sort_clause(params)
        assert res == ""

    def test_build_capital_sort(self):
        params = { 'sort_by_title': 'ASC_1' }
        res = Client.build_sort_clause(params)
        assert res == "title ASC"

    def test_not_match_key_build_sort(self):
        params = { 'title': 'asc' }
        res = Client.build_sort_clause(params)
        assert res == ""

    def test_build_multi_sort(self):
        params = { 'sort_by_title': 'asc_1', 'sort_by_client_code': 'desc_2' }
        res = Client.build_sort_clause(params)
        assert res == "title asc, client_code desc"

        params = { 'sort_by_title': 'asc_2', 'sort_by_client_code': 'desc_1' }
        res = Client.build_sort_clause(params)
        assert res == "client_code desc, title asc"


import unittest

import numpy as np
import pandas as pd

from pyspark import pandas as ps
from pyspark.testing.pandasutils import ComparisonTestBase
from pyspark.testing.sqlutils import SQLTestUtils

class FrameRenameMixin:
    @property
    def pdf(self):
        return pd.DataFrame(
            {"a": [1, 2, 3, 4, 5, 6, 7, 8, 9], "b": [4, 5, 6, 3, 2, 1, 0, 0, 0]},
            index=np.random.rand(9),
        )

    @property
    def df_pair(self):
        pdf = self.pdf
        psdf = ps.from_pandas(pdf)
        return pdf, psdf

    def test_rename_dataframe(self):
        pdf1 = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
        psdf1 = ps.from_pandas(pdf1)

        self.assert_eq(
            psdf1.rename(columns={"A": "a", "B": "b"}), pdf1.rename(columns={"A": "a", "B": "b"})
        )

        result_psdf = psdf1.rename(index={1: 10, 2: 20})
        result_pdf = pdf1.rename(index={1: 10, 2: 20})
        self.assert_eq(result_psdf, result_pdf)

        # inplace
        pser = result_pdf.A
        psser = result_psdf.A
        result_psdf.rename(index={10: 100, 20: 200}, inplace=True)
        result_pdf.rename(index={10: 100, 20: 200}, inplace=True)
        self.assert_eq(result_psdf, result_pdf)
        self.assert_eq(psser, pser)

        def str_lower(s) -> str:
            return str.lower(s)

        self.assert_eq(
            psdf1.rename(str_lower, axis="columns"), pdf1.rename(str_lower, axis="columns")
        )

        def mul10(x) -> int:
            return x * 10

        self.assert_eq(psdf1.rename(mul10, axis="index"), pdf1.rename(mul10, axis="index"))

        self.assert_eq(
            psdf1.rename(columns=str_lower, index={1: 10, 2: 20}),
            pdf1.rename(columns=str_lower, index={1: 10, 2: 20}),
        )

        self.assert_eq(
            psdf1.rename(columns=lambda x: str.lower(x)),
            pdf1.rename(columns=lambda x: str.lower(x)),
        )

        idx = pd.MultiIndex.from_tuples([("X", "A"), ("X", "B"), ("Y", "C"), ("Y", "D")])
        pdf2 = pd.DataFrame([[1, 2, 3, 4], [5, 6, 7, 8]], columns=idx)
        psdf2 = ps.from_pandas(pdf2)

        self.assert_eq(psdf2.rename(columns=str_lower), pdf2.rename(columns=str_lower))
        self.assert_eq(
            psdf2.rename(columns=lambda x: str.lower(x)),
            pdf2.rename(columns=lambda x: str.lower(x)),
        )

        self.assert_eq(
            psdf2.rename(columns=str_lower, level=0), pdf2.rename(columns=str_lower, level=0)
        )
        self.assert_eq(
            psdf2.rename(columns=str_lower, level=1), pdf2.rename(columns=str_lower, level=1)
        )

        pdf3 = pd.DataFrame([[1, 2], [3, 4], [5, 6], [7, 8]], index=idx, columns=list("ab"))
        psdf3 = ps.from_pandas(pdf3)

        self.assert_eq(psdf3.rename(index=str_lower), pdf3.rename(index=str_lower))
        self.assert_eq(
            psdf3.rename(index=str_lower, level=0), pdf3.rename(index=str_lower, level=0)
        )
        self.assert_eq(
            psdf3.rename(index=str_lower, level=1), pdf3.rename(index=str_lower, level=1)
        )

        pdf4 = pdf2 + 1
        psdf4 = psdf2 + 1
        self.assert_eq(psdf4.rename(columns=str_lower), pdf4.rename(columns=str_lower))

        pdf5 = pdf3 + 1
        psdf5 = psdf3 + 1
        self.assert_eq(psdf5.rename(index=str_lower), pdf5.rename(index=str_lower))

        msg = "Either `index` or `columns` should be provided."
        with self.assertRaisesRegex(ValueError, msg):
            psdf1.rename()
        msg = "`mapper` or `index` or `columns` should be either dict-like or function type."
        with self.assertRaisesRegex(ValueError, msg):
            psdf1.rename(mapper=[str_lower], axis=1)
        msg = "Mapper dict should have the same value type."
        with self.assertRaisesRegex(ValueError, msg):
            psdf1.rename({"A": "a", "B": 2}, axis=1)
        msg = r"level should be an integer between \[0, column_labels_level\)"
        with self.assertRaisesRegex(ValueError, msg):
            psdf2.rename(columns=str_lower, level=2)
        msg = r"level should be an integer between \[0, 2\)"
        with self.assertRaisesRegex(ValueError, msg):
            psdf3.rename(index=str_lower, level=2)

    def test_rename_axis(self):
        index = pd.Index(["A", "B", "C"], name="index")
        columns = pd.Index(["numbers", "values"], name="cols")
        pdf = pd.DataFrame([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], index=index, columns=columns)
        psdf = ps.from_pandas(pdf)

        for axis in [0, "index"]:
            self.assert_eq(
                pdf.rename_axis("index2", axis=axis).sort_index(),
                psdf.rename_axis("index2", axis=axis).sort_index(),
            )
            self.assert_eq(
                pdf.rename_axis(["index2"], axis=axis).sort_index(),
                psdf.rename_axis(["index2"], axis=axis).sort_index(),
            )

        for axis in [1, "columns"]:
            self.assert_eq(
                pdf.rename_axis("cols2", axis=axis).sort_index(),
                psdf.rename_axis("cols2", axis=axis).sort_index(),
            )
            self.assert_eq(
                pdf.rename_axis(["cols2"], axis=axis).sort_index(),
                psdf.rename_axis(["cols2"], axis=axis).sort_index(),
            )

        pdf2 = pdf.copy()
        psdf2 = psdf.copy()
        pdf2.rename_axis("index2", axis="index", inplace=True)
        psdf2.rename_axis("index2", axis="index", inplace=True)
        self.assert_eq(pdf2.sort_index(), psdf2.sort_index())

        self.assertRaises(ValueError, lambda: psdf.rename_axis(["index2", "index3"], axis=0))
        self.assertRaises(ValueError, lambda: psdf.rename_axis(["cols2", "cols3"], axis=1))
        self.assertRaises(TypeError, lambda: psdf.rename_axis(mapper=["index2"], index=["index3"]))
        self.assertRaises(ValueError, lambda: psdf.rename_axis(ps))

        self.assert_eq(
            pdf.rename_axis(index={"index": "index2"}, columns={"cols": "cols2"}).sort_index(),
            psdf.rename_axis(index={"index": "index2"}, columns={"cols": "cols2"}).sort_index(),
        )

        self.assert_eq(
            pdf.rename_axis(index={"missing": "index2"}, columns={"missing": "cols2"}).sort_index(),
            psdf.rename_axis(
                index={"missing": "index2"}, columns={"missing": "cols2"}
            ).sort_index(),
        )

        self.assert_eq(
            pdf.rename_axis(index=str.upper, columns=str.upper).sort_index(),
            psdf.rename_axis(index=str.upper, columns=str.upper).sort_index(),
        )

        index = pd.MultiIndex.from_tuples(
            [("A", "B"), ("C", "D"), ("E", "F")], names=["index1", "index2"]
        )
        columns = pd.MultiIndex.from_tuples(
            [("numbers", "first"), ("values", "second")], names=["cols1", "cols2"]
        )
        pdf = pd.DataFrame([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], index=index, columns=columns)
        psdf = ps.from_pandas(pdf)

        for axis in [0, "index"]:
            self.assert_eq(
                pdf.rename_axis(["index3", "index4"], axis=axis).sort_index(),
                psdf.rename_axis(["index3", "index4"], axis=axis).sort_index(),
            )

        for axis in [1, "columns"]:
            self.assert_eq(
                pdf.rename_axis(["cols3", "cols4"], axis=axis).sort_index(),
                psdf.rename_axis(["cols3", "cols4"], axis=axis).sort_index(),
            )

        self.assertRaises(
            ValueError, lambda: psdf.rename_axis(["index3", "index4", "index5"], axis=0)
        )
        self.assertRaises(ValueError, lambda: psdf.rename_axis(["cols3", "cols4", "cols5"], axis=1))

        self.assert_eq(
            pdf.rename_axis(index={"index1": "index3"}, columns={"cols1": "cols3"}).sort_index(),
            psdf.rename_axis(index={"index1": "index3"}, columns={"cols1": "cols3"}).sort_index(),
        )

        self.assert_eq(
            pdf.rename_axis(index={"missing": "index3"}, columns={"missing": "cols3"}).sort_index(),
            psdf.rename_axis(
                index={"missing": "index3"}, columns={"missing": "cols3"}
            ).sort_index(),
        )

        self.assert_eq(
            pdf.rename_axis(
                index={"index1": "index3", "index2": "index4"},
                columns={"cols1": "cols3", "cols2": "cols4"},
            ).sort_index(),
            psdf.rename_axis(
                index={"index1": "index3", "index2": "index4"},
                columns={"cols1": "cols3", "cols2": "cols4"},
            ).sort_index(),
        )

        self.assert_eq(
            pdf.rename_axis(index=str.upper, columns=str.upper).sort_index(),
            psdf.rename_axis(index=str.upper, columns=str.upper).sort_index(),
        )

class FrameRenameTests(FrameRenameMixin, ComparisonTestBase, SQLTestUtils):
    pass

if __name__ == "__main__":
    from pyspark.pandas.tests.indexes.test_rename import *  # noqa: F401

    try:
        import xmlrunner

        testRunner = xmlrunner.XMLTestRunner(output="target/test-reports", verbosity=2)
    except ImportError:
        testRunner = None
    unittest.main(testRunner=testRunner, verbosity=2)


from matplotlib import pyplot as plt
import numpy as np

def plot_ft(fname):
    data = []

    # with open(fname, 'r') as infile:
    #     for line in infile:
    #         splitted = line.split(",")[:-1]
    #         data = [float(v) for v in splitted]

    data = np.loadtxt(fname, delimiter=",")

    L = int(np.sqrt(len(data)))
    data = np.reshape(data, (L, -1))

    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.imshow(np.log(data))
    plt.show()

plot_ft("data/conc_ft.csv")


# os, stat , errno
import os, stat, errno
# argparse
import argparse
# subprocess
import subprocess
import shlex

# import config.py
from config import *

### ARGS ###
def intNotNull(string):
	try:
		val = int(string)
		if val > 0:
			return string
		else:
			msg = "%r can't be null, zero or negative, try again" % string
			raise argparse.ArgumentTypeError(msg)
	except ValueError:
		msg = "ERROR: %r  - scale must be a number, try again" % string
		print(msg)

def CheckIsDir(directory):
	try:
		return stat.S_ISDIR(os.stat(directory).st_mode)
	except OSError as e:
		if e.errno == errno.ENOENT:
			return False
		raise

def dirExists(string):
	try:
		if CheckIsDir(string):
			return string
		else:
			msg = "%r doesn't exists" % string
			raise argparse.ArgumentTypeError(msg)
	except ValueError:
		msg = "ERROR: %r  - data_path must be a valid directory, try again" % string
		print(msg)

# parser of arguments on command line
parser = argparse.ArgumentParser()
#ordered arguments
parser.add_argument('scale', type=intNotNull, help="integer value to be used when invoking dbgen")
parser.add_argument('data_path', type=dirExists, help="filesystem directory that will contain the files that qgen will generate.")
parser.add_argument('db_name', help="name of database that contains the empty TPC-H tables.")

# parse the args
args = parser.parse_args()
### ARGS ###

### MAIN ###
def __main__():
	# DEBUG
	#print(DBGEN.ARGS)
	#print(PSQL.DATABASE)
	#for i in PSQL.DATABASE_TABLES:
	#	print (i)
	print(args)
	# DEBUG

	# execute DBGEN with the scale
	runDbgen(args.scale)

	# execute TBL2CSV
	runTbl2Csv(DBGEN.PATH,args.data_path)

	# execute runDropConstraints
	runDropConstraints(args.db_name)

	# execute runTruncate
	runTruncate(args.db_name)

	# execute runLoad
	runLoad(args.data_path, args.db_name)

	# execute runAddConstraints
	runAddConstraints(args.db_name)

### MAIN ###

### DBGEN ###
# desc: function to execute the DBGEN program with the args passed
# return: output of the subprocess's STDOUT
def runDbgen(scale):
	print('runDbgen('+scale+'): START')

	# create a new object instance of the DBGEN class
	dbgen1 = DBGEN()
	# set the dbgen.ARGS to the value provided
	dbgen1.ARGS += scale
	# set the command
	command = dbgen1.PATH+"/"+dbgen1.BIN+" -v -f "+dbgen1.ARGS
	command = shlex.split(command)

	# subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, cwd=None, encoding=None, errors=None, universal_newlines=False, timeout=None)
	try:
		output = subprocess.check_output(command, cwd=dbgen1.PATH)
		success = True
	except subprocess.CalledProcessError as e:
		print('Handling run-time error:', e)
		success = False
		raise e

	print('runDbgen('+scale+'): END')

### DBGEN ###

### TBL2CSV ###
# desc: function to transform TBL files to CSV file to be ready to load them into POSTGRES DB
# return: output of the subprocess's STDOUT
def runTbl2Csv(src,dst):
	print('runTbl2Csv('+src+','+dst+'): START')
	# create a new object instance of the TBL2CSV class
	tbl2csv1 = TBL2CSV()
	# set the command
	command = tbl2csv1.PATH+"/"+tbl2csv1.BIN+" "+src+" "+dst
	command = shlex.split(command)

	# subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, cwd=None, encoding=None, errors=None, universal_newlines=False, timeout=None)
	try:
		output = subprocess.check_output(command, cwd=tbl2csv1.PATH,universal_newlines=True)
		print(output)
		success = True
	except subprocess.CalledProcessError as e:
		print('Handling run-time error:', e)
		success = False
		raise e

	print('runTbl2Csv('+src+','+dst+'): END')

### TBL2CSV ###

### runDropConstraints(database) ###
# desc: function to remove constraints
# return: output of the subprocess's STDOUT
def runDropConstraints(database):
	print('runDropConstraints('+database+'): START')
	# create a new object instance of the PSQL class
	psql1 = PSQL()
	# create a new object instance of the CONSTRAINT class
	constraint1 = CONSTRAINT()
	# set the command
	command = "sudo -u "+psql1.USER+" "+psql1.BIN+" -f "+constraint1.PATH+"/"+constraint1.BIN_DROP+" "+database

	# subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None)
	try:
		output = subprocess.run([command], stdout=subprocess.PIPE, cwd=constraint1.PATH,universal_newlines=True, shell=True)
		print (output)
		success = True
	except subprocess.CalledProcessError as e:
		print('Handling run-time error:', e)
		success = False
		raise e

	print('runDropConstraints('+database+'): END')
### runDropConstraints(database) ###

### runTruncate(database) ###
# desc: function to remove constraints
# return: output of the subprocess's STDOUT
def runTruncate(database):
	print('runTruncate('+database+'): START')
	# create a new object instance of the PSQL class
	psql1 = PSQL()
	# create a new object instance of the TRUNCATE class
	truncate1 = TRUNCATE()
	# set the command
	command = "sudo -u "+psql1.USER+" "+psql1.BIN+" -f "+truncate1.PATH+"/"+truncate1.BIN+" "+database

	# subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None)
	try:
		output = subprocess.run([command], stdout=subprocess.PIPE, cwd=truncate1.PATH,universal_newlines=True, shell=True)
		print (output)
		success = True
	except subprocess.CalledProcessError as e:
		print('Handling run-time error:', e)
		success = False
		raise e

	print('runTruncate('+database+'): END')
### runTruncate(database) ###

### runLoad(data_path,database) ###
# desc: function to Load CSV files from data_path  to database
# return: output of the subprocess's STDOUT
def runLoad(data_path,database):
	print('runLoad('+data_path+','+database+'): START')
	# create a new object instance of the PSQL class
	psql1 = PSQL()
	# create a new object instance of the LOAD class
	load1 = LOAD()
	# set the command
	command = "sudo -u "+psql1.USER+" "+psql1.BIN+" -f "+load1.PATH+"/"+load1.BIN+" "+database

	# subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None)
	try:
		output = subprocess.run([command], stdout=subprocess.PIPE, cwd=load1.PATH,universal_newlines=True, shell=True)
		print (output)
		success = True
	except subprocess.CalledProcessError as e:
		print('Handling run-time error:', e)
		success = False
		raise e

	print('runLoad('+data_path+','+database+'): END')
### runLoad(database) ###

### runAddConstraints(database) ###
# desc: function to remove constraints
# return: output of the subprocess's STDOUT
def runAddConstraints(database):
	print('runAddConstraints('+database+'): START')
	# create a new object instance of the PSQL class
	psql1 = PSQL()
	# create a new object instance of the CONSTRAINT class
	constraint1 = CONSTRAINT()
	# set the command
	command = "sudo -u "+psql1.USER+" "+psql1.BIN+" -f "+constraint1.PATH+"/"+constraint1.BIN_ADD+" "+database
	print(command)
	# subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None)
	try:
		output = subprocess.run([command], stdout=subprocess.PIPE, cwd=constraint1.PATH,universal_newlines=True, shell=True)
		print (output)
		success = True
	except subprocess.CalledProcessError as e:
		print('Handling run-time error:', e)
		success = False
		raise e

	print('runAddConstraints('+database+'): END')
### runAddConstraints(database) ###

__main__()


from dash import Dash, html, dcc
import dash_mantine_components as dmc
from dash.dependencies import Input, Output
from dash_iconify import DashIconify

import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# import plotly.express as px

from ...data.loader import ProductionDataSchema
from ...data.source import DataSource
from .. import ids, cns

def render(app: Dash, source: DataSource) -> html.Div:
    @app.callback(
        Output(ids.OIL_VS_WATER_SUBPLOTS, "children"),
        [
            Input(ids.FROM_DATE_DATEPICKER,  "value"),
            Input(ids.TO_DATE_DATEPICKER,    "value"),
            Input(ids.WELL_MAIN_MULTISELECT, "value"),
        ],  prevent_initial_call=True
    )

    def update_subplots(from_date: str, to_date: str, wells: list[str]) -> html.Div:

        filtered_pt_oil_date = source.filter(from_date=from_date, to_date=to_date, wells=wells).create_pivot_table_date(ProductionDataSchema.BORE_OIL_VOL)
        filtered_pt_wtr_date = source.filter(from_date=from_date, to_date=to_date, wells=wells).create_pivot_table_date(ProductionDataSchema.BORE_WAT_VOL)

        # Initialize figure with subplots
        figure = make_subplots(
                    rows=1, cols=1,
                    # column_widths=[0.5, 0.5],
                    # row_heights=[0.5, 0.5],
                    specs=[
                        [{"type": "scatter"}],
                    ]
                )

        # line chart for BORE_OIL_VOL
        figure.add_trace(
            go.Scatter(
                name="Total Oil Volume",
                x=filtered_pt_oil_date[ProductionDataSchema.DATE],
                y=filtered_pt_oil_date[ProductionDataSchema.BORE_OIL_VOL],
                mode='lines',
                # fill='tozeroy',  # Set fill to 'tozeroy' for area below the line
                line={'color': '#f2b705'},
                showlegend=True
                ),
                row=1, col=1
            )

        # line chart for BORE_WAT_VOL
        figure.add_trace(
            go.Scatter(
                name="Total Water Volume",
                x=filtered_pt_wtr_date[ProductionDataSchema.DATE],
                y=filtered_pt_wtr_date[ProductionDataSchema.BORE_WAT_VOL],
                mode='lines',
                # fill='tozeroy',  # Set fill to 'tozeroy' for area below the line
                line={'color': '#03a6a6'},
                showlegend=True
                ),
                row=1, col=1
            )

        # Set theme, margin, and annotation in layout
        figure.update_layout(
            title='Oil and Water Total Rate by Time (Yearly, Monthly, Daily)',
            xaxis_title='Date'
        )

        # Set y-axis titles
        figure.update_yaxes(title_text="Total Vol.(Sm3)",
                            title_font_size=12,)

        figure.update_layout(
            height=200,
            autosize=True,  # Allow the figure to be autosized
            margin=dict(l=10, r=10, t=60, b=10),  # Adjust the margins for the figure
            legend=dict(
                x=0.85,   # Set the x position of the legend (0.5 means centered horizontally)
                y=1.15,   # Set the y position of the legend (1.0 means at the top)
                xanchor='center',  # Anchor point for the x position ('center' for center alignment)
                yanchor='top',     # Anchor point for the y position ('top' for top alignment)
                orientation='h',   # Orientation of the legend ('h' for horizontal)
                bgcolor='rgba(255, 255, 255, 0.5)',  # Background color of the legend (with transparency)
                # bordercolor='rgba(0, 0, 0, 0.5)',     # Border color of the legend (with transparency)
                # borderwidth=1       # Border width of the legend
            ),
        )

        return html.Div(dcc.Graph(figure=figure), id=ids.OIL_VS_WATER_SUBPLOTS, className=cns.PPD_FOURTH_CHART_RIGHT_GRID)

    return html.Div(id=ids.OIL_VS_WATER_SUBPLOTS, className=cns.PPD_FOURTH_CHART_RIGHT_GRID)


import json
from datetime import timedelta
from django.conf import settings
from django.template import loader
from django.utils.timezone import now
from django.utils.translation import activate, get_language, ugettext_lazy as _
from reversion import create_revision

from shuup.core.models import PersonContact
from shuup.simple_cms.models import Page
from shuup.utils.django_compat import force_text
from shuup.utils.i18n import format_datetime

def add_consent_to_response_cookie(response, cookie_data):
    response.set_cookie(
        key=settings.SHUUP_GDPR_CONSENT_COOKIE_NAME,
        value=json.dumps(cookie_data),
        domain=settings.SESSION_COOKIE_DOMAIN,
        secure=settings.SESSION_COOKIE_SECURE or None,
        expires=now() + timedelta(days=365 * 3),
    )

def get_cookie_consent_data(cookie_categories, consent_documents):
    """
    :param list[GDPRCookieCategory] cookie_categories: list of cookie category
    """
    consent_cookies = [cookie_category.cookies for cookie_category in cookie_categories]
    return {
        "cookies": list(set(",".join(consent_cookies).replace(" ", "").split(","))),
        "documents": [dict(id=doc.id, url=doc.url) for doc in consent_documents],
    }

def get_all_contact_data(shop, contact):
    from shuup.apps.provides import get_provide_objects
    from shuup.gdpr.providers import GDPRBaseUserDataProvider

    user_data = {}
    for gdpr_user_data_provider in get_provide_objects("gdpr_user_data_provider"):
        if not isinstance(gdpr_user_data_provider, GDPRBaseUserDataProvider):
            continue

        user = None
        if isinstance(contact, PersonContact):
            user = contact.user
        for key, data in gdpr_user_data_provider.get_user_data(shop=shop, contact=contact, user=user):
            user_data[key] = data

    return user_data

def ensure_gdpr_privacy_policy(shop, force_update=False):
    from shuup.gdpr.models import GDPRSettings
    from shuup.simple_cms.models import Page

    gdpr_document = get_privacy_policy_page(shop)
    current_language = get_language()

    if force_update or not gdpr_document:
        now_date = now()
        company_name = shop.public_name or shop.name
        address = shop.contact_address
        full_address = ""
        if address:
            full_address = ", ".join(
                [
                    item
                    for item in [
                        company_name,
                        address.street,
                        address.city,
                        address.region_code,
                        address.postal_code,
                        address.country.code,
                    ]
                    if item
                ]
            )
        context = {
            "last_updated": format_datetime(now(), "LLLL dd, YYYY").capitalize(),
            "company_name": company_name,
            "full_address": full_address,
            "store_email": address.email if address else "",
        }
        content = loader.render_to_string(template_name="shuup/admin/gdpr/privacy_policy_page.jinja", context=context)
        created = False
        if not gdpr_document:
            with create_revision():
                gdpr_document = Page.objects.create(
                    shop=shop,
                    content=content,
                    available_from=now_date,
                    title=force_text(_("Privacy Policy")),
                    url=settings.GDPR_PRIVACY_POLICY_PAGE_URLS.get(current_language, "privacy-policy"),
                )
                created = True
            gdpr_settings = GDPRSettings.get_for_shop(shop)
            gdpr_settings.privacy_policy_page = gdpr_document
            gdpr_settings.save()

        # update only if it was created
        if created or force_update:
            for code, language in settings.LANGUAGES:
                if code == current_language:
                    continue
                url = settings.GDPR_PRIVACY_POLICY_PAGE_URLS.get(code)
                if not url:
                    continue

                activate(code)
                content = loader.render_to_string(
                    template_name="shuup/admin/gdpr/privacy_policy_page.jinja", context=context
                )
                gdpr_document.set_current_language(code)
                gdpr_document.title = force_text(_("Privacy Policy"))
                gdpr_document.url = url
                gdpr_document.content = content
                gdpr_document.save()

    # return to old language
    activate(current_language)
    gdpr_document.set_current_language(current_language)
    return gdpr_document

def create_initial_required_cookie_category(shop):
    from shuup.gdpr.models import GDPRCookieCategory

    if not GDPRCookieCategory.objects.filter(shop=shop).exists():
        cookie_category = GDPRCookieCategory.objects.create(
            shop=shop,
            always_active=True,
            cookies="sessionid,csrftoken,shuup_gdpr_consent,rvp",
            name=_("Required"),
            how_is_used=_(
                "We use these cookies to ensure the correct language is being "
                "chosen for you based on your region as well as the overall site functionality."
            ),
        )
        current_language = get_language()
        for code, language in settings.LANGUAGES:
            if code == current_language:
                continue
            activate(code)
            cookie_category.set_current_language(code)
            cookie_category.name = _("Required")
            cookie_category.how_is_used = _(
                "We use these cookies to ensure the correct language is being "
                "chosen for you based on your region as well as the overall site functionality."
            )
            cookie_category.save()
        activate(current_language)
        cookie_category.set_current_language(current_language)

def should_reconsent_privacy_policy(shop, user):
    from shuup.gdpr.models import GDPRUserConsent

    consent = GDPRUserConsent.objects.filter(shop=shop, user=user).first()
    if not consent:
        return False
    privacy_policy = get_privacy_policy_page(shop)
    if not privacy_policy:
        return False
    return consent.should_reconsent_to_page(privacy_policy)

def is_documents_consent_in_sync(shop, user):
    """
    Returns whether the user has consent to the lastest document versions
    """
    from shuup.gdpr.models import GDPRSettings

    gdpr_settings = GDPRSettings.get_for_shop(shop)
    if not gdpr_settings.enabled:
        return True  # nothing to do.

    from shuup.gdpr.models import GDPRUserConsent

    last_user_consent = GDPRUserConsent.get_for_user(user, shop)
    if not last_user_consent:
        return False
    return not last_user_consent.should_reconsent(shop, user)

def create_user_consent_for_all_documents(shop, user):
    """
    Create user consent for all available GDPR documents
    """
    from shuup.gdpr.models import GDPRSettings, GDPRUserConsent

    gdpr_settings = GDPRSettings.get_for_shop(shop)
    if not gdpr_settings.enabled or is_documents_consent_in_sync(shop, user):
        return

    consent_documents = get_active_consent_pages(shop)
    return GDPRUserConsent.ensure_for_user(user, shop, consent_documents)

def get_possible_consent_pages(shop):
    return Page.objects.filter(shop=shop, deleted=False)

def get_active_consent_pages(shop):
    from shuup.gdpr.models import GDPRSettings

    gdpr_settings = GDPRSettings.get_for_shop(shop)
    if not gdpr_settings.enabled:
        return []  # nothing to do.
    ids = [page.id for page in gdpr_settings.consent_pages.all()]
    if gdpr_settings.privacy_policy_page:
        ids.append(gdpr_settings.privacy_policy_page.pk)
    return Page.objects.filter(pk__in=set(ids))

def get_privacy_policy_page(shop):
    from shuup.gdpr.models import GDPRSettings

    gdpr_settings = GDPRSettings.get_for_shop(shop)
    if not gdpr_settings.enabled:
        return None
    return gdpr_settings.privacy_policy_page


#Faça um algoritmo para calcular a conta de energia elétrica de uma casa. O valor de cada KWH é 1.5. Quando a casa é de uma aposentada, a conta tem um desconto de 15%.

perfilUsuario = str(input('O cliente é aposentado? (S/N): '))
energiaConsumida = float(input('Digite o consumo de energia de uma casa: '))
aPagar = float(energiaConsumida * 1.5)
perfilUsuario.upper()

if perfilUsuario == "S":
    print('O cliente é aposentado e pagará R$ {0:.2f} na fatura da conta de luz.'.format(aPagar - (aPagar * .15)))
else:
    print('O cliente não é aposentado e pagará R$ {0:.2f} na fatura da conta de luz.'.format(aPagar))


from abc import ABC, abstractmethod
from typing import Union

import numpy as np
import tensorflow as tf
from scipy.ndimage import rotate, zoom

class InputModifier(ABC):
    """Abstract class for defining an input modifier.
    """
    @abstractmethod
    def __call__(self, seed_input) -> Union[np.ndarray, tf.Tensor]:
        """Implement modification to the input before processing gradient descent.

        Args:
            seed_input: An :obj:`numpy.ndarray` or a tf.Tensor that indicates a value to input to
                model.

        Returns:
            An :obj:`numpy.ndarray` or a tf.Tensor.

        Raises:
            NotImplementedError: This method must be overwritten.
        """
        raise NotImplementedError()

class Jitter(InputModifier):
    """An input modifier that introduces random jitter.
        Jitter has been shown to produce crisper activation maximization images.
    """
    def __init__(self, jitter=8) -> None:
        """
        Args:
            jitter: The amount of jitter to apply. Defaults to 8.
        """
        self.jitter = int(jitter)

    def __call__(self, seed_input) -> np.ndarray:
        ndim = len(seed_input.shape)
        if ndim < 3:
            raise ValueError("The dimensions of seed_input must be 3 or more "
                             f"(batch_size, ..., channels), but was {ndim}.")
        seed_input = tf.roll(seed_input,
                             shift=tuple(np.random.randint(-self.jitter, self.jitter, ndim - 2)),
                             axis=tuple(range(ndim)[1:-1]))
        return seed_input

class Rotate(InputModifier):
    """An input modifier that introduces random rotation.
    """
    def __init__(self, axes=(1, 2), degree=3.0) -> None:
        """
        Args:
            axes: The two axes that define the plane of rotation.
                Defaults to (1, 2).
            degree: The amount of rotation to apply. Defaults to 3.0.

        Raises:
            ValueError: When axes is not a tuple of two ints.
        """
        if type(axes) not in [list, tuple] or len(axes) != 2:
            raise ValueError(f"`axes` must be a tuple of two int values, but it was {axes}.")
        if not isinstance(axes[0], int) or not isinstance(axes[1], int):
            raise TypeError(f"`axes` must be consist of ints, but it was {axes}.")
        self.axes = axes
        self.degree = float(degree)
        self.random_generator = np.random.default_rng()

    def __call__(self, seed_input) -> np.ndarray:
        ndim = len(seed_input.shape)
        if ndim < 4:
            raise ValueError("The dimensions of seed_input must be 4 or more "
                             f"(batch_size, ..., channels), but was {ndim}.")
        if tf.is_tensor(seed_input):
            seed_input = seed_input.numpy()
        seed_input = rotate(seed_input,
                            self.random_generator.uniform(-self.degree, self.degree),
                            axes=self.axes,
                            reshape=False,
                            order=1,
                            mode='reflect',
                            prefilter=False)
        return seed_input

class Rotate2D(Rotate):
    """An input modifier for 2D that introduces random rotation.
    """
    def __init__(self, degree=3.0) -> None:
        """
        Args:
            degree: The amount of rotation to apply. Defaults to 3.0.
        """
        super().__init__(axes=(1, 2), degree=degree)

class Scale(InputModifier):
    """An input modifier that introduces randam scaling.
    """
    def __init__(self, low=0.9, high=1.1) -> None:
        """
        Args:
            low (float, optional): Lower boundary of the zoom factor. Defaults to 0.9.
            high (float, optional): Higher boundary of the zoom factor. Defaults to 1.1.
        """
        self.low = low
        self.high = high
        self.random_generator = np.random.default_rng()

    def __call__(self, seed_input) -> np.ndarray:
        ndim = len(seed_input.shape)
        if ndim < 3:
            raise ValueError("The dimensions of seed_input must be 3 or more "
                             f"(batch_size, ..., channels), but was {ndim}.")
        if tf.is_tensor(seed_input):
            seed_input = seed_input.numpy()
        shape = seed_input.shape
        _factor = factor = self.random_generator.uniform(self.low, self.high)
        factor *= np.ones(ndim - 2)
        factor = (1, ) + tuple(factor) + (1, )
        seed_input = zoom(seed_input, factor, order=1, mode='reflect', prefilter=False)
        if _factor > 1.0:
            indices = (self._central_crop_range(x, e) for x, e in zip(seed_input.shape, shape))
            indices = (slice(start, stop) for start, stop in indices)
            seed_input = seed_input[tuple(indices)]
        if _factor < 1.0:
            pad_width = [self._pad_width(x, e) for x, e in zip(seed_input.shape, shape)]
            seed_input = np.pad(seed_input, pad_width, 'mean')
        return seed_input

    def _central_crop_range(self, x, e):
        start = (x - e) // 2
        stop = start + e
        return start, stop

    def _pad_width(self, x, e):
        diff = e - x
        before = diff // 2
        after = diff - before
        return before, after


import serial
from time import process_time

# Defining the Arduino port
#arduino_port = "COM4"
arduino_port = "/dev/cu.wchusbserial54750076121"

# Baud rate
baud = 115200

# File name for the .csv file
file_name = "python_scripts/test1.csv"

# Start the serial port
ser = serial.Serial(port = arduino_port, baudrate = baud, timeout = 0.0005)
print("Connected to Arduino port: " + arduino_port)

# Open the csv file
file = open(file_name, "a+")
print("Created file: " + file_name)

# Sensor data string
sensor_data_str = ""
sensor_data = []

# Start the process
start_time = process_time()
print("Data measurement starts now!")

# Take measurements for 3 minutes
while (process_time() - start_time) < 180.0:
    if(ser.inWaiting() > 0):
        sensor_data_str += ser.read(ser.inWaiting()).decode('utf-8')

print("Measurement complete")

with open(file_name, 'w', encoding='UTF8') as f:
    f.write("top, topMid, botMid, bot\n")
    f.write(sensor_data_str.replace(";", "\n"))

print("CSV file complete")
file.close()


class Solution:
    def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:
        queue = deque([(0, 0, 1)])
        n = len(grid)
        visited = set()

        deltas = [(0, -1), (-1, 0), (0, 1), (1, 0), (-1, -1), (-1, 1), (1, -1), (1, 1)]
        while queue:
            i, j, cost = queue.popleft()
            if i < 0 or i >= n or j < 0 or j >= n or (i, j) in visited or grid[i][j] != 0:
                continue

            visited.add((i, j))
            if i == n - 1 and j == n - 1:
                return cost
            else:
                for delta in deltas:
                    queue.append((i + delta[0], j + delta[1], cost + 1))
        return -1


"""
This template code is intended to provide practice in debugging, speed
optimization, and spotting bad habits in programming. The code runs but
is deeply flawed. If you improve the code following all the best practices
you know, you'll learn something about both programming and the Central
Limit Theorem.

Author: Sheila Kannappan
Last modified: September 2019
"""

# standard imports and naming conventions; uncomment as needed
import numpy as np              # basic numerical analysis
import matplotlib.pyplot as plt # plotting
import scipy.stats as stats     # statistical functions
#import pdb                      # python debugger
#import time                     # python timekeeper

def gaussfunc(xvals, mean, sigma):
    y = np.exp(-1.*(((xvals-mean)/sigma)**2 / 2.)) # perform square once
    norm = 1./(np.sqrt(2. * np.pi) * sigma) # remove extra square operation
    y = norm * y
    return y

def poissonfunc(xvals, mean):   # move function out of loop to top of code
    prob=stats.poisson.pmf(xvals, mean) # use array math instead of loop
    return prob # note that defining this function proved entirely unnecessary,
                # could just use "stats.poisson.pmf" instead of poissonfunc

def main():
    # rename single-letter variables U, N, n -- note that "n" is a command for pdb!
    Urate = 8. # underlying rate of gym users per hour
    Nct = np.array([6, 36, 216, 1296]) # total number of people counted (powers of 6)
    nhr = Nct/Urate # time to count this many people
    # uncomment below to do array string operation
    labelarr = ["count for %s hr" % ihr for ihr in nhr]

    for i in range(0, len(Nct)):

        # plot probabilities of count values for range around mean
        mean = Nct[i]
        maxval = 2*mean
        xvals=np.arange(0, maxval)
        prob = poissonfunc(xvals, mean)
        plt.plot(xvals, prob, 'r', lw=3)
        sel = np.where(np.isclose(prob,max(prob)))
        sel = sel[0]
        nsel = np.mean(xvals[sel]) # if ties in maxprob, take mean xval
        probval = prob[sel[0]] # if ties in maxprob, just need one
        plt.text(nsel, probval, labelarr[i]) # use labelarr instead of looping over string operation
        # the lines below needed to be in the loop
        # plot Gaussian distribution with matching mean and sigma
        sigma=np.sqrt(mean)
        y = gaussfunc(xvals, mean, sigma)
        plt.plot(xvals, y, 'b')

    # these labels didn't need to be in the loop
    plt.xlabel("count value")
    plt.ylabel("probability")
    plt.xscale("log")
    plt.xlim([10,100])

if __name__ == '__main__':
    main()
    plt.show()


from django.forms import ValidationError
from . import constants
import time

def cleanUploadings():
    '''
        Will clean uploading listings after expiration
        Schedule this function with cron or any other process managers
    '''
    for k in constants.uploadings.keys():
        if time.time() - constants.uploadings.get(k).get("started_at") > constants.UPLOADING_TIMEOUT:
            del constants.uploadings[k]

def addUploadings(queryDict, videoId):
    print(f"Adding {queryDict.get('title')} in uploading list")
    try:
        constants.uploadings[str(videoId)] = {
            "title": queryDict.get("title"),
            "summary": queryDict.get("summary"),
            "started_at": time.time()
        }
    except:
        raise ValidationError(constants.ERRS.get('invalidField'))

def removeUploadings(videoId):
    del constants.uploadings[videoId]