# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import sys
from pathlib import Path
from typing import Union
from unittest.mock import Mock

from mach.site import MozSiteMetadata, SitePackagesSource

class NoopTelemetry(object):
    def __init__(self, failed_glean_import):
        self._failed_glean_import = failed_glean_import

    def metrics(self, metrics_path: Union[str, Path]):
        return Mock()

    def submit(self, is_bootstrap):
        if self._failed_glean_import and not is_bootstrap:
            active_site = MozSiteMetadata.from_runtime()
            if active_site.mach_site_packages_source == SitePackagesSource.SYSTEM:
                hint = (
                    "Mach is looking for glean in the system packages. This can be "
                    "resolved by installing it there, or by allowing Mach to run "
                    "without using the system Python packages."
                )
            elif active_site.mach_site_packages_source == SitePackagesSource.NONE:
                hint = (
                    "This is because Mach is currently configured without a source "
                    "for native Python packages."
                )
            else:
                hint = "You may need to run |mach bootstrap|."

            print(
                f"Glean could not be found, so telemetry will not be reported. {hint}",
                file=sys.stderr,
            )

class GleanTelemetry(object):
    """Records and sends Telemetry using Glean.

    Metrics are defined in python/mozbuild/metrics.yaml.
    Pings are defined in python/mozbuild/pings.yaml.

    The "metrics" and "pings" properties may be replaced with no-op implementations if
    Glean isn't available. This allows consumers to report telemetry without having
    to guard against incompatible environments.

    Also tracks whether an employee was just automatically opted into telemetry
    during this mach invocation.
    """

    def __init__(
        self,
    ):
        self._metrics_cache = {}

    def metrics(self, metrics_path: Union[str, Path]):
        if metrics_path not in self._metrics_cache:
            from glean import load_metrics

            metrics = load_metrics(metrics_path)
            self._metrics_cache[metrics_path] = metrics

        return self._metrics_cache[metrics_path]

    def submit(self, _):
        from pathlib import Path

        from glean import load_pings

        pings = load_pings(Path(__file__).parent.parent / "pings.yaml")
        pings.usage.submit()


#!/usr/bin/env python3

import numba
import numpy as np
from mytimeit import mytimeit

N = 2**27  # 2^27 * 2^3 = 1 GB
A = np.random.rand(N)

def f_numpy(A, n):
    B = np.zeros_like(A)
    for j in range(n):
        B += A**j
    return B

def f_numpy2(A, n):
    '''Avoid exponentiation; replace with telescoping sum-product.'''
    B = np.zeros_like(A)
    for j in range(n):
        B = B * A + 1.0
    return B

def f_numpy3(A, n):
    '''Avoid memory allocation; reuse existing array.'''
    B = np.zeros_like(A)
    for j in range(n):
        B *= A
        B += 1.0
    return B

@numba.vectorize
def f_numba(A, n):
    '''Avoid RAM access and let Numba vectorize this.'''
    B = 0.0
    for j in range(n):
        B = B * A + 1.0
    return B

@numba.vectorize(['float64(float64,uint64)'], target='parallel')
def f_parallel(A, n):
    '''Let Numba parallelize this as well.'''
    B = 0.0
    for j in range(n):
        B = B * A + 1.0
    return B

mytimeit('f_numpy   (A, 4)', n=1)
mytimeit('f_numpy2  (A, 4)')
mytimeit('f_numpy3  (A, 4)')
mytimeit('f_numba   (A, 4)')
mytimeit('f_parallel(A, 4)')

# vim: ts=4 sw=4 et ai sta foldmethod=indent


# first neural network with keras make predictions
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.callbacks import TensorBoard
import datetime
from sklearn.model_selection import train_test_split

layer1_sizes = [16,]
layer2_sizes = [16,32]
layer3_sizes = [8,16]
layer4_sizes = [8]
test_portion = 0.1

# load the dataset
dataset = np.loadtxt('hole-measurement/data/holes6.csv', delimiter=',')
# split into input (X) and output (y) variables
X = dataset[:,0:6]
y = dataset[:,8] / 6.0
print("X shape")
print(X.shape)
XTraining, XValidation, YTraining, YValidation = train_test_split(X,y,stratify=y,test_size=0.1) # before model building
print("X Training shape")
print(XTraining.shape)
print("X Validation shape")
print(XValidation.shape)

#print(y)
#ds_rows = X.shape[0]
#print("Number of rows: {}".format(ds_rows))
#train_rows = round(X.shape[0] * (1-test_portion))
#print("Number of rows in training set: {}".format(train_rows))
#all_ds = tf.data.Dataset.from_tensor_slices((X, y))
#all_ds = all_ds.shuffle(buffer_size=1024)
#train_ds = all_ds.take(train_rows)
#val_ds = all_ds.skip(train_rows)

for layer1_size in layer1_sizes:
    for layer2_size in layer2_sizes:
        for layer3_size in layer3_sizes:
            for layer4_size in layer4_sizes:
                NAME = "hole-size-not-proj-all-relu-normalized-{}-{}-{}-{}-".format(layer1_size, layer2_size,layer3_size, layer4_size) + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
                tensorboard_callback = TensorBoard(log_dir='logs\\fit\\'+NAME, histogram_freq=1)
                print("Iteration: " +NAME)

                # define the keras model
                model = Sequential()
                model.add(Dense(layer1_size, input_dim=6, activation='relu'))
                model.add(Dense(layer2_size, activation='relu'))
                model.add(Dense(layer3_size, activation='relu'))
                model.add(Dense(layer4_size, activation='relu'))
                model.add(Dense(1, activation='relu'))
                # compile the keras model
                print("Compiling model...")
                model.compile(loss='mean_squared_error', optimizer='adam', metrics=['mean_squared_error'])
                print("Done.")

                # fit the keras model on the dataset
                print("Fitting model...")
                history = model.fit(XTraining, YTraining, validation_data=(XValidation, YValidation), epochs=1000, verbose=0, callbacks=[tensorboard_callback])
                print("Done.")

                # make class predictions with the model
                #print("Making predictions...")
                #predictions = model.predict(X)
                #print("Done.")


# code working now
# next step is to find the most conserved spots
# figure out the meaning of each attribute; search through actual database

from Bio import SeqIO
from Bio import SwissProt
from Bio import pairwise2
from Bio import AlignIO
# Import format_alignment method
from Bio.pairwise2 import format_alignment
import itertools

# handle = open(r"/Volumes/ENDY_LAB/code_to_test_dbs/databases/test.dat")

handle = open(
    r"/Volumes/ENDY_LAB/code_to_test_dbs/databases/uniprot_sprot.dat")

# match is an int that starts at 0
# to print protein, use protein.sequence
for match, protein in enumerate(SwissProt.parse(handle)):
    g = True
    # print("Testing protein ", match+1)

    # for eachAA in protein, match:

# \n--> new line/ space for readability
    # print("\n")
    aaSet = ['Q', 'F', 'L', 'Y', 'K', 'D', 'M',
             'V', 'G', 'C', 'R', 'P', 'T', 'S', 'A']
    aaSetPrintable = ''.join(aaSet)
    # aaSetTwo = ['N','E', 'H', 'I', 'W', 'Q', 'F', 'L', 'Y', 'K', 'D', 'M', 'V', 'G', 'C', 'R', 'P', 'T', 'S', 'A']
# print statement of (-----) is used to help read the code

# protein.sequence[0+1] starts at the first letter in a sequence and increments to the next with +1
    for n in range(0, len(protein.sequence)):
            # letter +=1
            # print (len(protein.sequence))
            # print(n)
            # print("Print letter: ", match)
        if protein.sequence[n] not in aaSet:
            g = False
            # print(protein.sequence[n])
            # print(len(protein.sequence))
            # print(protein.sequence[0 + 1])
            # print(True)
            break
    if g == True and (len(protein.sequence)) >= 50:

        print("\n")
        print("Reduced amino acid set = [" + aaSetPrintable + "]")
        print("\n")

# match is an int that starts at 0; it increments everytime and counts the total number of proteins
        print("Matching Protein")
        print("Index = " + str(match+1))
        db = list(protein.sequence)
# .join turns list into strings
        print("Description = " + str(protein.description))
        print("Features = " + str(protein.features[0]))
        db = ''.join(db)
        print("Sequence = " + str(db))
        print("Length = " + str(len(protein.sequence)))
        print("\n")
        print("------------------------------------------------------------")
        # break
        # else:
        # print("\n")
# to test logic/ if failed, then uncomment the lines below
        # print(False)
        # print("Protein sequence in database: ", match+1)
        # db = list(protein.sequence)
        # db = ''.join(db);
        # print(db)
        # print("------------------------------------------------------------")


from plone.testing.z2 import ZSERVER_FIXTURE

from plone.app.testing import PloneSandboxLayer
from plone.app.testing import applyProfile
from plone.app.testing import PLONE_FIXTURE
from plone.app.testing import IntegrationTesting
from plone.app.testing import FunctionalTesting

from zope.configuration import xmlconfig

from mocker import Mocker
from mocker import ANY

class ExampleTddLayer(PloneSandboxLayer):

    defaultBases = (PLONE_FIXTURE,)

    def setUpZope(self, app, configurationContext):
        # Mock postmonkey
        mocker = Mocker()
        postmonkey = mocker.replace("postmonkey")
        mailchimp = postmonkey.PostMonkey(ANY)
        mocker.count(0, 1000)
        # Lists
        mailchimp.lists()
        mocker.count(0, 1000)
        mocker.result({
            u'total': 2,
            u'data': [{
                    u'id': 625,
                    u'web_id': 625,
                    u'name': u'ACME Newsletter',
                    u'default_from_name': u'info@acme.com',
                },
                {
                    u'id': 626,
                    u'web_id': 626,
                    u'name': u'ACME Newsletter 2',
                    u'default_from_name': u'info@acme.com',
                },
            ]})
        mocker.replay()

        # Load ZCML
        import example.tdd
        xmlconfig.file(
            'configure.zcml',
            example.tdd,
            context=configurationContext
        )

        # Install products that use an old-style initialize() function
        #z2.installProduct(app, 'Products.PloneFormGen')

#    def tearDownZope(self, app):
#        # Uninstall products installed above
#        z2.uninstallProduct(app, 'Products.PloneFormGen')

    def setUpPloneSite(self, portal):
        applyProfile(portal, 'example.tdd:default')

EXAMPLE_TDD_FIXTURE = ExampleTddLayer()
EXAMPLE_TDD_INTEGRATION_TESTING = IntegrationTesting(
    bases=(EXAMPLE_TDD_FIXTURE,),
    name="ExampleTddLayer:Integration")
EXAMPLE_TDD_ACCEPTANCE_TESTING = FunctionalTesting(
    bases=(EXAMPLE_TDD_FIXTURE, ZSERVER_FIXTURE),
    name="ExampleTDD:Acceptance"
)


def solution(new_id):
    answer = ''
    for ele in new_id:
        if 65 <= ord(ele) <= 90:
            answer += chr(ord(ele) + 32)    # 대문자 to 소문자
        elif 48 <= ord(ele) <= 57 or 45 <= ord(ele) <= 46 or ord(ele) == 95 or 97 <= ord(ele) <= 122:
            answer += ele
        else:
            continue
    result = ''
    for ele in answer.split('.'):
        if ele:
            result += ele + '.'
    result = result[:-1]
    if not result:
        result = 'aaa'
    elif len(result) > 15:
        result = result[:15]
        if result[-1] == '.':
            result = result[:-1]
    elif len(result) < 3:
         result = result + (result[-1] * (3 - len(result)))
    return result

new_id = "...!@BaT#*..y.abcdefghijklm"
print(new_id)
print(solution(new_id))


_author_ = "YE"
# -*- coding:utf-8 -*-

class Solution(object):
    def groupAnagrams(self, strs):
        """
        :type strs: List[str]
        :rtype: List[List[str]]
        """
        ref = {}
        length = len(strs)
        for str in strs:
            word = "".join(sorted(str))
            if word in ref:
                ref[word]  = ref[word] + [str]
            else:
                ref[word] = [str]
        res = []
        for key in ref:
            l = ref[key]
            l.sort()
            res.append(l)

        return res

s = Solution()
strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
print(s.groupAnagrams(strs))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""Gère le joueur"""

import pygame as pg
from copy import deepcopy

import save

class Player(pg.sprite.Sprite):
    """Représente le joueur"""

    TEXTURE_FILE_LOCATION = 'res/textures/m2.png'

    SPEED_NORMALISATION = 1/(2**0.5)
    SPRINT_WALK_SPEED_MULTIPLIER = 8 # Multiplicateur de vitesse en cas de sprint
    WALK_ANIMATION_COOLDOWN = 8 # Cooldown entre deux changements d'animations (en frames)
    SPRINT_ANIMATION_COOLDOWN = 3 # Cooldown entre deux changements d'animations (en frames)

    FEET_SIZE = 12 # Hauteur de la zone de collision (en pixels)

    ANIMATION_DICT = {
    "1,1" : "down-right",
    "1,0" : "right",
    "0,1" : "down",
    "1,-1" : "up-right",
    "0,-1" : "up",
    "-1,1" : "down-left",
    "-1,0" : "left",
    "-1,-1" : "up-left"}

    def __init__(self, game):
        super().__init__()
        self.game = game

        # Variables d'état
        self.is_animated = False        # Le sprite du joueur défile
        self.is_sprinting = False       # Le joueur sprinte
        self.can_move = True            # Le joueur est capable de bouger
        self.boop = False               # Le joueur est en collision

        # Chargement de la position dans la sauvegarde
        config = save.load_config("player")
        self.position = config["position"]
        self.base_walk_speed = config["speed"] #Vitesse du joueur sans multiplicateur (en pixel/frame)

        # Graphique
        self.drawing_layer = 1
        self.sprite_sheet = pg.image.load(self.TEXTURE_FILE_LOCATION)
        self.image = self.get_image(0, 0)  # en bas par défaut
        self.image.set_colorkey([0, 0, 0])  # transparence
        self.rect = self.image.get_rect()  # rectangle autour du joueur
        self.feet = pg.Rect(0, 0, self.rect.width * 0.5, self.FEET_SIZE)
        self.current_sprite = 0

        self.IMAGES = {
        'down': [self.get_image(0, 0), self.get_image(32, 0), self.get_image(64, 0)],
        'down-left': [self.get_image(0, 0), self.get_image(32, 0), self.get_image(64, 0)],
        'down-right': [self.get_image(0, 0), self.get_image(32, 0), self.get_image(64, 0)],
        'left': [self.get_image(0, 32), self.get_image(32, 32), self.get_image(64, 32)],
        'right': [self.get_image(0, 64), self.get_image(32, 64), self.get_image(64, 64)],
        'up': [self.get_image(0, 96), self.get_image(32, 96), self.get_image(64, 96)],
        'up-left': [self.get_image(0, 96), self.get_image(32, 96), self.get_image(64, 96)],
        'up-right': [self.get_image(0, 96), self.get_image(32, 96), self.get_image(64, 96)]
        }

    def save(self):
        """Sauvegarde lors de la fermeture du jeu"""
        save.save_config("player", map_id = self.game.map_manager.map_id, position = self.position, speed = self.base_walk_speed)

    def change_animation(self, direction):  # change l'image en fonction du sens 'sens'
        """Change l'image de l'animation du joueur"""
        animation = self.ANIMATION_DICT[str(direction[0])+","+str(direction[1])]
        self.image = self.IMAGES[animation][int(self.current_sprite)]
        self.image.set_colorkey([0, 0, 0])  # transparence

    def is_colliding(self):
        """Vérifie la collision avec un mur ou un portail"""
        # Collision avec un portail
        index = self.feet.collidelist(self.game.map_manager.portals)
        if index >= 0:   # Le joueur est dans un portail
            # On récupère l'endroit où téléporter le joueur
            [to_world, to_point] = self.game.game_data_db.execute("SELECT to_world, to_point FROM portals WHERE id = ?", (self.game.map_manager.portals_id[index],)).fetchall()[0]
            old_bgm = self.game.map_manager.sound_manager.music_file
            self.game.map_manager.load_map(to_world, old_bgm) # On charge la nouvelle carte
            self.game.map_manager.teleport_player(to_point)  # on téléporte le joueur à la destination
            return True
        else:
            # Collision avec les murs
            return True if self.feet.collidelist(self.game.map_manager.walls) > -1 else False

    def move(self, list_directions, sprinting):
        """Méthode de déplacement du joueur"""
        if list_directions.count(True) > 0: # Si au moins une touche de déplacement est préssée
            if self.can_move: # Le joueur n'est pas en dialogue
                self.boop = False # Le joueur a de nouveau bougé depuis la dernière collision
                speed_multiplier = self.SPRINT_WALK_SPEED_MULTIPLIER if sprinting else 1
                self.is_sprinting = True if sprinting else False

                # On calcule le déplacement potentiel en x et en y en fonction des touche préssées
                deplacement = [0, 0]
                if list_directions[0]: #Haut
                    deplacement[1] -= 1
                if list_directions[1]: #Droite
                    deplacement[0] += 1
                if list_directions[2]: #Bas
                    deplacement[1] += 1
                if list_directions[3]: #Gauche
                    deplacement[0] -= 1

                if deplacement[0] != 0 or deplacement[1] != 0: # Si le déplacement n'est pas nul

                    # Si le déplacement est non nul selon les deux coordonées, on se déplace en diagonale, il faut normaliser le vecteur déplacement
                    if deplacement[0] != 0 and deplacement[1] != 0:
                        speed_normalisation = self.SPEED_NORMALISATION
                    else:
                        speed_normalisation = 1

                    # On traite les deux coordonées x et y
                    for coord_id in [0, 1]:
                        # On déplace le sprite et on recalcule la position
                        self.position[coord_id] += deplacement[coord_id]*self.base_walk_speed*speed_multiplier*speed_normalisation
                        self.rect.topleft = self.position
                        self.feet.midbottom = self.rect.midbottom

                        # Si il y a collision, on annule le dernier déplacement
                        if self.is_colliding():
                            self.boop = True # Enregistrement de la collision
                            self.position[coord_id] -= deplacement[coord_id]*self.base_walk_speed*speed_multiplier*speed_normalisation
                            self.rect.topleft = self.position
                            self.feet.midbottom = self.rect.midbottom
                    else:
                        self.is_animated = True
                        self.change_animation(deplacement)
            else:
                self.is_animated = False

    def update(self):
        """Mise à jour graphique"""
        self.rect.topleft = self.position
        self.feet.midbottom = self.rect.midbottom

        # Recalcul de l'image à utiliser
        animation_cooldown = self.SPRINT_ANIMATION_COOLDOWN if self.is_sprinting else self.WALK_ANIMATION_COOLDOWN
        if self.is_animated == True:
            self.current_sprite = (int(self.game.tick_count/animation_cooldown) % 3)

    def get_image(self, x, y):
        """Retourne une partie de l'image du joueur"""
        image = pg.Surface([32, 32])
        image.blit(self.sprite_sheet, (0, 0), (x, y, 32, 32))
        return image


"""up: Create and launch specified containers

Runs 'docker compose up -d ...' for the specified process.
Options: --dev, --prod, --all

If the --debug flag is provided, only the debug container is launched.
Even if --dev or --prod flags are provided.

Otherwise (i.e. no --debug):
    -- dev, all, or no flags  |  dev container is launched
    -- prod or all            |  prod container is launched
"""
import os
from pathlib import Path
import subprocess
import yaml
from dsco.helpers import add_timer

cmd_name = Path(__file__).stem

def add_subparser(subparsers):
    sub = subparsers.add_parser(cmd_name, help="create and launch containers")
    sub.add_argument("--dev", action="store_true", help="dev container")
    sub.add_argument("--prod", action="store_true", help="prod container")
    sub.add_argument(
        "--debug",
        action="store_true",
        help="bring up base container without running ansible",
    )
    sub.add_argument("--all", action="store_true", help="dev and prod containers")

@add_timer(cmd_name)
def run_cmd(args, conf):
    if conf["proj_root"]:
        # Flag logic
        no_flags = not any([args.dev, args.prod, args.debug, args.all])
        service_list = [
            # (service, flag)
            ("dev", (args.dev or args.all or no_flags) and not args.debug),
            ("prod", (args.prod or args.all) and not args.debug),
            ("debug", args.debug),
        ]
        services_str = " ".join([service for service, flag in service_list if flag])

        cmd = f"docker compose up -d {services_str}"
        print(cmd)
        subprocess.run(cmd, cwd=conf["proj_root"], shell=True)

    else:
        print("No project found.")

def add_dispatch(dispatcher):
    dispatcher[cmd_name] = run_cmd


from gymnasium.envs.registration import register
from .ensure_valid_action import EnsureValidAction
from .up_down_left_right import UpDownLeftRight
from .pz_to_gymnasium_wrappers import aec_to_gymnasium, parallel_to_gymnasium

__version__ = "0.1.1"

register(
    id='qwertyenv/BlackJack-v0',
    entry_point='qwertyenv.black_jack:BJEnv',
    max_episode_steps=300
)

register(
    id='qwertyenv/CollectCoins-v0',
    entry_point='qwertyenv.collect_coins:CollectCoinsEnv',
    max_episode_steps=300
)

__all__ = [
    EnsureValidAction,
    UpDownLeftRight,
    aec_to_gymnasium,
    parallel_to_gymnasium
]


"""Tick label argument starts empty unless we want to label each ticket with a value"""
def draw_line(tick_length, tick_label=''):  #draws a single tick with specified number of dashes and a label is used
    line= '-'* tick_length # this line will contain "-" amount of ticks that we want tick_length=3 -> ---
    if tick_label:
        line+= ' ' + tick_label # if there is a tick label attach to dash
    print(line)

"""This function draws the sequence of minor ticks within some interval
based upon the length of the interval's central tick"""
def draw_interval(center_length):
    if center_length > 0: #stop when length drops to 0
        draw_interval(center_length -1 ) #recursively draw top ticks
        draw_line(center_length) #draw center tick
        draw_interval(center_length -1 ) #recursively draw bottom ticks

"""This function manages the construction of the ruler and the major tick length """
def draw_ruler(num_inches, major_length):
    """Draw english ruler based upon a central tick length"""
    draw_line(major_length, '0') #first line to be drawn -> inch 0 line
    for j in range(1, 1+num_inches):
        draw_interval(major_length-1)
        draw_line(major_length, str(j))

draw_ruler(10, 3)


# set up dependencies
import datetime as dt
import numpy as np
import pandas as pd
import sqlalchemy
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session
from sqlalchemy import create_engine, func

from flask import Flask, jsonify

engine = create_engine("sqlite:///hawaii.sqlite",
                       connect_args={'check_same_thread': False})

# reflect an existing database into a new model
Base = automap_base()
# reflect the tables
Base.prepare(engine, reflect=True)

# Save references to each table
Measurement = Base.classes.measurement
Station = Base.classes.station

# Create our session (link) from Python to the DB
session = Session(engine)

app = Flask(__name__)

@app.route("/")
def welcome():
    return (
        f"Welcome to the Hawaii Climate Analysis App Homepage!
"
        f"Available Routes Below:
"
        f"Precipitation measurement over the last 12 months: /api/v1.0/precipitation
"
        f"A list of stations and their respective station numbers: /api/v1.0/stations
"
        f"Temperatures observations at the most active station over the previous 12 months: /api/v1.0/tobs
"
        f"Enter a start date (yyyy-mm-dd) to retrieve the minimum, maximum, and average temperatures for all dates after the specified date: /api/v1.0/<start>
"
        f"Enter both a start and end dates (yyyy-mm-dd) to retrieve the minimum, maximum and average temperatures for that date range: /api/v1.0/<start>/<end>"
    )

@app.route("/api/v1.0/precipitation")
def precipitation():

    # Query Measurement
    results = (session.query(Measurement.date, Measurement.tobs)
                      .order_by(Measurement.date))

    # Create a dictionary
    precipitation_date_tobs = []
    for each_row in results:
        dt_dict = {}
        dt_dict["date"] = each_row.date
        dt_dict["tobs"] = each_row.tobs
        precipitation_date_tobs.append(dt_dict)

    return jsonify(precipitation_date_tobs)

@app.route("/api/v1.0/stations")
def stations():

    # Query Measurement
    results = session.query(Station.name).all()

    # Convert list of tuples into normal list
    station_details = list(np.ravel(results))
    return jsonify(station_details)

@app.route("/api/v1.0/tobs")
def temp_monthly():
    # Calculate the date 1 year ago from last date in database
    prev_year = dt.date(2017, 8, 23) - dt.timedelta(days=365)

    # Query the primary station for all tobs from the last year
    results = session.query(Measurement.tobs).\
        filter(Measurement.station == 'USC00519281').\
        filter(Measurement.date >= prev_year).all()

    # Convert list of tuples into normal list
    temps_detail = list(np.ravel(results))

    return jsonify(temps_detail)

@app.route("/api/v1.0/<start>")
def start_only(start):

    # Query the max date
    date_max = session.query(Measurement.date).order_by(Measurement.date.desc()).first()
    date_max_str = str(date_max)
    date_max_str = re.sub("'|,", "",date_max_str)
    print (date_max_str)

    # Query the min date
    date_min = session.query(Measurement.date).first()
    date_min_str = str(date_min)
    date_min_str = re.sub("'|,", "",date_min_str)
    print (date_min_str)

    # Check for valid start date
    start_entry = session.query(exists().where(Measurement.date == start)).scalar()

    if start_entry:

        results = (session.query(func.min(Measurement.tobs)
                    ,func.avg(Measurement.tobs)
                    ,func.max(Measurement.tobs))
                   .filter(Measurement.date >= start).all())

        tmin =results[0][0]
        tavg ='{0:.2}'.format(results[0][1])
        tmax =results[0][2]

        result_temps =( ['Entered Start Date: ' + start,
                            'Lowest Temperature: '  + str(tmin),
                            'Average Temperature: ' + str(tavg),
                            'Highest Temperature: ' + str(tmax)])
        return jsonify(result_temps)

@app.route("/api/v1.0/<start>/<end>")
def start_end(start_entry, end_entry):

    # Query the max date
    date_max = session.query(Measurement.date).order_by(Measurement.date.desc()).first()
    date_max_str = str(date_max)
    date_max_str = re.sub("'|,", "",date_max_str)
    print (date_max_str)

    # Query the min date
    date_min = session.query(Measurement.date).first()
    date_min_str = str(date_min)
    date_min_str = re.sub("'|,", "",date_min_str)
    print (date_min_str)

     # Check for valid start date
    start_entry = session.query(exists().where(Measurement.date == start)).scalar()

     # Check for valid end date
    end_entry = session.query(exists().where(Measurement.date == end)).scalar()

    if start_entry and end_entry:

        results = (session.query(func.min(Measurement.tobs)
                    ,func.avg(Measurement.tobs)
                    ,func.max(Measurement.tobs))
                        .filter(Measurement.date >= start)
                        .filter(Measurement.date <= end).all())

        tmin =results[0][0]
        tavg ='{0:.2}'.format(results[0][1])
        tmax =results[0][2]

        result_temps=( ['Entered Start Date: ' + start,
                            'Entered End Date: ' + end,
                            'Lowest Temperature: '  + str(tmin),
                            'Average Temperature: ' + str(tavg),
                            'Highest Temperature: ' + str(tmax)])
        return jsonify(result_temps)

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


from statistics import mean, stdev
from enum import Enum
import numpy as np

class TableFormat(Enum):
    TEXTUAL = 1
    CSV = 2

    def format(self, table):
        if self == TableFormat.TEXTUAL:
            for col in range(len(table[0])):
                max_strlen = max(len(table[i][col]) for i in range(len(table)))
                for i in range(len(table)):
                    if col == 0:
                        table[i][col] = table[i][col].ljust(max_strlen, " ")
                    else:
                        table[i][col] = table[i][col].rjust(max_strlen, " ")
            return "\n".join("  ".join(row) for row in table)
        assert self == TableFormat.CSV
        return "\n".join(",".join(row) for row in table)

    def get_file_extension(self):
        if self == TableFormat.TEXTUAL:
            return 'txt'
        else:
            return 'csv'

def summary_datas_to_absolute_and_relative_means_and_stdevs(summary_datas):
    """
    Accepts multiple summary datas (one from each run of the same strategy),
    computes and returns strings describing the mean and standard variation of different properties,
    both absolute (i.e. 100 +- 20 infected) and relative (i.e. 30% +- 5% infected).
    In the case where there is only one summary data, does not
    compute standard deviation.
    :param summary_datas: A list of 'summary_data' dicts, one from each run
    :return: Two dicts from property names to "value"
    (string containing mean and standard variation).
    One for absolute amounts and another for relative amounts.
    """
    keys_to_data_arrays = {}
    for i, data in enumerate(summary_datas):
        assert len(data) == len(summary_datas[0])
        for key, val in data.items():
            if i == 0:
                keys_to_data_arrays[key] = []
            else:
                assert key in keys_to_data_arrays
            keys_to_data_arrays[key].append(val)
    absolute_data = {}
    relative_data = {}
    for key, absolute_array in keys_to_data_arrays.items():
        #relative_array = [x / y for (x, y) in zip(absolute_array, keys_to_data_arrays["Total people"])]
        relative_array = []
        for (x,y) in zip(absolute_array, keys_to_data_arrays["Total people"]):
            if y != 0:
                relative_array.append(x/y)
            else:
                relative_array.append(np.nan)

        if len(relative_array) == 1:
            absolute_data[key] = "{}".format(absolute_array[0])
            relative_data[key] = "{:3.3f}%".format(100 * relative_array[0])
        else:
            absolute_data[key] = "{m} ±{s:6.1f}".format(m=mean(absolute_array), s=stdev(absolute_array))
            relative_data[key] = "{m}% ±{s:3.3f}%".format(m=100 * mean(relative_array), s=100 * stdev(relative_array))
    return absolute_data, relative_data

def make_summary_by_age_table(age_group_to_summary_tables, table_format, is_relative=True):
    """
    :param age_group_to_summary_tables: A table from age_group to
    a list of 'summary_data's on that age group
    :return: A short readable text containing a table of
    age-stratified results (total deceased, total infected, ...)
    """
    assert isinstance(table_format, TableFormat)
    age_group_to_absolute_data = {}
    age_group_to_relative_data = {}
    for age_group, summary_datas in age_group_to_summary_tables.items():
        age_group_to_absolute_data[age_group], age_group_to_relative_data[age_group] = \
            summary_datas_to_absolute_and_relative_means_and_stdevs(summary_datas)
    age_groups = list(age_group_to_summary_tables.keys())
    table = []
    age_groups_text = ['Age group']
    for age_group in age_groups:
        if age_group is None:
            age_groups_text.append("Total")
        else:
            age_groups_text.append("{}-{}".format(*age_group))
    table.append(age_groups_text)
    keys = ["Total people"] + [key for key in age_group_to_relative_data[age_groups[0]] if key != "Total people"]
    for key in keys:
        curr = [key]
        for age_group in age_groups:
            if (key == "Total people") or not is_relative:
                curr.append(age_group_to_absolute_data[age_group][key])
            else:
                curr.append(age_group_to_relative_data[age_group][key])
        table.append(curr)
    return table_format.format(table)


import unittest

#O(n log(n)) Solution

def check_Permutation(s1, s2):
    if len(s1) != len(s2) and s1 == s2:
        return False

    s1, s2 = sorted(s1), sorted(s2)

    for i in range (len(s1)):
        if(s1[i] != s2[i]):
            return False
    return True

#O(n^2) Solution

def check_Permutation2(string1, string2):

    if len(string1) == len(string2) and string1 != string2:

        for letter1 in string1:
            for letter2 in string2:
                if string1.find(letter2) != -1:
                    string1 = string1.replace(letter2, "", 1)
                    string2 = string2.replace(letter2, "", 1)

    if len(string1) == 0 & len(string2) == 0:
        return True

    else:
        return False

class Test(unittest.TestCase):

    test_cases = [
        ("hola", "aloh", True),
        ("hi", "i", False),
        ("diego", "ogdie", True),
        ("s", "s", False)]

    def test_p(self):

        for s1, s2, boolean in self.test_cases:
            assert check_Permutation(s1, s2) == boolean

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

Cracking Code Interview Solutions/Ch1_Arrays&Strings/2_Check_Permutation.py


BOTO_MAKE_API_CALL = "botocore.client.BaseClient._make_api_call"
SERVICE_ID_FSX = "FSx"
SERVICE_ID_CW = "CloudWatch"
FSX_CREATE_OPERATION = "CreateFileSystem"
CW_PUT_METRIC_ALARM_OPERATION = "PutMetricAlarm"
FSX_DESCRIBE_OPERATION = "DescribeFileSystems"
ENV_VARS = "os.environ"

FILESYSTEM_ID = "fsxFilesystemId"
FILESYSTEM_DNS_NAME = "fsxFilesystemDnsName"
FILESYSTEM_MOUNT_NAME = "fsxFilesystemMountName"
FILESYSTEM_LIFECYCLE = "fsxFilesystemLifecycle"

# fsx api response property names
FILESYSTEM_PROPERTY = "FileSystem"
FILESYSTEM_IDS_PROPERTY = "FileSystemIds"
FILESYSTEM_ID_PROPERTY = "FileSystemId"
DNS_NAME_PROPERTY = "DNSName"
LUSTRE_CONFIG_PROPERTY = "LustreConfiguration"
MOUNT_NAME_PROPERTY = "MountName"
LIFECYCLE_PROPERTY = "Lifecycle"
FILESYSTEMS_PROPERTY = "FileSystems"
IMPORT_PATH = "ImportPath"
EXPORT_PATH = "ExportPath"
DEPLOYMENT_TYPE = "DeploymentType"
DATA_COMPRESSION_TYPE = "DataCompressionType"

# fsx provisioning parameters
DEFAULT_FSX_PARTITION_SIZE = 1200
FSX_INBOUND_PORT = 988
FSX_INBOUND_PORT_RANGE_START = 1021
FSX_INBOUND_PORT_RANGE_END = 1023
FSX_SG_ID = "FSX_SG_ID"
FSX_SUBNET_ID = "FSX_SUBNET_ID"
FX_PROVISION_ALARM_EVALUATION_PERIODS = "FX_PROVISION_ALARM_EVALUATION_PERIODS"
FX_PROVISION_ALARM_THRESHOLD = "FX_PROVISION_ALARM_THRESHOLD"
FX_PROVISION_ALARM_PERIOD = "FX_PROVISION_ALARM_PERIOD"
FX_PROVISION_ALARM_STATISTIC = "FX_PROVISION_ALARM_STATISTIC"

S3_BUCKET_IMPORT_URL = "S3_BUCKET_IMPORT_URL"
S3_BUCKET_EXPORT_URL = "S3_BUCKET_EXPORT_URL"
S3_URI_TEMPLATE = "s3://{}/{}"

CW_ALARM_TOPIC = "CW_ALARM_TOPIC"

# lambda parameters
FILESYSTEM_ID_PARAMETER = "fsxFilesystemId"
FILESYSTEM_LIFECYCLE_PARAMETER = "fsxFilesystemLifecycle"
FILESYSTEM_SYNC_LIFECYCLE_PARAMETER = "fsxSyncToS3Lifecycle"
FILESYSTEM_DNS_NAME_PARAMETER = "fsxFilesystemDnsName"
FILESYSTEM_MOUNT_NAME_PARAMETER = "fsxFilesystemMountName"
BUCKET_NAME_PARAMETER = "bucketName"
BUCKET_ARN_PARAMETER = "bucketArn"

# step function parameter constants
INPUT_PATH = "input_path"
PARAMETERS = "parameters"
RESULT_SELECTOR = "result_selector"
RESULT_PATH = "result_path"
OUTPUT_PATH = "output_path"

# fsx creation and sync statuses
AVAILABLE = "AVAILABLE"
CREATING = "CREATING"
FAILED = "FAILED"
DELETING = "DELETING"
MISCONFIGURED = "MISCONFIGURED"
UPDATING = "UPDATING"
MISCONFIGURED_UNAVAILABLE = "MISCONFIGURED_UNAVAILABLE"

SUCCEEDED = "SUCCEEDED"
EXECUTING = "EXECUTING"
PENDING = "PENDING"

# cloudwatch parameters
DIMESIONS_PROPERTY = "Dimensions"
VALUE_PROPERTY = "Value"

# managed policies
LAMBDA_EXECUTION_POLICY = "service-role/AWSLambdaBasicExecutionRole"
XRAY_WRITE_POLICY = "AWSXRayDaemonWriteAccess"
FSX_ACCESS_POLICY = "AmazonFSxFullAccess"

# AWS service principals
LAMBDA_SERVICE_PRINCIPAL = "lambda.amazonaws.com"
FSX_SERVICE_PRINCIPAL = "fsx.amazonaws.com"
S3_FSX_SERVICE_PRINCIPAL = "s3.data-source.lustre.fsx.amazonaws.com"

# config settings
STACK_FOLDER = "provision_fsx_lustre_step_function"
LAMBDA_LAYER_FILE_PATH = "lambda_layer_file_path"
LAMBDA_FILE_PATH = "lambda_file_path"
LAMBDA_FOLDER = "lambdas"
LAMBDA_LAYER_FOLDER = "lambda_layer"
LAMBDA_FILE_NAME = "index.py"

VENDED_LOGS_PREFIX = "/aws/vendedlogs/{}"
STATES_PREFIX = "states/"

POWERTOOLS_SERVICE_NAME = "POWERTOOLS_SERVICE_NAME"
LOG_LEVEL = "LOG_LEVEL"
LAMBDA_POWERTOOLS_LAYER = (
    "arn:aws:lambda:{}:017000801446:layer:AWSLambdaPowertoolsPython:37"
)

VPC_ID = "vpc_id"
SUBNET_ID = "subnet_id"

VALID_TEST_URL = "valid_url"
INVALID_TEST_URL = "invalid_url"
SOME_ID = "some_id"
API_ERROR = "api error"

TEST_FSX_ID_1 = "id1"
TEST_FSX_ID_2 = "id2"
TEST_FSX_ID_3 = "id3"
TEST_FSX_ID_4 = "id4"
TEST_FSX_ID_5 = "id5"
TEST_FSX_ID_6 = "id6"
TEST_FSX_ID_7 = "id7"

REPLACE_THIS = "<SOME_INVALID_ID>"

ALARM_EMAIL_ADDRESS = (
    "noreply@mailinator.com"  # TODO: Change Fake Email for Alarm Email Testing
)


import random

LENG = 10

lst = [random.randint(0, 100) for i in range(LENG)]
min_ = lst[0]
max_ = lst[0]
pos_min = 0
pos_max = 0
summ_ = 0

for i in range(len(lst)):
    if lst[i] <= min_:
        min_ = lst[i]
        pos_min = i
    elif lst[i] >= max_:
        max_ = lst[i]
        pos_max = i

print(lst)
print(f'Максимальный элемент {max_}, его позиция {pos_max}, минимальный элемент {min_}, его позиция {pos_min}')
print(f'Между ними {abs(pos_min - pos_max)-1} элемента(ов)')

if pos_min < pos_max and pos_max - pos_min != 1:
    if pos_min + 1 == pos_max - 1:
        summ_ = lst[pos_min + 1]
    else:
        for i in range((pos_min + 1), pos_max):
            summ_ = summ_ + lst[i]
    print(f'Cумма элементов между ними {summ_}')
elif pos_min > pos_max and pos_min - pos_max != 1:
    if pos_min - 1 == pos_max + 1:
        summ_ = lst[pos_max + 1]
    else:
        for i in range((pos_max + 1), pos_min):
            summ_ = summ_ + lst[i]
    print(f'Cумма элементов между ними {summ_}')
else:
    print(f'Нет элементов между')


#!/usr/bin/env python
# coding: utf8
from __future__ import print_function
import logging
import argparse
import ConfigParser as configparser

from httplib2 import Http
from apiclient.discovery import build
from oauth2client import file, client, tools

from constants import LOCATION_ID_MAX_LEN

DIR2DIR_ID = {
    u"север": "N",
    u"СВ": "NE",
    u"восток": "E",
    u"ЮВ": "SE",
    u"юг": "S",
    u"ЮЗ": "SW",
    u"запад": "W",
    u"СЗ": "NW",
    u"ВЕРХ": "U",
    u"НИЗ": "D"
}

class Position(object):

    def __init__(self, x = 0, y = 0, z = 0):
        self._x = x
        self._y = y
        self._z = z

    def __str__(self):
        return "({}, {}, {})".format(self._x, self._y, self._z)

class Transition(object):

    def __init__(self, to_id, descr, multiplier, arrow, extra_button_markup):
        self._to_id = to_id
        self._descr = descr
        self._multiplier = multiplier
        self._arrow = arrow
        self._extra_button_markup = extra_button_markup

def accumulate_probs(events):
    result = list()
    acc_prob = 0
    for prob, event_data in sorted(events, reverse=True):
        acc_prob += prob
        result.append((acc_prob, event_data))
    assert abs(1 - acc_prob) < 0.001, "invalid accumulated prob"
    return result

class Location(object):
    """
    descr: unicode
    size: float
    research_rage: float
    pos: Position
    adjacent: list of (dir_id, Transition)
    venues: list of (venue_id, venue_descr, research_threshold) tuples
    venue_option2events: unicode -> events dict
    """

    def __init__(self, id, descr, size, research_rate, pos, adjacent, venues, events):
        self._id = id
        assert type(self._id) == str and len(self._id) < LOCATION_ID_MAX_LEN
        self._descr = descr
        self._size = size
        self._research_rate = research_rate
        self._pos = pos
        self._adjacent = adjacent
        self._venues = venues
        self._events = events
        self._venue_option2events = dict()

    @staticmethod
    def parse_from_sheet(worksheet):
        rows = worksheet["values"]
        assert len(rows) > 19

        assert rows[0] == [u"глобальная карта", u"основное"]

        descr = rows[1][0]
        assert descr

        assert rows[2][0] == u"размер квадрата"
        size = float(rows[2][1])
        assert rows[2][2] == u"скорость исследования"
        research_rate = int(rows[2][3])

        assert rows[3][0] == u"X"
        x = float(rows[3][1])
        assert rows[4][0] == u"Y"
        y = float(rows[4][1])

        assert rows[6][:5] == [
            u"выходы",
            u"условие",
            u"переход на",
            u"множитель",
            u"описание процесса перехода"
        ]
        adjacent = dict()
        for row_index in range(7, 15):
            row = rows[row_index]
            assert len(row) >= 6
            dir_id = DIR2DIR_ID[row[0]]
            to_id = row[2]
            multiplier = float(row[3])
            journey_descr = row[4]
            arrow = row[5]
            extra_button_markup = row[6] if len(row) >= 7 else u""
            adjacent[dir_id] = Transition(to_id, journey_descr, multiplier,
                                          arrow, extra_button_markup)

        assert rows[17][0] == u"постоянные объекты"
        row_index = 18
        venues = list()
        research_threshold = 0
        while row_index < len(rows) and rows[row_index][0] != u"случайные ивенты":
            row = rows[row_index]
            if len(row) >= 3:
                research_threshold += int(row[1].strip("%"))
                venues.append((row[0], row[2], research_threshold))
            row_index += 1

        events = list()
        if row_index < len(rows):
            row_index += 1
            while row_index < len(rows):
                row = rows[row_index]
                if len(row) >= 2:
                    event_name, prob = row[:2]
                    assert prob.endswith("%")
                    prob = int(prob.strip("%")) * 0.01
                    if prob > 0:
                        events.append((prob, event_name))
                row_index += 1
            if events:
                events = accumulate_probs(events)
        return Location("", descr, size, research_rate, Position(x, y), adjacent, venues, events)

class Venue(object):
    """
    options - dict of (descr, message, events)
        events is a sorted list of (accu prob, event_id)
    events - sorted list of (accu prob, event_id)
    """

    def __init__(self, name, options, events):
        self._name = name
        self._options = options
        self._events = events

def load_venues(sheet_data):
    rows = sheet_data["values"]
    row_index = 1
    venues = dict()
    while row_index < len(rows):
        assert len(rows[row_index]) == 1, "venue id expected, found: {}".format(" ".join(row))
        venue_id = rows[row_index][0]
        if venue_id in venues:
            logging.warning("duplicate venue id: {}, row: {}".format(venue_id.encode("utf8"), u" ".join(rows[row_index]).encode('utf8')))
        row_index += 1
        while row_index < len(rows) and len(rows[row_index]) > 1:
            row = rows[row_index]
            assert row[2] != "" or row[1] == u"исследование", "expected venue option or research section"
            venue_name = row[1]

            options = list()
            while row_index < len(rows) and len(rows[row_index]) > 1 and (rows[row_index][1] in {venue_name, u""}):
                row = rows[row_index]
                option_text = row[2]
                option_message = row[3] if row[3] else u"Исследуем"

                events = list()
                while row_index < len(rows) and len(rows[row_index]) > 1 and (rows[row_index][1] in {venue_name, u""}) and (rows[row_index][2] in {option_text, u""}):
                    row = rows[row_index]
                    if len(row) >= 7:
                        events.append((float(row[5].strip("%")) * 0.01, row[6]))
                    row_index += 1

                options.append((option_text, option_message, accumulate_probs(events)))
            if venue_name != u"исследование":
                venues[venue_id] = Venue(venue_name, options, list())
            else:
                assert len(options) == 1
                if venue_id not in venues:
                    venues[venue_id] = Venue(venue_name, options, options[0][2])
                else:
                    venues[venue_id]._events = options[0][2]
    return venues

class TextQuestOutcome(object):

    def __init__(self, cnt, message, outcome_id):
        self._cnt = cnt
        self._message = message
        self._outcome_id = outcome_id

def load_texts(sheet_data):
    rows = sheet_data["values"]
    row_index = 1
    event_id2texts = dict()
    while row_index < len(rows):
        event_id = rows[row_index][1]
        if event_id in event_id2texts:
            logging.warning("duplicate event_id {} in row {}".format(event_id.encode("utf8"), row_index))
        event_id2texts[event_id] = dict()
        row_index += 1

        while row_index < len(rows) and len(rows[row_index]) > 2:
            text_id, text = rows[row_index][:2]
            assert text_id not in event_id2texts[event_id]
            event_id2texts[event_id][text_id] = (text, dict())

            while row_index < len(rows) and len(rows[row_index]) > 2 and (rows[row_index][0] in {text_id, u""}):
                option_text = rows[row_index][5]
                assert option_text not in event_id2texts[event_id][text_id]

                outcomes = list()
                while row_index < len(rows) and len(rows[row_index]) > 2 and (rows[row_index][0] in {text_id, u""}) and (rows[row_index][5] in {option_text, u""}):
                    row = rows[row_index]
                    if len(row) >= 6 and row[6]:
                        prob = float(row[6].strip("%")) * 0.01
                        cnt = int(row[7]) if len(row) >= 8 and row[7] else None
                        message = row[8] if len(row) >= 9 else ""
                        outcome_id = row[9] if len(row) >= 10 else None
                        if outcome_id is not None and outcome_id.startswith("i_") and (cnt is None or cnt == 0):
                            logging.warning(u"Bad item count in row #{}: {}".format(row_index, cnt).encode("utf8"))
                        if prob > 0:
                            outcomes.append((prob, TextQuestOutcome(cnt, message, outcome_id)))
                    row_index += 1
                event_id2texts[event_id][text_id][1][option_text] = accumulate_probs(outcomes)
    return event_id2texts

class Event(object):
    """
    descr - event descr unicode
    options - option descr -> outcomes mapping, outcomes is a list of
            (accumulated probability, descr, outcome_id)
    """

    def __init__(self, descr, options):
        self._descr = descr
        self._options = options

class Item(object):

    def __init__(self, name, descr, weight):
        self._name = name
        self._descr = descr
        self._weight = weight

    def get_info(self):
        return u"{}\n{}\nВес: {}".format(self._name, self._descr, self._weight)

def load_items(sheet_data):
    rows = sheet_data["values"]
    items = dict()
    row_index = 2
    while row_index < len(rows):
        row = rows[row_index]
        if row[0] and len(row) >= 4:
            item_id = row[0]
            if item_id in items:
                logging.warning("duplicate item id {} in row {}".format(
                                item_id.encode("utf8"), row_index))
            items[item_id] = Item(row[1], row[2], float(row[3]))
        row_index += 1
    return items

class Program(object):

    def __init__(self, name, descr, ram_usage, compile_time, cpu_usage):
        self._name = name
        self._descr = descr
        self._ram_usage = ram_usage
        self._compile_time = compile_time
        self._cpu_usage = cpu_usage

    def get_info(self):
        text = self._name + u"\n"
        text += self._descr + u"\n"
        text += u"Потребление памяти: {}\n".format(self._ram_usage)
        text += u"Потребление CPU: {}\n".format(self._cpu_usage)
        return text

def load_programs(sheet_data):
    rows = sheet_data["values"]
    programs = dict()
    for row in rows[1:]:
        assert row[0] not in programs
        programs[row[0]] = Program(row[1], row[2], int(row[3]), int(row[4]), int(row[5]))
    return programs

class GameData(object):
    """
        map: location_id -> Location dict
        venues: venue_id -> Venue dict
    """

    def __init__(self, game_map, venues, texts, items, programs):
        self._map = game_map
        self._venues = venues
        self._texts = texts
        self._items = items
        for loc_id in game_map:
            venue_option2events = dict()
            for venue_id, _, _ in game_map[loc_id]._venues:
                if venue_id not in self._venues:
                    logging.warning("Skipping unknown venue: {}".format(venue_id.encode("utf8")))
                    continue
                venue = self._venues[venue_id]
                for option, _, events in venue._options:
                    venue_option2events[option] = events
            game_map[loc_id]._venue_option2events = venue_option2events
        self._programs = programs

    def update(self, gamedata):
        self.__init__(gamedata._map, gamedata._venues, gamedata._texts,
                      gamedata._items, gamedata._programs)

def load_spreadsheets(credentials_filename, spreadsheet_id):
    store = file.Storage(credentials_filename)
    creds = store.get()
    service = build('sheets', 'v4', http=creds.authorize(Http()))
    request = service.spreadsheets().get(spreadsheetId=spreadsheet_id,
                                         ranges=[], includeGridData=False)
    response = request.execute()
    sheet_data = dict()
    for sheet in response["sheets"]:
        title = sheet["properties"]["title"]
        sheet_data[title] = service.spreadsheets().values().get(
            spreadsheetId=spreadsheet_id, range=title).execute()
    return response, sheet_data

def check_gamedata(gamedata):
    missing_locations, missing_venues, missing_texts, missing_items = set(), set(), set(), set()
    for loc in gamedata._map.itervalues():
        for adj in loc._adjacent.itervalues():
            if adj._to_id not in gamedata._map:
                missing_locations.add(adj._to_id)
        for venue_id, _, _ in loc._venues:
            if venue_id not in gamedata._venues:
                missing_venues.add(venue_id)
        for events in loc._venue_option2events.itervalues():
            for _, event_id in events:
                if event_id not in gamedata._texts:
                    missing_texts.add(event_id)
    for event in gamedata._texts:
        for text_id in gamedata._texts[event]:
            for _, outcomes in gamedata._texts[event][text_id][1].iteritems():
                for _, outcome in outcomes:
                    if outcome._outcome_id is not None and outcome._outcome_id.startswith("i_"):
                        if outcome._outcome_id not in gamedata._items:
                            missing_items.add(outcome._outcome_id)
    return sorted(missing_locations), sorted(missing_venues), sorted(missing_texts), sorted(missing_items)

def get_gamedata_status(gamedata):
    missing_loc, missing_venues, missing_texts, missing_items = check_gamedata(gamedata)
    return u"\n".join([
        u"Status check.",
        u"Missing locations:",
        u", ".join(missing_loc),
        u"Missing venues:",
        u", ".join(missing_venues),
        u"Missing texts:",
        u", ".join(missing_texts),
        u"Missing items:",
        u", ".join(missing_items)
    ])

def load_gamedata(credentials_filename, spreadsheet_id):
    spreadsheets_info, sheet2data = load_spreadsheets(credentials_filename, spreadsheet_id)

    game_map = dict()
    for title, data in sheet2data.iteritems():
        assert title not in game_map
        if title.isnumeric():
            try:
                location = Location.parse_from_sheet(data)
            except Exception as e:
                logging.error("Error occured while parsing {}".format(title.encode("utf8")))
                raise e
            location._id = title
            if location is not None:
                game_map[location._id] = location
    location_names = u", ".join(sorted(list(game_map.iterkeys()))).encode("utf8")
    logging.info("loaded {} locations: {}".format(len(game_map), location_names))

    venues = load_venues(sheet2data[u"локации"])
    venue_names = u", ".join(sorted(list(venues.iterkeys()))).encode("utf8")
    logging.info("loaded {} venues: {}".format(len(venues), venue_names))

    texts = load_texts(sheet2data[u"тексты"])
    logging.info("loaded {} texts".format(len(texts)))

    items = load_items(sheet2data[u"Ресурсы"])
    programs = load_programs(sheet2data[u"программы"])
    return GameData(game_map, venues, texts, items, programs)

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("cfg")
    args = parser.parse_args()

    cfg = configparser.RawConfigParser()
    cfg.read(args.cfg)

    logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                        level=logging.INFO)
    gamedata = load_gamedata(cfg.get("auth", "credentials"), cfg.get("gamedata", "spreadsheet_id"))
    logging.info(get_gamedata_status(gamedata))


import datetime

months = [
    "Январь",
    "Февраль",
    "Март",
    "Апрель",
    "Май",
    "Июнь",
    "Июль",
    "Август",
    "Сентябрь",
    "Октябрь",
    "Ноябрь",
    "Декабрь",
]

today = datetime.datetime.today()
today_month = months[today.month-1]
today_day = str(today.day)

after_21_days = datetime.date(today.year, today.month, today.day) + datetime.timedelta(days=21)
after_month = months[after_21_days.month-1]
after_day = str(after_21_days.day)


from django.contrib import admin
from .models import Order, OrderItem

# Register your models here.

class OrderItemAdmin(admin.TabularInline):
    """Admin settings for the OrderItem class"""

    model = OrderItem
    list_display = ("product", "order")
    list_display_link = ("product", "order")
    readonly_fields = ("item_total",)

class OrderAdmin(admin.ModelAdmin):
    """Admin settings for the Order class"""

    inlines = (OrderItemAdmin,)

    readonly_fields = (
        "delivery_costs",
        "sub_total",
        "grand_total",
        "created",
    )

    list_display = (
        "full_name",
        "created",
        "email",
        "postcode",
    )

    list_display_links = (
        "email",
        "created",
    )

    search_fields = (
        "full_name",
        "email",
        "postcode",
        "created",
    )

    ordering = ("-created",)

admin.site.register(Order, OrderAdmin)


import json
import os
import socket
import subprocess
import time
from contextlib import suppress
from urllib.parse import urlparse

import pytest
import webdriver
from mozprofile import Profile
from mozrunner import FirefoxRunner

from support.network import get_free_port

@pytest.fixture(scope="module")
def browser(full_configuration):
    """Start a Firefox instance without using geckodriver.

    geckodriver will automatically use the --remote-allow-hosts and
    --remote.allow.origins command line arguments.

    Starting Firefox without geckodriver allows to set those command line arguments
    as needed. The fixture method returns the browser instance that should be used
    to connect to a RemoteAgent supported protocol (CDP, WebDriver BiDi).
    """
    current_browser = None

    def _browser(use_bidi=False, use_cdp=False, extra_args=None, extra_prefs=None):
        nonlocal current_browser

        # If the requested preferences and arguments match the ones for the
        # already started firefox, we can reuse the current firefox instance,
        # return the instance immediately.
        if current_browser:
            if (
                current_browser.use_bidi == use_bidi
                and current_browser.use_cdp == use_cdp
                and current_browser.extra_args == extra_args
                and current_browser.extra_prefs == extra_prefs
                and current_browser.is_running
            ):
                return current_browser

            # Otherwise, if firefox is already started, terminate it because we need
            # to create a new instance for the provided preferences.
            current_browser.quit()

        binary = full_configuration["browser"]["binary"]
        firefox_options = full_configuration["capabilities"]["moz:firefoxOptions"]
        current_browser = Browser(
            binary,
            firefox_options,
            use_bidi=use_bidi,
            use_cdp=use_cdp,
            extra_args=extra_args,
            extra_prefs=extra_prefs,
        )
        current_browser.start()
        return current_browser

    yield _browser

    # Stop firefox at the end of the test module.
    if current_browser is not None:
        current_browser.quit()
        current_browser = None

@pytest.fixture
def custom_profile(configuration):
    # Clone the known profile for automation preferences
    firefox_options = configuration["capabilities"]["moz:firefoxOptions"]
    _, profile_folder = firefox_options["args"]
    profile = Profile.clone(profile_folder)

    yield profile

    profile.cleanup()

@pytest.fixture
def geckodriver(configuration):
    """Start a geckodriver instance directly."""
    driver = None

    def _geckodriver(config=None, hostname=None, extra_args=None):
        nonlocal driver

        if config is None:
            config = configuration

        driver = Geckodriver(config, hostname, extra_args)
        driver.start()

        return driver

    yield _geckodriver

    if driver is not None:
        driver.stop()

class Browser:
    def __init__(
        self,
        binary,
        firefox_options,
        use_bidi=False,
        use_cdp=False,
        extra_args=None,
        extra_prefs=None,
    ):
        self.use_bidi = use_bidi
        self.bidi_port_file = None
        self.use_cdp = use_cdp
        self.cdp_port_file = None
        self.extra_args = extra_args
        self.extra_prefs = extra_prefs

        self.debugger_address = None
        self.remote_agent_host = None
        self.remote_agent_port = None

        # Prepare temporary profile
        _profile_arg, profile_folder = firefox_options["args"]
        self.profile = Profile.clone(profile_folder)
        if self.extra_prefs is not None:
            self.profile.set_preferences(self.extra_prefs)

        if use_cdp:
            self.cdp_port_file = os.path.join(
                self.profile.profile, "DevToolsActivePort"
            )
            with suppress(FileNotFoundError):
                os.remove(self.cdp_port_file)
        if use_bidi:
            self.webdriver_bidi_file = os.path.join(
                self.profile.profile, "WebDriverBiDiServer.json"
            )
            with suppress(FileNotFoundError):
                os.remove(self.webdriver_bidi_file)

        cmdargs = ["-no-remote"]
        if self.use_bidi or self.use_cdp:
            cmdargs.extend(["--remote-debugging-port", "0"])
        if self.extra_args is not None:
            cmdargs.extend(self.extra_args)
        self.runner = FirefoxRunner(
            binary=binary, profile=self.profile, cmdargs=cmdargs
        )

    @property
    def is_running(self):
        return self.runner.is_running()

    def start(self):
        # Start Firefox.
        self.runner.start()

        if self.use_bidi:
            # Wait until the WebDriverBiDiServer.json file is ready
            while not os.path.exists(self.webdriver_bidi_file):
                time.sleep(0.1)

            # Read the connection details from file
            data = json.loads(open(self.webdriver_bidi_file).read())
            self.remote_agent_host = data["ws_host"]
            self.remote_agent_port = int(data["ws_port"])

        if self.use_cdp:
            # Wait until the DevToolsActivePort file is ready
            while not os.path.exists(self.cdp_port_file):
                time.sleep(0.1)

            # Read the port if needed and the debugger address from the
            # DevToolsActivePort file
            lines = open(self.cdp_port_file).readlines()
            assert len(lines) == 2

            if self.remote_agent_port is None:
                self.remote_agent_port = int(lines[0].strip())
            self.debugger_address = lines[1].strip()

    def quit(self, clean_profile=True):
        if self.is_running:
            self.runner.stop()
            self.runner.cleanup()

        if clean_profile:
            self.profile.cleanup()

class Geckodriver:
    def __init__(self, configuration, hostname=None, extra_args=None):
        self.config = configuration["webdriver"]
        self.requested_capabilities = configuration["capabilities"]
        self.hostname = hostname or configuration["host"]
        self.extra_args = extra_args or []

        self.command = None
        self.proc = None
        self.port = get_free_port()

        capabilities = {"alwaysMatch": self.requested_capabilities}
        self.session = webdriver.Session(
            self.hostname, self.port, capabilities=capabilities
        )

    @property
    def remote_agent_port(self):
        webSocketUrl = self.session.capabilities.get("webSocketUrl")
        assert webSocketUrl is not None

        return urlparse(webSocketUrl).port

    def start(self):
        self.command = (
            [self.config["binary"], "--port", str(self.port)]
            + self.config["args"]
            + self.extra_args
        )

        print(f"Running command: {' '.join(self.command)}")
        self.proc = subprocess.Popen(self.command)

        # Wait for the port to become ready
        end_time = time.time() + 10
        while time.time() < end_time:
            returncode = self.proc.poll()
            if returncode is not None:
                raise ChildProcessError(
                    f"geckodriver terminated with code {returncode}"
                )
            with socket.socket() as sock:
                if sock.connect_ex((self.hostname, self.port)) == 0:
                    break
        else:
            raise ConnectionRefusedError(
                f"Failed to connect to geckodriver on {self.hostname}:{self.port}"
            )

        return self

    def stop(self):
        self.delete_session()

        if self.proc:
            self.proc.kill()

    def new_session(self):
        self.session.start()

    def delete_session(self):
        self.session.end()


# coding: utf-8

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import os
import io
import ConfigParser
from StringIO import StringIO

class Item(tuple):
  def __new__(cls, name, value, source):
    result = super(Item, cls).__new__(cls, (name, value))
    result.source = source
    return result

class DiffForUnknownOptionError(ConfigParser.Error):
  def __init__(self, option, section):
    ConfigParser.Error.__init__(self, 'Failed to apply diff for unknown option '
                                      '%r in section %r' % (option, section))
    self.option = option
    self.section = section
    self.args = (option, section)

class ChainedConfigParser(ConfigParser.SafeConfigParser):
  '''
    This class provides essentially the same interfaces as SafeConfigParser but
    allows chaining configuration files so that one config file provides the
    default values for the other. To specify the config file to inherit from
    a config file needs to contain the following option:

    [default]
    inherit = foo/bar.config

    It is also possible to add values to or remove values from
    whitespace-separated lists given by an inherited option:

    [section]
    opt1 += foo
    opt2 -= bar

    The value of the inherit option has to be a relative path with forward
    slashes as delimiters. Up to 5 configuration files can be chained this way,
    longer chains are disallowed to deal with circular references.

    As opposed to SafeConfigParser, files are decoded as UTF-8 while
    reading. Also, ChainedConfigParser data is read-only. An additional
    option_source(section, option) method is provided to get the path
    of the configuration file defining this option (for relative paths).
    Items returned by the items() function also have a source attribute
    serving the same purpose.
  '''

  def __init__(self):
    ConfigParser.SafeConfigParser.__init__(self)
    self._origin = {}

  def _make_parser(self, filename):
    parser = ConfigParser.SafeConfigParser()
    parser.optionxform = lambda option: option

    with io.open(filename, encoding='utf-8') as file:
      parser.readfp(file, filename)

    return parser

  def _get_parser_chain(self, parser, filename):
    parsers = [(parser, filename)]

    try:
      inherit = parser.get('default', 'inherit')
    except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
      return parsers

    dirname = os.path.dirname(filename)
    for parent in inherit.split():
      parent_filename = os.path.join(dirname, *parent.split('/'))
      parent_parser = self._make_parser(parent_filename)
      parsers[:0] = self._get_parser_chain(parent_parser, parent_filename)

    return parsers

  def _apply_diff(self, section, option, value):
    is_addition = option.endswith('+')
    is_diff = is_addition or option.endswith('-')

    if is_diff:
      option = option[:-1].rstrip()
      try:
        orig_value = self.get(section, option)
      except ConfigParser.NoOptionError:
        raise DiffForUnknownOptionError(option, section)

      orig_values = orig_value.split()
      diff_values = value.split()

      if is_addition:
        new_values = orig_values + [v for v in diff_values if v not in orig_values]
      else:
        new_values = [v for v in orig_values if v not in diff_values]

      value = ' '.join(new_values)

    return is_diff, option, value

  def _process_parsers(self, parsers):
    for parser, filename in parsers:
      for section in parser.sections():
        if not self.has_section(section):
          try:
            ConfigParser.SafeConfigParser.add_section(self, section)
          except ValueError:
            # add_section() hardcodes 'default' and raises a ValueError if
            # you try to add a section called like that (case insensitive).
            # This bug has been fixed in Python 3.
            ConfigParser.SafeConfigParser.readfp(self, StringIO('[%s]' % section))

        for option, value in parser.items(section):
          is_diff, option, value = self._apply_diff(section, option, value)
          ConfigParser.SafeConfigParser.set(self, section, option, value)

          if not is_diff:
            self._origin[(section, self.optionxform(option))] = filename

  def read(self, filenames):
    if isinstance(filenames, basestring):
      filenames = [filenames]

    read_ok = []
    for filename in filenames:
      try:
        parser = self._make_parser(filename)
      except IOError:
        continue
      self._process_parsers(self._get_parser_chain(parser, filename))
      read_ok.append(filename)

    return read_ok

  def items(self, section, *args, **kwargs):
    items = []
    for option, value in ConfigParser.SafeConfigParser.items(self, section, *args, **kwargs):
      items.append(Item(
        option, value,
        self._origin[(section, self.optionxform(option))]
      ))
    return items

  def option_source(self, section, option):
    option = self.optionxform(option)
    try:
      return self._origin[(section, option)]
    except KeyError:
      if not self.has_section(section):
        raise ConfigParser.NoSectionError(section)
      raise ConfigParser.NoOptionError(option, section)

  def readfp(self, fp, filename=None):
    raise NotImplementedError

  def set(self, section, option, value=None):
    raise NotImplementedError

  def add_section(self, section):
    raise NotImplementedError

  def remove_option(self, section, option):
    raise NotImplementedError

  def remove_section(self, section):
    raise NotImplementedError


import numpy as np
import pandas as pd
from itertools import chain

from indoorplants.validation import crossvalidate

def _cv_proba(X, y, model_obj, splits=5, **cv_engine_kwargs):
    """
    Return numpy array of "splits"-fold CV results,
    where results are:
    -column 0: actual class
    -columns 1 & 2: proba. of each of neg. and pos. classes.
    """
    model_obj.predict = model_obj.predict_proba

    score = lambda true, predicted: np.hstack(
                [true.values.reshape(-1, 1), predicted[:, 1].reshape(-1, 1)]
                )

    return crossvalidate.cv_engine(
                            X=X, y=y,
                            model_obj=model_obj,
                            score_funcs=[score],
                            splits=splits,
                            train_scores=False,
                            **cv_engine_kwargs
                            )

def _get_rank_stats(results):
    """
    Helper function that produces median and m.a.d
    probabilities for each of 2 classes given _cv_proba
    results with reworked columns.
    """
    grouped = results[["class", "proba"]
                     ].groupby(
                        ["class"]
                     ).median(
                     ).rename(columns={"proba":"median"})

    return grouped.join(results[
                            ["class", "proba"]
                                ].groupby(["class"]
                  ).mad(
                  ).rename(columns={"proba":"mad"}))

def cv_rank(X, y, model_obj, splits=5, **cv_engine_kwargs):
    """
    Returns median and m.a.d. probabilities for each class
    for test results over "splits"-fold CV.
    """
    results = pd.DataFrame(
                np.vstack(
                    chain(
                        *_cv_proba(
                            X=X, y=y,
                            model_obj=model_obj,
                            splits=splits,
                            **cv_engine_kwargs
                    ))),
                columns=["class", "proba"])

    return _get_rank_stats(results)

def _calibrate_cv(model_results, calib_type, splits):
    """
    Produces calibrated probabilities for passed "model_results"
    using passed "calib_type" calibration model type
    (uninstantiated model object).
    """
    def calibrator_fit(split_number):
        X = model_results.loc[split_number, "proba"].to_frame()
        y = model_results.loc[split_number, "class"]
        return calib_type().fit(X, y)

    def calibrator_predict_proba(calib_obj, split_number):
        X = model_results.loc[split_number, "proba"].to_frame()
        return calib_obj.predict_proba(X)

    def get_results_for_split(split_number):
        calib_obj = calibrator_fit(split_number)
        return calibrator_predict_proba(calib_obj, split_number)

    calib_res = [np.hstack(
                    [
                        model_results.loc[i, "class"].values.reshape(-1, 1),
                        get_results_for_split(i)[:, 1].reshape(-1, 1)
                    ])
                 for i in range(splits)]

    df = pd.concat({
            i: pd.DataFrame(data) for i, data in enumerate(calib_res)
            })

    df.columns = ["class", "proba"]
    return df

def _cv_calibrate(X, y, model_obj, splits=5, calib_types=None, **cv_engine_kwargs):
    """
    Returns CV results for passed model, and calibrates results.
    """
    model_res = _cv_proba(
                    X=X, y=y,
                    model_obj=model_obj,
                    splits=splits,
                    **cv_engine_kwargs
                    )

    df = pd.concat({
            i: pd.DataFrame(data) for i, data in enumerate(chain(*model_res))
        })

    df.columns = ["class", "proba"]

    if calib_types is None:
        return pd.concat({"original_model": df}, axis=1)

    else:
        dfs_cal = pd.concat(
                    [
                        pd.concat({
                            cal_type.__name__ + "_cal": _calibrate_cv(df, cal_type, splits)
                            }, axis=1)
                        for cal_type in calib_types
                    ])

        return pd.concat({"original_model": df}, axis=1).join(dfs_cal)

def _custom_round_to_int(x, base=5):
    return int(base * round(float(x)/base))

def _custom_round_to_five_hundredth(x):
    return _custom_round_to_int(100 * x) / 100

def _prob_bin_stats(results, retain_counts=True):
    """
    Bins passed probabilities and calculates mean and std.
    actual positive class frequencies.
    """
    df = results.copy()
    df["prob_bin"] = df.proba.apply(_custom_round_to_five_hundredth)

    # group `df` by fold, class, and probablity bin
    grouped = df[["class", "prob_bin"]
                 ].groupby(
                    [df.index.get_level_values(0), # fold
                     "class",
                     "prob_bin"]
                 ).size()

    grouped = grouped.to_frame().rename(columns={0: "count"})

    grouped = grouped.unstack(1) # pop `class` out from row- to column-level-index
    grouped.columns = grouped.columns.droplevel() # drop `count` column above `class` numbers
    grouped = grouped.drop(0, axis=1) # retain only positive class
    grouped.columns = ["count_positive"] # update columns

    # group `df` by fold and probablity bin
    grouped_other = df[["prob_bin"]
                       ].groupby(
                          [df.index.get_level_values(0), # fold
                           "prob_bin"]
                       ).size()

    grouped_other = grouped_other.to_frame().rename(columns={0: "count_bin"})

    # join the two groupings on fold and probability bin
    joined = grouped.join(grouped_other)
    joined = joined.fillna(0)

    # calculate empirical probabilities
    joined['proportion_positive_of_bin'] = joined['count_positive'] / joined['count_bin']
    joined_reset = joined.reset_index().rename(columns={"level_0": "fold"})

    # handle counts
    if retain_counts is True:
        fold_totals = joined.groupby(level=0 # get total rows per fold
                   ).sum(
                   ).loc[:, "count_bin"
                   ].rename("fold_total"
                   ).reset_index(
                   ).rename(columns={"index": "fold"})

        # merge in, and scale bin counts by, fold totals
        joined_reset = joined_reset.merge(fold_totals, on="fold")
        joined_reset["proportion_bin_of_fold"] = joined_reset["count_bin"] / joined_reset["fold_total"]

        # select final columns
        cols_to_retain = ["prob_bin", "proportion_positive_of_bin", "proportion_bin_of_fold"]
        display_columns = ["empirical_probability", "proportion_of_test_data"]

    else:
        # select final columns
         cols_to_retain = ["prob_bin", "proportion_positive_of_bin"]
         display_columns = ["empirical_probability"]

    # aggregate results and return
    means = joined_reset[cols_to_retain].groupby("prob_bin").mean()
    means.columns = display_columns
    means = pd.concat({"mean": means}, axis=1)
    means.columns = means.columns.swaplevel()

    stds = joined_reset[cols_to_retain].groupby("prob_bin").std()
    stds.columns = display_columns
    stds = pd.concat({"std": stds}, axis=1)
    stds.columns = stds.columns.swaplevel()

    to_return = means.join(stds)
    to_return.index = to_return.index.rename("predicted_probability_bin")

    return to_return

def cv_calibrate(X, y, model_obj, splits=5, calib_types=None, retain_counts=True, **cv_engine_kwargs):
    """Return mean and std. CV results comparing actual positive
    class probabilities to binned predicted probabilities, for
    the original model and all passed calibrators."""
    res = _cv_calibrate(
                    X=X, y=y,
                    model_obj=model_obj,
                    splits=splits,
                    calib_types=calib_types,
                    **cv_engine_kwargs
                    )

    modeled = pd.concat({"original_model":
                _prob_bin_stats(res.loc[:, "original_model"], retain_counts=retain_counts)
                        }, axis=1)

    if calib_types is None:
        return modeled

    else:
        calib_results = [pd.concat(
                                {
                                    mod.__name__ + "_cal":
                                        _prob_bin_stats(res.loc[:, mod.__name__ + "_cal"],
                                                        retain_counts=retain_counts)
                                }, axis=1)
                        for mod in calib_types]
        return modeled.join(pd.concat(calib_results))


import os
import tensorflow as tf
import numpy as np
from tensorflow import keras
# from skimage import io
from tensorflow.keras.preprocessing import image
# from keras.models import Sequential
# from tensorflow._api.v1.keras import layers

# Flask utils
from flask import Flask, redirect, url_for, request, render_template, jsonify
from werkzeug.utils import secure_filename
from gevent.pywsgi import WSGIServer
import pandas as pd
import pickle

import warnings
from sklearn.exceptions import InconsistentVersionWarning

warnings.filterwarnings("ignore", category=InconsistentVersionWarning)

app = Flask(__name__, static_folder=r"C:\Users\Deepak\Desktop\crop\static")

model2 = tf.keras.models.load_model("best_plant_model.h5")
data = pd.DataFrame(pd.read_csv("final.csv"))
model = pickle.load(open(r"model.pkl", "rb"))
crop = pd.read_csv(r"final_dataset.csv").copy()
area = pd.read_csv(r"final_data.csv")
commodity = pd.read_csv(r"commodities.csv")

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/predictor')
def predictor():
    season = crop['Season'].unique()
    return render_template('predictor.html', seasons=season)

@app.route('/market')
def market():
    state1 = sorted(area['State'].unique())
    # print(states)  # Add this line to print the states

    area["District"] = area["State"] + "_" + area["District"]
    district1 = sorted(area['District'].unique())
    # print(district1)
    # area['Market'] = area['District'] + "_" + area['Market']
    markets = sorted(area['Market'])
    commodities = commodity["Commodities"].unique()
    return render_template('market.html', states=state1, districts=district1, commodities=commodities, markets=markets)

@app.route('/commodities')
def commodities():
    state1 = sorted(area['State'].unique())

    crop["District"] = area["State"] + "_" + area["District"]
    district1 = sorted(area['District'].unique())

    return render_template('commodities.html', states=state1, district1=district1)

@app.route('/predict', methods=['POST'])
def predict():
    pH = float(request.form.get('ph'))
    rainfall = float(request.form.get('rainfall'))
    temperature = float(request.form.get('temperature'))
    nitrogen = int(request.form.get('nitrogen'))
    phosphorus = int(request.form.get('phosphorus'))
    potassium = int(request.form.get('potassium'))
    humidity = float(request.form.get('humidity'))
    output = model.predict([[nitrogen, phosphorus, potassium, temperature, humidity, pH, rainfall]]),

    return ("{} Crop can be Grown".format(str(output[0])))

def about_disease(filtered_df, column):
    cause_values = filtered_df[column]

    f = ""
    for cause in cause_values:
        f = f + cause + ", "  # Separate multiple causes with a comma
    return f.rstrip(", ")  # Remove trailing comma and spaces

def load_prep(img_path):
    img = tf.io.read_file(img_path)

    img = tf.image.decode_image(img)

    img = tf.image.resize(img, size=(224, 224))

    return img

def model_predict(img_path, model2):
    image = load_prep(img_path)
    preds = model2.predict(tf.expand_dims(image, axis=0))
    return preds

@app.route('/disease', methods=['GET'])
def disease():
    # Main page
    return render_template('disease.html')

@app.route('/disease_pred', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        # Get the file from post request
        f = request.files['file']

        # Save the file to ./uploads
        basepath = os.path.dirname(__file__)
        file_path = os.path.join(
            basepath, 'uploads', secure_filename(f.filename))
        f.save(file_path)

        # Make prediction
        preds = model_predict(file_path, model2)
        print(preds)

        # x = x.reshape([64, 64]);
        disease_class = ['Apple___Apple_scab',
                         'Apple___Black_rot',
                         'Apple___Cedar_apple_rust',
                         'Apple___healthy',
                         'Blueberry___healthy',
                         'Cherry_(including_sour)___Powdery_mildew',
                         'Cherry_(including_sour)___healthy',
                         'Corn_(maize)___Cercospora_leaf_spot Gray_leaf_spot',
                         'Corn_(maize)___Common_rust_',
                         'Corn_(maize)___Northern_Leaf_Blight',
                         'Corn_(maize)___healthy',
                         'Grape___Black_rot',
                         'Grape___Esca_(Black_Measles)',
                         'Grape___Leaf_blight_(Isariopsis_Leaf_Spot)',
                         'Grape___healthy',
                         'Orange___Haunglongbing_(Citrus_greening)',
                         'Peach___Bacterial_spot',
                         'Peach___healthy',
                         'Pepper,_bell___Bacterial_spot',
                         'Pepper,_bell___healthy',
                         'Potato___Early_blight',
                         'Potato___Late_blight',
                         'Potato___healthy',
                         'Raspberry___healthy',
                         'Soybean___healthy',
                         'Squash___Powdery_mildew',
                         'Strawberry___Leaf_scorch',
                         'Strawberry___healthy',
                         'Tomato___Bacterial_spot',
                         'Tomato___Early_blight',
                         'Tomato___Late_blight',
                         'Tomato___Leaf_Mold',
                         'Tomato___Septoria_leaf_spot',
                         'Tomato___Spider_mites Two-spotted_spider_mite',
                         'Tomato___Target_Spot',
                         'Tomato___Tomato_Yellow_Leaf_Curl_Virus',
                         'Tomato___Tomato_mosaic_virus',
                         'Tomato___healthy']

        result = disease_class[preds.argmax()]

        filtered_df = data[data['Type'] == result]

        symptoms = about_disease(filtered_df, 'Symptoms')
        cause = about_disease(filtered_df, 'Cause')
        prevention = about_disease(filtered_df, 'Prevention')

        response = {
            'disease': result,
            'cause': cause,
            'symptoms': symptoms,
            'prevention': prevention
        }

        return jsonify(response)

if __name__ == '__main__':
    app.run();


from bioseq.bioseq import BioSeq, SequenceType
from bioseq.dnaseq import DNASeq
from bioseq.rnaseq import RNASeq
from bioseq.proteinseq import AminoacidSeq, ProteinSeq
import re

__types_dic = {
    'dna': DNASeq,
    'rna': RNASeq,
    'aa': AminoacidSeq,
    'aminoacid': AminoacidSeq,
    'protein': ProteinSeq,
}

def read_fasta_file(filename, sequence_type='dna', use_dic=True):
    dic = __create_dictionary(filename)
    Type = __types_dic[sequence_type]

    if use_dic:
        return {k:Type(v) for k,v in dic.items()}
    else:
        return [Type(v, k) for k,v in dic.items()]

def __create_dictionary(filename):
    dic = {}
    fd = open(filename)
    key = ''

    for line in fd:
        if len(line.strip()):
            line = line.strip()

            if(line[0] == '>'):
                key = line[1:]
                dic[key] = ''
            else:
                dic[key] += line

    fd.close()
    return dic


#%%
import typing
import numpy as np
from collections import namedtuple
import matplotlib.pyplot as plt
from pxr import Usd, UsdGeom, Gf, Vt

class SPHGeom:
    def __init__(self):
        self.sources = None
        self.boundaries = None
        self.sinks = None

class CubeGeom(SPHGeom):

    def __init__(self, x_lim=2*np.pi, y_lim=2*np.pi, z_lim=2*np.pi, halfres=None):
        super().__init__()
        self.x_lim = x_lim
        self.y_lim = y_lim
        self.z_lim = z_lim

        if halfres is not None:
            self.init_meshgrid(halfres)

    def init_meshgrid(self, halfres):
        """
        produces grid of 2^halfres x 2^halfres x 2^halfres number of particles
        """
        x_ = np.linspace((self.x_lim/(2**halfres)), self.x_lim, 2**halfres, endpoint=True)
        y_ = np.linspace((self.y_lim/(2**halfres)), self.y_lim, 2**halfres, endpoint=True)
        z_ = np.linspace((self.y_lim/(2**halfres)), self.z_lim, 2**halfres, endpoint=True)

        meshgrid = np.meshgrid(x_, y_, z_, indexing='ij')

        self.meshgrid = np.array(meshgrid).T.reshape(-1,3)
        self.N = self.meshgrid.shape[0]

        return self.meshgrid

MeshPoints = namedtuple('MeshPoints', ['counts', 'faces', 'points', 'normals'])

def transform_coords_xform(prim: Usd.Prim, points:Vt.Vec3fArray, normals:Vt.Vec3fArray) -> typing.Tuple[np.ndarray, np.ndarray]:
    world_transform = get_world_transform_xform(prim)
    newpoints = [world_transform.Transform(points[i]) for i in range(points.__len__())]
    newnormals = [world_transform.TransformDir(normals[i]) for i in range(normals.__len__())]
    return np.array(newpoints), np.array(newnormals)

def get_world_transform_xform(prim: Usd.Prim) -> Gf.Matrix4d:
    """
    Get the world transformation of a prim using Xformable.
    See https://graphics.pixar.com/usd/release/api/class_usd_geom_xformable.html
    or https://docs.omniverse.nvidia.com/prod_usd/prod_kit/programmer_ref/usd/transforms/get-world-transforms.html
    Args:
        prim: The prim to calculate the world transformation.
    Returns:
        The global transformation as a Matrix4d
    """
    xform = UsdGeom.Xformable(prim)
    time = Usd.TimeCode.Default() # The time at which we compute the bounding box
    world_transform: Gf.Matrix4d = xform.ComputeLocalToWorldTransform(time)
    return world_transform

def get_local_transform_xform(prim: Usd.Prim) -> Gf.Matrix4d:
    """
    Get the local transformation of a prim using Xformable.
    See https://graphics.pixar.com/usd/release/api/class_usd_geom_xformable.html
    Args:
        prim: The prim to calculate the local transformation.
    Returns:
        The local tranformation of that matrix as a Mtrix4d
    """
    xform = UsdGeom.Xformable(prim)
    local_transformation: Gf.Matrix4d = xform.GetLocalTransformation()
    return local_transformation

class USDAGeom(SPHGeom):
    def __init__(self, filename):
        super().__init__()
        self.filename = filename
        self.stage = Usd.Stage.Open(self.filename)
        self.boundaries = self.get_children_meshpoints('/Boundaries')
        self.sources = self.get_children_meshpoints('/Sources')

    def get_children_meshpoints(self, primname: str) -> typing.List[MeshPoints]:
        root = self.stage.GetPrimAtPath(primname)
        children: Usd.Prim = root.GetChildren()
        children_mesh = [child.GetChildren()[0] for child in children if child.GetChildren()[0].IsA(UsdGeom.Mesh)]

        mespoints_list = []
        for child in children_mesh:
            # print(bd.GetPath())
            counts = np.array(child.GetAttribute('faceVertexCounts').Get())
            faces = np.array(child.GetAttribute('faceVertexIndices').Get())
            points = child.GetAttribute('points').Get()
            normals = child.GetAttribute('normals').Get()

            newpoints, newnormals = transform_coords_xform(child, points, normals)
            meshpoints = MeshPoints(counts, faces, newpoints, newnormals)
            mespoints_list.append(meshpoints)

        return mespoints_list

    def visualize(self, how="mpl"):
        """
        visualize the geometry in usdview if available, otherwise use matplotlib
        """
        exit_status = 0

        if how=="usdview":
            import os
            print("Running comand: 'usdview' "+self.filename)
            exit_status = os.system("usdview "+self.filename)

        if how=="matplotlib" or exit_status != 0:
            print("usdview not available, using matplotlib")
            fig = plt.figure()
            ax = fig.add_subplot(projection='3d')

            for meshpoints in self.boundaries + self.sources:
                points = np.array([meshpoints.points[i] for i in meshpoints.faces])
                normals = meshpoints.normals

                ax.scatter(points[:,0], points[:,1], points[:,2], marker='o', label="points", color='r')

                q = ax.quiver(points[:,0], points[:,1], points[:,2], normals[:,0], normals[:,1], normals[:,2], label="normals", normalize=True, alpha=0.5, length=0.05)

            ax.set_xlabel('X')
            ax.set_ylabel('Y')
            ax.set_zlabel('Z')
            # plt.legend()
            # plt.show()
            return ax

if __name__=="__main__":
    geometry = USDAGeom("../demos/data/meshes/glass.usda")
    geometry.visualize()