from mpl_toolkits import mplot3d
import sys
import numpy as np
import matplotlib.pyplot as plt
#from mayavi import mlab

from matplotlib import animation
from IPython.display import HTML

# ### Some relevant parameters

# Select which plots and animations to compute and save
make3DtrajectoryPlot = False
makeSingleEnergyPlots = False
makeCombinedEnergyPlot = False
makeCOMdeviationPlot= False
make3Danimations = True
make_E_ifv_h_plot = False
make_E_ifv_driverfunctions = False
makeSingle2DtrajectoryPlots = False    # Plot of the xy-plane
makeCombined2DtrajectoryPlot = False   # Plot of the xy-plane

equaliseAspect = False # Set to True if you want all axes to have the same scale
# Do be careful with the 3D animation though, as it changes the camera angle
# from what you input below.

# The variables below are only relevant if make3Danimations==True

# How many steps are condensed into a single point in the 3D animation.
# Decreasing it results in a better animation resolution but a slower computation
stepsPerPoint = 2
# IF you want the animation to end earlier than the largest time in the file you
# read in, set this to when you want the animation to end.
endTime = 50 # sys.float_info.max()
fps = 10
# The elevation and azimuth of the camera in the 3D plots, in degrees.
elevation = 50
azimuth = 30
# The relative margin to be used in the limits of the axes of the 3D animation
# The formula for e.g. the lower x boundary will be
#           x_lower = x_min - relativeMargin*(x_max-x_min) + additiveMargin
# The additive margin is needed in cases where, for instance, z is always zero.
relativeMargin = 0.1
additiveMargin = 0.05

# ### Preparing to read in the data

# A list that will contain strings of all the methods selected.
method_all = []

# Lists that will contain a numpy array for each method in the order of selection.
t_all = []
E_all = []
Ereldif_all = []

# Lists that will contain a 2D array for each particle's coordinate per method.
# Yes, I know it's not pretty.
x_all = []
y_all = []
z_all = []

# ### Choose inputfiles

# Choose the first file
# Don't enter 'stop' just yet. You ought to select at least one method
method = input("Which file do you want to plot: ").lower()
bestand = "{}.txt".format(method)
while method != 'stop' :

    # ### Read inputfile
    f = open(bestand, "r")
    f.readline()    #first line is whitespace due to setprecision()

    AantalObjecten = int(f.readline()[1:])
    print("Number of objects: "+str(AantalObjecten))

    masses_str = f.readline()[1:]    # First character is '#'
    masses = [float(mass) for mass in (masses_str.strip('\t\n')).split('\t')]
    print('Masses: ', masses)
    f.close()

    # Load in the time and energy data and place them and the relative energy error in their respective lists.
    # This shouldn't need to be loaded in for every method IF they all used the same timestep. When adaptive
    # timesteps are used, it is highly unlikely that that condition would be met.
    load = np.loadtxt(bestand)
    t_all.append(load[:,0])
    E = load[:,1]
    E0 = E[0]
    E_all.append(E)
    Ereldif = (E - E0)/E0
    Ereldif_all.append(Ereldif)

    # Add empty lists to the coordinate superlists to house positions arrays of each particle for this method.
    x_all.append([])
    y_all.append([])
    z_all.append([])
    # Add the position coordinates of each particle to the 2D arrays of this method.
    for n in range(AantalObjecten):
        x_all[-1].append(load[:,(n*3+2)])
        y_all[-1].append(load[:,(n*3+3)])
        z_all[-1].append(load[:,(n*3+4)])

    # Add the previous method to the list, as that was not yet done.
    method_all.append(method)

    # Ask for the next method or to stop.
    print(" ")
    print("Enter 'stop' if you do not wish to add more methods.")
    method = input("Which file do you want to plot? (e.g rk4/Verlet/Forest-Ruth): ").lower()
    bestand = "{}.txt".format(method)

print('Selected methods: ' + str(method_all))

def set_axes_equal(ax):
    '''Make axes of 3D plot have equal scale so that spheres appear as spheres,
    cubes as cubes, etc..  This is one possible solution to Matplotlib's
    ax.set_aspect('equal') and ax.axis('equal') not working for 3D.

    Input
      ax: a matplotlib axis, e.g., as output from plt.gca().
    '''

    x_limits = ax.get_xlim3d()
    y_limits = ax.get_ylim3d()
    z_limits = ax.get_zlim3d()

    x_range = abs(x_limits[1] - x_limits[0])
    x_middle = np.mean(x_limits)
    y_range = abs(y_limits[1] - y_limits[0])
    y_middle = np.mean(y_limits)
    z_range = abs(z_limits[1] - z_limits[0])
    z_middle = np.mean(z_limits)

    # The plot bounding box is a sphere in the sense of the infinity
    # norm, hence I call half the max range the plot radius.
    plot_radius = 0.5*max([x_range, y_range, z_range])

    ax.set_xlim3d([x_middle - plot_radius, x_middle + plot_radius])
    ax.set_ylim3d([y_middle - plot_radius, y_middle + plot_radius])
    ax.set_zlim3d([z_middle - plot_radius, z_middle + plot_radius])

# ### Make a 3D trajectory plot, energy accuracy plots and a 3D animation for each method.
# j is used as an index here, as i is already defined in the animation section.
for j, method in enumerate(method_all) :

    # ### Make 3D figure of the trajectories
    if make3DtrajectoryPlot :
        fig = plt.figure(constrained_layout=True)
        ax = plt.axes(projection ='3d')
        for n in range(AantalObjecten):
            ax.plot3D(x_all[j][n], y_all[j][n], z_all[j][n], label='Particle'+str(n))
            #mlab.plot3d(load[:,n*3+2],load[:,n*3+3],load[:,n*3+4], t)
        #mlab.show()
        #extra dan ax2.plot(t,E)
        plt.title('Trajectories - method: ' + method, fontsize=18)
        plt.xlabel('x', fontsize=16)
        plt.ylabel('y', fontsize=16)
        ax.set_zlabel('z', fontsize=16)
        ax.legend()
        #plt.show()
        if equaliseAspect:
            set_axes_equal(ax)
        fig.savefig('3Dtrajectories_'+method, bbox_inches='tight', dpi=400)

    # ### Make subplots of the relative energy error for each method. Left panel is linear,
    # right panel is logarithmic.
    if makeSingleEnergyPlots :
        fig, ax = plt.subplots(1, 2, figsize=(16, 6))
        ax[0].plot(t_all[j], Ereldif_all[j])
        ax[0].set_xlabel('t', fontsize=16)
        ax[0].set_ylabel("$\\frac{\Delta E}{E_0}$ (/)", fontsize=16)
        ax[0].set_title('Linear accuracy - '+method, fontsize=18)
        ax[0].grid()

        ax[1].plot(t_all[j], np.log10(abs(Ereldif_all[j])))
        ax[1].set_xlabel('t', fontsize=16)
        ax[1].set_ylabel("$\\log_{10}( | \\frac{\Delta E}{E_0} | )$ (/)", fontsize=16)
        ax[1].set_title('Logarithmic accuracy - '+method, fontsize=18)
        ax[1].grid()

        #plt.show()
        fig.savefig('Energy errors_'+method, bbox_inches='tight', dpi=400)

    if make3Danimations :
        # ### Create an animation of the trajectories

        # Select a color from the 'rainbow' colormap for each particle
        color = plt.cm.rainbow(np.linspace(0, 1, AantalObjecten))

        # Make a figure and axis for animation.
        fig_anim = plt.figure(constrained_layout=True, figsize=(10, 10))
        #spec = fig.add_gridspec(2, 1)

        ax_anim = fig_anim.add_subplot(projection='3d')
        ax_anim.view_init(elev=elevation, azim=azimuth)

        # Animations do not choose limits automatically, so they are computed here.
        # We seek to find the largest and smallest x, y and z of any particle in this method.
        # We begin with the minima and maxima of the first particle and then check if the others are smaller or larger respectively.
        x_min = min(x_all[j][0])
        y_min = min(y_all[j][0])
        z_min = min(z_all[j][0])
        x_max = max(x_all[j][0])
        y_max = max(y_all[j][0])
        z_max = max(z_all[j][0])
        for n in range(1, AantalObjecten) :
            if min(x_all[j][n]) < x_min :
                x_min = min(x_all[j][n])
            if min(y_all[j][n]) < y_min :
                y_min = min(y_all[j][n])
            if min(z_all[j][n]) < z_min :
                z_min = min(z_all[j][n])

            if max(x_all[j][n]) > x_max :
                x_max = max(x_all[j][n])
            if max(y_all[j][n]) > y_max :
                y_max = max(y_all[j][n])
            if max(z_all[j][n]) > z_max :
                z_max = max(z_all[j][n])

        x_dif = x_max - x_min
        y_dif = y_max - y_min
        z_dif = z_max - z_min

        if equaliseAspect :
            dif = max([x_dif, y_dif, z_dif])
            x_mean = (x_max+x_min)/2
            y_mean = (y_max+y_min)/2
            z_mean = (z_max+z_min)/2
            x_min = x_mean-dif/2
            x_max = x_mean+dif/2
            y_min = y_mean-dif/2
            y_max = y_mean+dif/2
            z_min = z_mean-dif/2
            z_max = z_mean+dif/2

        # Using the minima and maxima as limits would mean the trajectories would go right to the edges of the animation, which does not look tidy.
        # As such, we add a small margin - defined above - to either side.
        x_lower = x_min - relativeMargin*x_dif - additiveMargin
        y_lower = y_min - relativeMargin*y_dif - additiveMargin
        z_lower = z_min - relativeMargin*z_dif - additiveMargin
        x_upper = x_max + relativeMargin*x_dif + additiveMargin
        y_upper = y_max + relativeMargin*y_dif + additiveMargin
        z_upper = z_max + relativeMargin*z_dif + additiveMargin

        # Set the computed limits
        ax_anim.set(xlabel='x', ylabel='y', zlabel='z',
                    xlim=(x_lower, x_upper), ylim=(y_lower, y_upper), zlim=(z_lower, z_upper))

        # Make "line" elements to update every frame.
        lines = []
        points = []
        for n in range(AantalObjecten):
            lines.append(ax_anim.plot([], [], [], color=color[n])[0])
            points.append(ax_anim.plot([], [], [], color=color[n], marker=".", ms=5)[0])

        def animate(i):
            """
            animate function is called every frame i.
            """

            index = int(i*stepsPerPoint)
            time = t_all[j][index]
            # print("time: {} \r".format(time), end="")

            fig_anim.suptitle("time: {}".format(time))    # Title changes every frame to show time.

            # Loop over all objects and change the figure.
            for n in range(AantalObjecten):
                lines[n].set_data(x_all[j][n][:index], y_all[j][n][:index])
                lines[n].set_3d_properties(z_all[j][n][:index])

                points[n].set_data(x_all[j][n][index], y_all[j][n][index])
                points[n].set_3d_properties(z_all[j][n][index])

            return fig_anim,

        print("Calculating frames...")

        if (endTime > t_all[j][-1]) :
            endTime = t_all[j][-1]
        endIndex = 0
        while (t_all[j][endIndex] < endTime) :
            endIndex += 1
        anim = animation.FuncAnimation(fig_anim, animate, frames=[i for i in range(round(endIndex/stepsPerPoint))], interval=1000/fps, blit=True) #50 geeft 20fps
        HTML(anim.to_jshtml())

        name = "3Danimation_"+ str(method) + ".mp4"
        anim.save(name)

# ### Make a single energy accuracy plot containing all methods for easy comparison
if makeCombinedEnergyPlot :
    fig, ax = plt.subplots(1, 2, figsize=(16, 6))
    for j, method in enumerate(method_all) :
        ax[0].plot(t_all[j], Ereldif_all[j], label=method)
        ax[1].plot(t_all[j], np.log10(abs(Ereldif_all[j])), label=method_all[j])

    ax[0].set_xlabel('t', fontsize=16)
    ax[0].set_ylabel("$\\frac{\Delta E}{E_0}$ (/)", fontsize=16)
    ax[0].set_title('Linear accuracy', fontsize=18)
    ax[0].grid()
    ax[0].legend()

    ax[1].set_xlabel('t', fontsize=16)
    ax[1].set_ylabel("$\\log_{10}( | \\frac{\Delta E}{E_0} | )$ (/)", fontsize=16)
    ax[1].set_title('Logarithmic accuracy', fontsize=18)
    ax[1].grid()
    ax[1].legend()

    #plt.show()
    fig.savefig('Energy errors_all', bbox_inches='tight', dpi=400)

 # Plot the total deviation of the centre of mass of the system from zero.
if makeCOMdeviationPlot :

    # Make a figure that all methods will be plotted in
    fig, ax = plt.subplots(2, 2, figsize=(16, 12))

    for j, method in enumerate(method_all) :
        # Ik maak bewust drie van die dingen indien we plots van individuele componenten willen maken.
        xdev = []
        ydev = []
        zdev = []

        # Compute the three coordinates of the centre of mass for each timestep.
        for k in range(len(x_all[j][0])) :
            x = 0
            y = 0
            z = 0
            for n in range(AantalObjecten) :
                x += masses[n] * x_all[j][n][k]
                y += masses[n] * y_all[j][n][k]
                z += masses[n] * z_all[j][n][k]
            xdev.append(x)
            ydev.append(y)
            zdev.append(z)
        xdev = np.array(xdev)
        ydev = np.array(ydev)
        zdev = np.array(zdev)
        COMdev = np.sqrt(xdev**2 + ydev**2 + zdev**2)

        # Plot the deviations of this method in the earlier defined figure
        ax[0][0].plot(t_all[j], COMdev, label=method_all[j])
        ax[0][1].plot(t_all[j], xdev, label=method_all[j])
        ax[1][0].plot(t_all[j], ydev, label=method_all[j])
        ax[1][1].plot(t_all[j], zdev, label=method_all[j])

    # Labelling and formatting of the subplots
    ax[0][0].set_xlabel('t', fontsize=14)
    ax[0][0].set_ylabel('$r_{CoM}$', fontsize=14)
    ax[0][0].grid()
    ax[0][0].legend(fontsize=12)

    ax[0][1].set_xlabel('t', fontsize=14)
    ax[0][1].set_ylabel('$x_{CoM}$', fontsize=14)
    ax[0][1].grid()
    ax[0][1].legend(fontsize=12)

    ax[1][0].set_xlabel('t', fontsize=14)
    ax[1][0].set_ylabel('$y_{CoM}$', fontsize=14)
    ax[1][0].grid()
    ax[1][0].legend(fontsize=12)

    ax[1][1].set_xlabel('t', fontsize=14)
    ax[1][1].set_ylabel('$z_{CoM}$', fontsize=14)
    ax[1][1].grid()
    ax[1][1].legend(fontsize=12)

    fig.savefig('COMdeviations_all', dpi=400, bbox_inches='tight')

if make_E_ifv_h_plot:

    #prepare figure
    fig, ax = plt.subplots(1, 1, figsize=(10, 5))
    ax.set(title = "E error ifv h", xlabel = "h", ylabel = "dE / E0", xscale="log", yscale = "log")
    ax.invert_xaxis()

    # load and plot file for each method
    for j, method in enumerate(method_all) :
        load = np.loadtxt("dE_ifv_h_" + method + ".txt", unpack=True)
        ax.plot(load[0], load[1], label=method)

    ax.legend()
    fig.savefig('dE_ifv_h', dpi=400, bbox_inches='tight')

if make_E_ifv_driverfunctions:
    fig, ax = plt.subplots(1, 1, figsize=(10, 5))
    ax.set(title = "E error ifv number of driver function evaluations",
           xlabel = "driver function evaluations", ylabel = "dE / E0",
           yscale = "log")

    # load and plot file for each method
    for j, method in enumerate(method_all) :
        load = np.loadtxt("dE_ifv_h_" + method + ".txt", unpack=True)
        ax.plot(load[2], load[1], label=method)

    ax.legend()
    fig.savefig('dE_ifv_driverfunctions', dpi=400, bbox_inches='tight')

if makeCombined2DtrajectoryPlot :
    fig, ax = plt.subplots(1, 1, figsize=(8, 6))
    ax.grid()
    for j, method in enumerate(method_all) :
        for n in range(AantalObjecten) :
            plt.plot(x_all[j][n], y_all[j][n], label=method+' '+str(n+1))
    if equaliseAspect :
        ax.set_aspect('equal')
    plt.xlabel('x (a.u.)', fontsize=16)
    plt.ylabel('y (a.u.)', fontsize=16)
    plt.legend(fontsize=12)
    fig.savefig('combined2Dtrajectory', bbox_inches='tight', dpi=400)

if makeSingle2DtrajectoryPlots :
    for j, method in enumerate(method_all) :
        fig, ax = plt.subplots(1, 1, figsize=(8, 6))
        ax.grid()
        for n in range(AantalObjecten) :
            plt.plot(x_all[j][n], y_all[j][n], label='particle'+' '+str(n+1))
        if equaliseAspect :
            ax.set_aspect('equal')
        plt.xlabel('x (a.u.)', fontsize=16)
        plt.ylabel('y (a.u.)', fontsize=16)
        plt.title(method, fontsize=18)
        fig.savefig('2Dtrajectory_'+method, bbox_inches='tight', dpi=400)


import os
import sys
import json
import api
import logging

def list_to_dict(l, key):
    d = dict()
    for e in l:
        d[e[key]] = e
    return d

def save_json_file(root, fname, obj):
    with open(os.path.join(root, fname), 'w') as f:
        json.dump(obj, f)
    logging.debug("Fetch success:" + fname)

def work_type_category(t, lang, sem, category):
    # 學士班課程、研究所課程
    data = {}
    # 學院列表
    collages = api.get_college(
        t,
        lang,
        sem,
        category)

    for collage, collage_name in collages.items():
        data[collage_name] = {}
        logging.debug("Fetch " + collage_name)
        deps = api.get_dep(
            t,
            lang,
            sem,
            category,
            collage
        )

        for dep, dep_name in deps.items():
            data[collage_name][dep_name] = {}
            logging.debug("Fetch " + dep_name)
            grades = api.get_grade(
                t,
                lang,
                sem,
                category,
                collage,
                dep
            )
            if len(grades) == 0:
                courses = api.get_cos_list(
                    sem,
                    dep
                )
                courses = api.course_id_pipe(courses)
                data[collage_name][dep_name]['all'] = courses
            else:
                for level in grades:
                    courses = api.get_cos_list(
                        sem,
                        dep,
                        str(level)
                    )
                    courses = api.course_id_pipe(courses)
                    data[collage_name][dep_name][level] = (courses)
    return data

def work_common_class(t, lang, sem, category):
    # 學士班共同課程、學分學程、跨域學程、其他課程、教育學程
    data = {}
    deps = api.get_dep(t, lang, sem, category, '*')
    for dep, dep_name in deps.items():
        logging.debug("Fetch " + dep_name)
        courses = api.get_cos_list(sem, dep)
        courses = api.course_id_pipe(courses)
        data[dep_name] = courses
    return data

def work_all_courses_data(sem):
    data = api.get_all_cos(sem)
    data = api.course_pipe(data)
    return data

def work(sem, root):
    lang = ['zh-tw', 'en-us'][0]
    types = list_to_dict(api.get_type(), 'cname')

    save_json_file(root, 'courses.json', work_all_courses_data(sem))
    save_json_file(root, 'bachelor.json', work_type_category(types['學士班課程']['uid'], lang, sem, '3*'))
    save_json_file(root, 'graduated.json', work_type_category(types['研究所課程']['uid'], lang, sem, '2*'))
    save_json_file(root, 'common.json', work_common_class(types['學士班共同課程']['uid'], lang, sem, '0G'))
    save_json_file(root, 'program.json', work_common_class(types['學分學程']['uid'], lang, sem, '0G'))
    save_json_file(root, 'cross.json', work_common_class(types['跨領域學程']['uid'], lang, sem, '0G'))
    save_json_file(root, 'others.json', work_common_class(types['其他課程']['uid'], lang, sem, '0G'))
    save_json_file(root, 'education.json', work_common_class(types['教育學程']['uid'], lang, sem, '0G'))


#! /usr/local/bin/python3

import argparse
import string
import collections

def cmp_key(a):
    return (-1 * a[1], a[0])

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('input_file', help='File of input data')
    args = parser.parse_args()

    input_file = open(args.input_file)
    input_lines = input_file.readlines()
    input_file.close()

    real_rooms = []

    for line in input_lines:
        x = line.find('[')
        a = line[:x]
        b = line[x:-1]
        parts = a.split('-')
        orig_name = ''.join(parts[:-1])
        name = orig_name.replace('-', '')
        sector = int(parts[-1])
        #print('input line: %s' % line.strip())
        #print('name: %s' % name)
        #print('sector: %s' % sector)
        c = collections.Counter(name)
        #print(c)

        common = sorted(c.most_common(), key=cmp_key, reverse=False)
        #print('sorted: %s' % common)
        top5 = ''.join([ltr for (ltr, cnt) in common[:5]])
        #print('top5: %s' % top5)
        checksum = b.strip('[]')
        #print('checksum: %s' % checksum)

        if checksum == top5:
            real_rooms.append((orig_name, sector))
        #print('')

    for (name, sector) in real_rooms:
        new_name = []
        for char in list(name):
            i = string.ascii_lowercase.find(char)
            ii = (i + sector) % 26
            new_name.append(string.ascii_lowercase[ii])
        new_name = ''.join(new_name)
        print('%s  sector: %s' % (new_name, sector))


# -*- coding: utf-8 -*-
"""
Created on Fri Oct 30 16:54:53 2015
Generalize Procedure class for doing anything to data
define both main function for processing and
optionally plotting functions for shot to shot
Two calculated plots and six parameter plots may be designated

Specific procedures will be subclassed.
@author: zachglassman
"""
from collections import OrderedDict
import inspect
class Procedure(object):
    """Class for defining procedure to operate on data"""
    def __init__(self,name,func = None, data = None, other = []):
        self.name = name
        #input, output, data, names bound to types for specific purpose
        #will be ordered dictionary for consistence
        #input is user input, other is things like ROI which are not parameters
        #input will be passed with default arguments
        self.input = OrderedDict()
        self.output = OrderedDict()
        self.data = OrderedDict()
        #define operatation on data, should be function
        #will always be able to
        self.operation = None
        #plotting function
        self.plot_func = None
        #list of plotted variables must be six or less
        self.plot_vars = []
        if func:
            self.create_from_function(func,data)

    @property
    def operation(self):
        return self._operation

    @operation.setter
    def operation(self, val):
        """set the function"""
        self._operation = val

    @property
    def plot_vars(self):
        return self._plot_vars

    @plot_vars.setter
    def plot_vars(self, var_list):
        self._plot_vars = var_list[:6]

    def create_from_function(self,func,data=None,other=[]):
        self.operation = func
        func_sig = inspect.getfullargspec(func)
        print(func_sig)
        self.input = None


import os
import argparse
import yaml
import subprocess
import time
from kubernetes import client, config
from base import init_logger

# Function to create a deployment from a YAML template with a given index
def create_deployment(infer_suffix, template_path, infer_type):
    with open(template_path) as f:
        dep = yaml.safe_load(f)

    # logger.info(dep)

    # Update the deployment name with the infer_suffix
    deploy_name = f"{dep['metadata']['name']}-deployment-{infer_suffix}"
    dep['metadata']['name'] = deploy_name

    # Update the label selector with the new deployment name
    # dep['spec']['selector']['matchLabels']['app'] = deploy_name
    # dep['spec']['template']['metadata']['labels']['app'] = deploy_name
    # dep['spec']['template']['spec']['containers'][0]['name'] = deploy_name

    # Update the environment variables infer_type with the infer_type, stream_name with the infer_suffix
    for container in dep['spec']['template']['spec']['containers']:
        for env in container['env']:
            if env['name'] == 'INFER_TYPE':
                env['value'] = infer_type
            elif env['name'] == 'STREAM_NAME':
                env['value'] = infer_suffix

    # Create the deployment
    apps_v1 = client.AppsV1Api()
    apps_v1.create_namespaced_deployment(
        body=dep, namespace="default")

if __name__ == "__main__":
    # Parse command line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument("--template_path", '-t',type=str, required=True, help="Path to deployment YAML template")
    parser.add_argument("--infer_type", '-i',type=str, required=True, help="infer_type for the name of queues")
    parser.add_argument("--begin_num",'-b', type=int, default=1, help="Starting number for name suffixes of deployment in a  queue")
    parser.add_argument("--end_num", '-e',type=int, default=50, help="Ending number for name suffixes of deployment in a queue")
    parser.add_argument("--begin_q",'-bq', type=int, default=1, help="Starting number for name suffixes of queue")
    parser.add_argument("--end_q", '-eq',type=int, default=1, help="Ending number for name suffixes of queue")
    parser.add_argument("--log_file", '-l',type=str, default="../logs/batch_deploy_multi_queue.log", help="log file name")
    parser.add_argument('--dry-run', action='store_true', help='Run the script in dry-run mode.')
    args = parser.parse_args()
    logger = init_logger(args.log_file)

    logger.info(f'the arguments: {args}')

    # Load Kubernetes configuration
    config.load_kube_config()

    # Create the specified number of deployments
    for q in range(args.begin_q, args.end_q+1):
        for i in range(args.begin_num, args.end_num+1):
            infer_suffix = f"{args.infer_type}-q{q:02d}-r{i:02d}"
            infer_type = f"{args.infer_type}-q{q:02d}"
            if args.dry_run:
                logger.info(f'dry-run======> infer_suffix: {infer_suffix}, args.template_path:{args.template_path},queue:{q},replic:{i}')
            else:
                logger.info(f'create_deployment=======> infer_suffix: {infer_suffix}, args.template_path:{args.template_path},queue:{q},replic:{i}')
                create_deployment(infer_suffix, args.template_path, infer_type)
                logger.info(f'after create_deployment wait 10 seconds ...')
                time.sleep(10)
                logger.info(f'10 seconds elapsed. ')


import uuid
from datetime import datetime

from fastapi import FastAPI
from pydantic import BaseModel

from database import database, users

app = FastAPI()

class User(BaseModel):
    email: str
    name: str

@app.on_event("startup")
async def startup():
    await database.connect()

@app.on_event("shutdown")
async def shutdown():
    await database.disconnect()

@app.get('/')
async def read_users():
    query = users.select()
    return await database.fetch_all(query)

@app.post('/')
async def create_user(user: User):
    query = users.insert().values(
        name=user.name,
        email=user.email,
        id=uuid.uuid4(),
        created=datetime.utcnow(),
    )
    await database.execute(query)
    return user.dict()


import modal

import stenops

mount = modal.Mount.from_local_dir(local_path=stenops.repo_root, remote_path="/stenops")

image = modal.Image.debian_slim(python_version="3.10").copy(mount).pip_install(["/stenops"])

stub = modal.Stub(
    name="stenops",
    image=image,
    secrets=[
        modal.Secret.from_name("OPENAI_API_KEY"),
    ],
)

if __name__ == "__main__":
    stub.run()


import torch
from torch.nn import TripletMarginLoss, CrossEntropyLoss, BCELoss
from torch.nn.functional import pairwise_distance
import numpy as np
from rune.model import *

class CosineEmbeddingTrainer:

    """
    Trainer for cosine embedding-based model.
    sequence pair -> encoder -> cosine embedding distance
    """

    def __init__(self):
        pass

    def init(self, model_params, lr, device, **kwargs):
        self.learning_rate = lr
        self.device = device

        self.model = RuneEncoder(21, **model_params).to(self.device)
        self.criterion = torch.nn.CosineEmbeddingLoss()
        self.optimizer = torch.optim.AdamW(self.model.parameters(), lr=self.learning_rate)

        self.train_loss = {"loss":[], "loss_pos":[], "loss_neg":[], "loss_mixed":[]}
        self.valid_loss = {"loss":[], "loss_pos":[], "loss_neg":[], "loss_mixed":[]}

        print("{:<20} {:<20} {:<20} {:<20}".format("epoch", "train_loss", "valid_loss", "lapse"))

    def run_epoch(self, dl_pos, dl_neg, train_mode=True):
        if train_mode:
            self.model.train()
        else:
            self.model.eval()

        batch_loss = {"loss":[], "loss_pos":[], "loss_neg":[], "loss_mixed":[]}

        for i, (batch_neg, batch_pos) in enumerate(zip(dl_pos, dl_neg)):
            self.optimizer.zero_grad()

            vec_neg, len_neg, y_neg = batch_neg
            vec_pos, len_pos, y_pos = batch_pos
            out_neg = self.model(vec_neg.to(self.device), len_neg.view(-1))
            out_pos = self.model(vec_pos.to(self.device), len_pos.view(-1))

            ind = len(out_neg) // 2
            out_neg_top = out_neg[:ind]
            out_neg_bot = out_neg[ind:]
            out_pos_top = out_pos[:ind]
            out_pos_bot = out_pos[ind:]

            y_true = torch.tensor([1] * ind, dtype=torch.float).to(self.device)
            y_false = torch.tensor([-1] * ind, dtype=torch.float).to(self.device)

            loss_neg = self.criterion(out_neg_top, out_neg_bot, y_true)
            loss_pos = self.criterion(out_pos_top, out_pos_bot, y_true)
            loss_mixed = self.criterion(out_neg_top, out_pos_top, y_false) + \
                         self.criterion(out_neg_bot, out_pos_bot, y_false)
            loss = loss_neg + loss_pos + loss_mixed

            batch_loss["loss"].append(loss.item())
            batch_loss["loss_pos"].append(loss_pos.item())
            batch_loss["loss_neg"].append(loss_neg.item())
            batch_loss["loss_mixed"].append(loss_mixed.item())

            if train_mode:
                loss.backward()
                self.optimizer.step()

        for key in batch_loss:
            if train_mode:
                self.train_loss[key].append(np.mean(batch_loss[key]))
            else:
                self.valid_loss[key].append(np.mean(batch_loss[key]))

    def print_loss(self, epoch, time_interval):
        print("{:<20} {:<20.5} {:<20.5} {:<20.5}".format(epoch+1, self.train_loss["loss"][epoch],
                                                         self.valid_loss["loss"][epoch], time_interval))


import os,scipy.misc
import keras.backend as K
from keras.models import Sequential, Model
from keras.layers import Conv2D, ZeroPadding2D, BatchNormalization, Input
from keras.layers import Conv2DTranspose, Reshape, Activation, Cropping2D, Flatten
from keras.layers.advanced_activations import LeakyReLU
from keras.optimizers import RMSprop
from keras.activations import relu
from keras.initializers import RandomNormal
from keras.preprocessing.image import ImageDataGenerator
from tqdm import tqdm
import numpy as np

conv_init = RandomNormal(0, 0.02)
gamma_init = RandomNormal(1., 0.02)

os.environ['KERAS_BACKEND']='tensorflow'
os.environ['TENSORFLOW_FLAGS']='floatX=float32,device=cuda'

def DCGAN_D(isize, nc, ndf):
    inputs = Input(shape=(isize, isize, nc))
    x = ZeroPadding2D()(inputs)
    x = Conv2D(ndf, kernel_size=4, strides=2, use_bias=False, kernel_initializer=conv_init)(x)
    x = LeakyReLU(alpha=0.2)(x)
    for _ in range(4):
        x = ZeroPadding2D()(x)
        x = Conv2D(ndf*2, kernel_size=4, strides=2, use_bias=False, kernel_initializer=conv_init)(x)
        x = BatchNormalization(epsilon=1.01e-5, gamma_init=gamma_init)(x, training=1)
        x = LeakyReLU(alpha=0.2)(x)
        ndf *= 2
    x = Conv2D(1, kernel_size=3, strides=1, use_bias=False, kernel_initializer=conv_init)(x)
    outputs = Flatten()(x)
    return Model(inputs=inputs, outputs=outputs)

def DCGAN_G(isize, nz, ngf):
    inputs = Input(shape=(nz,))
    x = Reshape((1, 1, nz))(inputs)
    x = Conv2DTranspose(filters=ngf, kernel_size=3, strides=2, use_bias=False,
                           kernel_initializer = conv_init)(x)
    for _ in range(4):
        x = Conv2DTranspose(filters=int(ngf/2), kernel_size=4, strides=2, use_bias=False,
                        kernel_initializer = conv_init)(x)
        x = Cropping2D(cropping=1)(x)
        x = BatchNormalization(epsilon=1.01e-5, gamma_init=gamma_init)(x, training=1)
        x = Activation("relu")(x)
        ngf = int(ngf/2)
    x = Conv2DTranspose(filters=3, kernel_size=4, strides=2, use_bias=False,
                        kernel_initializer = conv_init)(x)
    x = Cropping2D(cropping=1)(x)
    outputs = Activation("tanh")(x)

    return Model(inputs=inputs, outputs=outputs)

nc = 3
nz = 100
ngf = 1024
ndf = 64
imageSize = 96
batchSize = 64
lrD = 0.00005
lrG = 0.00005
clamp_lower, clamp_upper = -0.01, 0.01

netD = DCGAN_D(imageSize, nc, ndf)
netD.summary()

netG = DCGAN_G(imageSize, nz, ngf)
netG.summary()

clamp_updates = [K.update(v, K.clip(v, clamp_lower, clamp_upper))
                          for v in netD.trainable_weights]
netD_clamp = K.function([],[], clamp_updates)

netD_real_input = Input(shape=(imageSize, imageSize, nc))
noisev = Input(shape=(nz,))

loss_real = K.mean(netD(netD_real_input))
loss_fake = K.mean(netD(netG(noisev)))
loss = loss_fake - loss_real
training_updates = RMSprop(lr=lrD).get_updates(netD.trainable_weights,[], loss)
netD_train = K.function([netD_real_input, noisev],
                        [loss_real, loss_fake],
                        training_updates)

loss = -loss_fake
training_updates = RMSprop(lr=lrG).get_updates(netG.trainable_weights,[], loss)
netG_train = K.function([noisev], [loss], training_updates)

fixed_noise = np.random.normal(size=(batchSize, nz)).astype('float32')

datagen = ImageDataGenerator(
    # featurewise_center=True,
    # featurewise_std_normalization=True,
    rotation_range=20,
    rescale=1./255
)

train_generate = datagen.flow_from_directory("faces/", target_size=(96,96), batch_size=64,
                                                shuffle=True, class_mode=None, save_format='jpg')

step = 0
print(dir(train_generate))
for step in range(100000):

    for _ in range(5):
        real_data = (np.array(train_generate.next())*2-1)
        noise = np.random.normal(size=(batchSize, nz))
        errD_real, errD_fake  = netD_train([real_data, noise])
        errD = errD_real - errD_fake
        netD_clamp([])

    noise = np.random.normal(size=(batchSize, nz))
    errG, = netG_train([noise])
    print('[%d] Loss_D: %f Loss_G: %f Loss_D_real: %f Loss_D_fake %f' % (step, errD, errG, errD_real, errD_fake))

    if step%1000==0:
        netD.save("discriminator.h5")
        netG.save("generate.h5")
        fake = netG.predict(fixed_noise)
        display_grid = np.zeros((8*96,8*96,3))

        for j in range(int(64/8)):
            for k in range(int(64/8)):
                display_grid[j*96:(j+1)*96,k*96:(k+1)*96,:] = fake[k+8*j]
        img_save_path = os.path.join(os.getcwd(),"saved/img/{}.png".format(step))
        scipy.misc.imsave(img_save_path, display_grid)


import logging
import sqlite3
import threading
lock = threading.RLock()
class SqliteHelperError(Exception):
        def __init__(self, msg):
                self.msg = msg
        def __str__(self):
                return self.msg
class SqliteHelper:
	def __init__(self,name,connect=True):
		self.name=name
		self.connection = None
		if connect:self.connect()
	def connect(self):
		self.connection = sqlite3.connect(self.name)
		self.connection.execute("PRAGMA foreign_keys = 1")
		self.connection.commit()
	def __del__(self):
		if self.connection:self.connection.close()
		self.connection = None
	def get_data_sql(self,sql):
		if not self.connection:self.connect()
		logging.debug(sql)
		lock.acquire()
		try:
			cursor = self.connection.cursor()
			cursor.execute(sql)
			ans = cursor.fetchall()
		except Exception:
			lock.release()
			raise
		lock.release()
		return ans
	def get_value_sql(self,sql,null_valid=False):
		ans = self.get_data_sql(sql)
		if len(ans)> 1 or (ans and len(ans[0])> 1): raise SqliteHelperError("error: get more then one value:"+ans + "for sql:"+sql)
		value = None if not ans else ans[0][0]
		if not null_valid and value == None : raise SqliteHelperError("error: didn't get value("+str(ans)+") for sql:"+sql)
		return value
	def get_list_sql(self,sql,encode=False):
		if encode: return [ value[0].encode("utf8") for value in self.get_data_sql(sql)]
		return [ value[0] for value in self.get_data_sql(sql)]
	def run_sql(self,sql,args=None,many=False):
		if not self.connection:self.connect()
		logging.debug(sql)
		lock.acquire()
		try:
			if args:
				if not many:
					self.connection.cursor().execute(sql,args)
				else:
					self.connection.cursor().executemany(sql,args)
			else: self.connection.cursor().execute(sql)
			self.connection.commit()
		except Exception:
			self.connection.commit()
			lock.release()
			raise
		lock.release()
	def insert_row_and_get_id(self,sql_insert,args):
		if not self.connection:self.connect()
		lock.acquire()
		id=-1
		try:
			cursor=self.connection.cursor()
			cursor.execute(sql_insert,args)
			id=cursor.lastrowid
			self.connection.commit()
			#id=cursor.lastrowid
		except Exception:
			self.connection.commit()
			lock.release()
			raise
		lock.release()
		return id


import csv
import xmlschema
import os

def parser(name, path):
    print("parsing started")
    f = open(path)
    csv_f = csv.reader(f)
    data = []
    for row in csv_f:
        data.append(row)
    f.close()

    xmlData = {}
    # criar o objeto que vai guardar os items,types e outletSize
    print("Creating the xmlData")
    for item in data[0]:
        xmlData[item] = {}
    # correr o arquivo csv e guardar os valores no xmlData
    for row in data[1:]:
        item = ''
        item_type = ""
        outlet_size = ''
        try:
            item = xmlData[data[0][0]].get(row[0])
            item_type = xmlData[data[0][2]].get(row[2])
            outlet_size = xmlData[data[0][6]].get(row[6])

        except:
            pass
        if item is None:
            xmlData[data[0][0]][row[0]] = {
                'name': row[0], 'id': len(xmlData[data[0][0]])}
        if item_type is None:
            xmlData[data[0][2]][row[2]] = {
                'name': row[2], 'id': len(xmlData[data[0][2]])}
        if outlet_size is None:
            xmlData[data[0][6]][row[6]] = {
                'name': row[6], 'id': len(xmlData[data[0][6]])}

    print("Start creating the string")
    # criar a string que sera o xml final
    string = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> <File>\n"

    string += "<Items>\n"
    print("Adding items")
    # adcionar os items na string a partir do xmlData
    for item in xmlData[data[0][0]]:
        string += f"""    <Item name=\"{xmlData[data[0][0]][item]['name']}\" id=\"{xmlData[data[0][0]][item]['id']}\"></Item>\n"""

    string += "</Items>\n"

    print('Addind types')
    string += "<Types>\n"
    # adcionar os tipos na string a partir do xmlData
    for a in xmlData[data[0][2]]:
        try:
            string += f"""    <Type name=\"{xmlData[data[0][2]][a]['name']}\" id=\"{xmlData[data[0][2]][a]['id']}\"></Type>\n"""
        except:
            pass
    string += "</Types>\n"
    print('Adding outlet sizes')
    string += "<OutletSizes>\n"
    # adcionar os tipos na string a partir do xmlData
    for a in xmlData[data[0][6]]:
        try:
            string += f"""    <OutletSize name=\"{xmlData[data[0][6]][a]['name']}\" id=\"{xmlData[data[0][6]][a]['id']}\"></OutletSize>\n"""
        except:
            pass
    string += "</OutletSizes>\n"

    print('Adding products')
    string += "<Products>\n"
    # corre o arquivo csv e adciona os produtos na string
    for row in data[1:]:
        try:
            format_float = "{:.2f}".format(float(row[8]))
            string += f"""<Item id=\"{xmlData[data[0][0]].get(row[0])['id']}\" type_id=\"{xmlData[data[0][2]].get(row[2])['id']}\" outlet_size_id=\"{xmlData[data[0][6]][row[6]]['id']}\">
                <Item_W > {row[1]} </Item_W >
                <Item_MRP>{row[3]}</Item_MRP>
                <Outlet_ID>{row[4]}</Outlet_ID>
                <Outlet_Year>{row[5]}</Outlet_Year>
                <Outlet_Lotation_Type>{row[7]}</Outlet_Lotation_Type>
                <Sales>{format_float}</Sales>\n</Item>\n"""

        except:
            pass
    # tags para fechar o xml
    string += "</Products></File>"
    print("Done")
    # grava o xml
    f = open(f"{os.path.dirname(os.path.realpath(__file__))}/XML/{name}.xml", "w")
    f.write(string)
    f.close()
    # validar o xml
    print("testing")
    my_schema = xmlschema.XMLSchema(
        f"{os.path.dirname(os.path.realpath(__file__))}/schema.xsd")
    is_valid = my_schema.is_valid(
        f"{os.path.dirname(os.path.realpath(__file__))}/XML/{name}.xml")
    text = '' if (is_valid) else 'in'
    print(f'The XML is {text}valid')
    return string


import os
import sys
import csv

import pandas as pd

from cfwf import read_cfwf

REGISTROS_TIPOS = {
    '1':'empresas',
    '2':'socios',
    '6':'cnaes_secundarios'
}

EMPRESAS_COLUNAS = [
    'cnpj',
    'matriz_filial',
    'razao_social',
    'nome_fantasia',
    'situacao',
    'data_situacao',
    'motivo_situacao',
    'nm_cidade_exterior',
    'cod_pais',
    'nome_pais',
    'cod_nat_juridica',
    'data_inicio_ativ',
    'cnae_fiscal',
    'tipo_logradouro',
    'logradouro',
    'numero',
    'complemento',
    'bairro',
    'cep',
    'uf',
    'cod_municipio',
    'municipio',
    'ddd_1',
    'telefone_1',
    'ddd_2',
    'telefone_2',
    'ddd_fax',
    'num_fax',
    'email',
    'qualif_resp',
    'capital_social',
    'porte',
    'opc_simples',
    'data_opc_simples',
    'data_exc_simples',
    'opc_mei',
    'sit_especial',
    'data_sit_especial'
]

EMPRESAS_COLSPECS = [
    (3, 17),
    (17 ,18 ),
    (18 ,168),
    (168,223),
    (223,225),
    (225,233),
    (233,235),
    (235,290),
    (290,293),
    (293,363),
    (363,367),
    (367,375),
    (375,382),
    (382,402),
    (402,462),
    (462,468),
    (468,624),
    (624,674),
    (674,682),
    (682,684),
    (684,688),
    (688,738),
    (738,742),
    (742,750),
    (750,754),
    (754,762),
    (762,766),
    (766,774),
    (774,889),
    (889,891),
    (891,905),
    (905,907),
    (907,908),
    (908,916),
    (916,924),
    (924,925),
    (925,948),
    (948,956)
]

EMPRESAS_DTYPE = {'capital_social':float}

SOCIOS_COLUNAS = [
    'cnpj',
    'tipo_socio',
    'nome_socio',
    'cnpj_cpf_socio',
    'cod_qualificacao',
    'perc_capital',
    'data_entrada',
    'cod_pais_ext',
    'nome_pais_ext',
    'cpf_repres',
    'nome_repres',
    'cod_qualif_repres'
]

SOCIOS_COLSPECS = [
    (3, 17),
    (17 ,18 ),
    (18 ,168),
    (168,182),
    (182,184),
    (184,189),
    (189,197),
    (197,200),
    (200,270),
    (270,281),
    (281,341),
    (341,343)
]

SOCIOS_DTYPE = {'perc_capital':float}

CNAES_COLUNAS = ['cnpj'] + [num for num in range(99)]
CNAES_COLSPECS = [(3,17)] + [(num*7+17,num*7+24) for num in range(99)]

CHUNKSIZE=100000

NOME_ARQUIVO_SQLITE = 'CNPJ_full.db'

def cnpj_full(input_path, tipo_output, output_path):

    if tipo_output == 'sqlite':
        import sqlite3
        conBD = sqlite3.connect(os.path.join(output_path,NOME_ARQUIVO_SQLITE))

    dados = read_cfwf(input_path,
                      type_width=1,
                      colspecs= {'1':EMPRESAS_COLSPECS,
                                 '2':SOCIOS_COLSPECS,
                                 '6':CNAES_COLSPECS},
                      names={'1': EMPRESAS_COLUNAS,
                             '2': SOCIOS_COLUNAS,
                             '6': CNAES_COLUNAS},
                      dtype={'1': EMPRESAS_DTYPE,
                         '2': SOCIOS_DTYPE},
                      chunksize=CHUNKSIZE)

    for i, dado in enumerate(dados):
        print('Processando bloco {}: até linha {}.'.format(i+1,(i+1)*CHUNKSIZE),
              end='\r')

        for tipo_registro, df in dado.items():

            if tipo_registro == '1': # empresas
                # Troca datas zeradas por vazio
                df['data_opc_simples'] = (df['data_opc_simples']
                        .where(df['data_opc_simples'] != '00000000',''))
                df['data_exc_simples'] = (df['data_exc_simples']
                        .where(df['data_exc_simples'] != '00000000',''))
                df['data_sit_especial'] = (df['data_sit_especial']
                        .where(df['data_sit_especial'] != '00000000',''))

            elif tipo_registro == '2': # socios
                # Troca cpf invalido por vazio
                df['cpf_repres'] = (df['cpf_repres']
                        .where(df['cpf_repres'] != '***000000**',''))
                df['nome_repres'] = (df['nome_repres']
                        .where(df['nome_repres'] != 'CPF INVALIDO',''))

                # Se socio for tipo 1 (cnpj), deixa campo intacto, do contrario,
                # fica apenas com os ultimos 11 digitos
                df['cnpj_cpf_socio'] = (df['cnpj_cpf_socio']
                        .where(df['tipo_socio'] == '1',
                               df['cnpj_cpf_socio'].str[-11:]))

            elif tipo_registro == '6': # cnaes_secundarios
                # Verticaliza tabela de associacao de cnaes secundarios,
                # mantendo apenas os validos (diferentes de 0000000)
                df = pd.melt(df,
                             id_vars=[CNAES_COLUNAS[0]],
                             value_vars=range(99),
                             var_name='cnae_ordem',
                             value_name='cnae')

                df = df[df['cnae'] != '0000000']

            if tipo_output == 'csv':
                if i > 0:
                    replace_append = 'a'
                    header=False
                else:
                    replace_append = 'w'
                    header=True

                nome_arquivo_csv = REGISTROS_TIPOS[tipo_registro] + '.csv'
                df.to_csv(os.path.join(output_path,nome_arquivo_csv),
                          header=header,
                          mode=replace_append,
                          index=False,
                          quoting=csv.QUOTE_NONNUMERIC)

            elif tipo_output == 'sqlite':
                replace_append = 'append' if i > 0 else 'replace'

                df.to_sql(REGISTROS_TIPOS[tipo_registro],
                          con=conBD,
                          if_exists=replace_append,
                          index=False)

    print('\nProcessamento concluído!')
    if tipo_output == 'csv':
        print(u'''
            Arquivos CSV gerados na pasta {}.
            '''.format(output_path))

    elif tipo_output == 'sqlite':
        conBD.close()
        print(u'''
            Arquivo SQLITE gerado: {}
            OBS: Uso de índices altamente recomendado!
            '''.format(os.path.join(output_path,NOME_ARQUIVO_SQLITE)))

def help():
    print('''
        Uso: python cnpj.py <arquivo_input> <output:csv/sqlite> <path_output>
        Exemplo: python cnpj.py data/F.K032001K.D81106D sqlite data/CNPJ.db
    ''')

def main():
    # python cnpj.py <arquivo_input> <output:csv/sqlite> <arquivo_output>
    if len(sys.argv) != 4:
        help()
        sys.exit(-1)
    else:
        input_path = sys.argv[1]
        tipo_output = sys.argv[2]
        output_path = sys.argv[3]

        if tipo_output not in ['csv','sqlite']:
            print('''
                Erro: tipo de output inválido.
                Escolha um dos seguintes tipos de output: csv ou sqlite.
            ''')

            help()
        else:
            cnpj_full(input_path, tipo_output, output_path)

if __name__ == "__main__":
    main()


from selenium import webdriver
from dotenv import load_dotenv
load_dotenv()
import unittest
import time
import os
from selenium.common.exceptions import NoSuchElementException

# Setup Driver
url = os.environ.get('SELENIUM_URL') or "https://ibmdotcom-react-canary.mybluemix.net/"
driver = webdriver.Chrome()
driver.maximize_window()
driver.refresh()
driver.get(url)
time.sleep(3)

parenthandle = driver.current_window_handle
Masthead = driver.find_element_by_xpath("//span[contains(.,'Masthead')]")
Masthead.click()
print("Clicked on Masthead component")
time.sleep(2)

#Masthead_Default = driver.find_element_by_xpath("//span[contains(.,'Default')]")
#Masthead_Default.click()
#print("Clicked on Masthead default component ")
#time.sleep(2)

full_screen = driver.find_element_by_xpath("//*[contains(@title, 'Open canvas in new tab')]")
full_screen.click()
print("Masthead component opened in new tab")
time.sleep(4)

handles = driver.window_handles
for handle in handles:

    if handle not in parenthandle:
        driver.switch_to.window(handle)

        try:
            Masthead_Logo = driver.find_element_by_xpath("//a[@data-autoid='dds--masthead-logo__link']")
            if Masthead_Logo.is_displayed():
                print("IBM Logo is present")

        except NoSuchElementException:
            print(" ")

        try:
            Search_Icon = driver.find_element_by_css_selector(".bx--header__search--search")
            if Search_Icon.is_displayed():
                print("Search Icon is present")
                #Search_Icon.click()
                time.sleep(3)

        except NoSuchElementException:
            print("No such element found on page")

        try:
            Profile_Icon = driver.find_element_by_xpath("//*[@data-autoid='dds--masthead__profile']")
            if Profile_Icon.is_displayed():
                print("Profile icon is present")

        except NoSuchElementException:
            print("No such element is present")

        Masthead_Logo = driver.find_element_by_xpath("//a[@data-autoid='dds--masthead-logo__link']")
        Masthead_Logo.click()
        print("Clicked on Mathead IBM logo")
        time.sleep(4)
        if "IBM - India" ==driver.title:
            print("Page title is :" + driver.title)
        time.sleep(2)

        driver.execute_script("window.history.go(-1)")
        time.sleep(8)

        ProfileIcon1 = driver.find_element_by_xpath("//button[@class='bx--header__action bx--overflow-menu']").click()
        print("CLicked on user profile icon")
        time.sleep(3)

        ProfileIcon = driver.find_element_by_css_selector("li.bx--overflow-menu-options__option:nth-child(1)").value_of_css_property("height")
        print("User profile dropdown menu height in pixel is :" + ProfileIcon)

        Navigation = driver.find_element_by_xpath("//a[contains(text(),'Products')]")
        Navigation.click()
        time.sleep(2)

        Navigation_Item = driver.find_element_by_css_selector("li.bx--header__submenu:nth-child(1) > ul:nth-child(2) > li:nth-child(1) > a:nth-child(1)").value_of_css_property("height")
        print("Navigation item height in pixel is :" + Navigation_Item)

        Click_NavigationLink = driver.find_element_by_xpath("//div[contains(@class,'bx--header__search')]//li[1]//ul[1]//li[4]//a[1]")
        Click_NavigationLink.click()
        time.sleep(5)

        driver.execute_script("window.history.go(-1)")
        time.sleep(8)

        print("With browser window set to 672px")
        driver.set_window_size(682,450)
        time.sleep(2)

        Hamburger_Icon = driver.find_element_by_css_selector(".bx--header__menu-trigger")
        Hamburger_Icon.click()
        print("Clicked on hamburger menu icon")
        time.sleep(2)

        Click_NavgLink = driver.find_element_by_xpath("//span[contains(text(),'Developers')]")
        Click_NavgLink.click()
        time.sleep(1)

        Click_Back = driver.find_element_by_css_selector("li.bx--side-nav__item:nth-child(4) > ul:nth-child(2) > li:nth-child(1) > a:nth-child(1) > span:nth-child(1)")
        Click_Back.click()
        time.sleep(5)

        Click_CloseIcon = driver.find_element_by_css_selector(".bx--header__menu-trigger")
        Click_CloseIcon.click()
        time.sleep(1)

        Search_Icon = driver.find_element_by_css_selector(".bx--header__search--search")
        Search_Icon.click()
        print("Search icon clicked")
        time.sleep(3)

        Search_Keyword = driver.find_element_by_xpath("//input[@name='q']")
        Search_Keyword.send_keys("IBM")
        Search_Keyword.submit()
        print("Search keyword is entered")
        time.sleep(5)
        print("Search Page Title is :" + driver.title)

driver.quit()


# Used Pillow Docs at https://pillow.readthedocs.io/en/stable/reference/ImageDraw.html for help
# Font OdubeeSans-Regular.ttf is downloaded from Google Fonts at https://fonts.google.com/specimen/Odibee+Sans#pairings
# Function for finding file extension found at https://www.geeksforgeeks.org/how-to-get-file-extension-in-python/
# Iterating through files found at https://www.geeksforgeeks.org/how-to-iterate-over-files-in-directory-using-python/
# Numbers for Exif Tags found at https://www.exiv2.org/tags.html
# OpenCV docs used at https://docs.opencv.org/3.4/d9/df8/tutorial_root.html for help with OpenCV
# Help with user input in Python found at https://www.geeksforgeeks.org/taking-input-in-python/
# Check if the file is a directory found at https://www.geeksforgeeks.org/python-check-if-a-file-or-directory-exists/

import cv2 as cv
import os, time, glob
from PIL import Image
import sys
from pathlib import Path

# A function to recursively add text to pictures and add them as frames of the video
def Rec(folderInp):
    # os.path
    # files = glob.glob("./*")
    # files =
    #folderInp = "/Users/clewarne/" + folderInp
    os.chdir(folderInp)
    #filepath = os.listdir(folderInp)
    filepath = glob.glob("*")
    #print(os.path)
    filepath.sort(key=os.path.getmtime)

    # A loop to execute on every file in the directory given, they are sorted alphabetically
    for files in filepath:
       # print(files)
       #files = files[2:]
       # print(files)

       # Some String manipulation for file paths below, the above is some string manipulation, for some reason
       # this is necessary sometimes with the hard drive, I do not understand why this is
        f = os.path.join(folderInp,files)
        names = os.path.splitext(f)
        # If the file being looked at is actually a directory, the code is essentially paused, this same
        # function is then called using a file path that is extended with the new directory appended on it
        if os.path.isdir(f):
            tempInp = folderInp
            folderInp = f
            Rec(folderInp)
            folderInp = tempInp
        # If the file is an image, (.PNG, .jpg, .jpeg, etc.), the next part is executed, if not, it is skipped
        # and the next file is accessed at the start of the for loop
        if names[1] == '.PNG' or names[1] == '.jpg' or names[1] == '.jpeg' or names[1] == '.JPG' or names[1] == '.png' or names[1] == '.JPEG':
            img = cv.imread(cv.samples.findFile(f))
            with Image.open(f).convert("RGBA") as base:
                # Gets the date and time of the picture using exif tags
                dateTime = base.getexif()[0x0132]
            # Prints the date and time that will be added to the picture, this is for me to make sure that the program is
            # running well while it is happening
            print(dateTime)
            # Creates a new image object by combining the old image and the text, this new image is not saved
            newImg = cv.putText(img,dateTime,(100,200),cv.FONT_HERSHEY_SIMPLEX,4.0,(0,0,0),10,cv.FILLED,False)
            # The image is then added as the next frame of the video that we defined in the beginning
            vidOutput.write(newImg)

# A function to add text to the pictures in the folder given. However, in this function,
# folders are skipped over like other, non-image files and no recursion occurs
def noRec():

    # folderInp = "/Users/clewarne/" + folderInp
    os.chdir(folderInp)
    # filepath = os.listdir(folderInp)
    filepath = glob.glob("*")
    # print(os.path)
    filepath.sort(key=os.path.getmtime)
    # A loop to execute on every file in the directory given, they are sorted alphabetically
    for files in filepath:
        # print(files)
        # files = files[2:]
        # print(files)

        # Some String manipulation for file paths below, the above is some string manipulation, for some reason
        # this is necessary sometimes with the hard drive, I do not understand why this is
        f = os.path.join(folderInp,files)
        names = os.path.splitext(f)
        # If the file is an image, (.PNG, .jpg, .jpeg, etc.), the next part is executed, if not, it is skipped
        # and the next file is accessed at the start of the for loop
        if names[1] == '.PNG' or names[1] == '.jpg' or names[1] == '.jpeg' or names[1] == '.JPG' or names[1] == '.png' or names[1] == '.JPEG':
            img = cv.imread(cv.samples.findFile(f))
            with Image.open(f).convert("RGBA") as base:
                # Gets the date and time of the picture using exif tags
                dateTime = base.getexif()[0x0132]
            # Prints the date and time that will be added to the picture, this is for me to make sure that the program is
            # running well while it is happening
            print(dateTime)
            # Creates a new image object by combining the old image and the text, this new image is not saved
            newImg = cv.putText(img,dateTime,(100,200),cv.FONT_HERSHEY_SIMPLEX,4.0,(0,0,0),10,cv.FILLED,False)
            # The image is then added as the next frame of the video that we defined in the beginning
            vidOutput.write(newImg)
# Gets inputs to determine locations of files that will be the input or output, along with some preferences
folderInp = input("File path for folder that contains pictures to add text to: ")
folderOut = input("Folder to add the completed time lapse to: ")
OutputStr = input("What would you like to name the time lapse? ")
folders = input("Would you like to read any subfolders in the current directory?(y/n) ")
# folderInp = '2019_Selected_Time_Lapse_Photos_copy'
# folderOut = 'OutputTest'
# OutputStr = 'PresentationDemo'
# folders = 'y'

# Some simple string manipulation to create actual file paths
fileNum = 0
fileStr = ""
if folderOut != '':
    folderOut += '/'
outputLoc = folderOut + OutputStr + '.mov'
text = ""
dateTime = ""
# Creating an empty video with no frames, this will be added to
vidOutput = cv.VideoWriter(outputLoc,cv.VideoWriter_fourcc(*'jpeg'),15,(6000,4000))
# Getting the exact time, mainly for debugging, to determine later how long the program takes to execute
ts = time.time()

# There are two functions to be executed, one if subfolders are to be looped through and one if they are not
# The one that is executed is determined by the user's answer to the question earlier
if folders == 'y':
    Rec(folderInp)
else:
    noRec()

# Check current time and calculate the amount of time this process has taken, the above functions will have
# completed entirely before these execute
tm = time.time()
print(tm - ts)

# Below this, is a piece of code that I may need in the future to check if an image is empty,
# I may use this somewhere so I am keeping it at the bottom for now

#if img is None:
 #   sys.exit("Could not read image")


# vim: set fileencoding=utf8 :
import crits.models as models
import crits.trackable_fetcher as trackable_fetcher
import os

from django.test import TestCase
from mock import Mock

class FeedItem(object):
    def __init__(self, title):
        self.title = title

class FeedStub(object):
    def __init__(self):
        self.entries = [
            FeedItem('test1'),
            FeedItem('test2'),
            FeedItem('test3')
        ]

class FetcherTest(TestCase):
    def setUp(self):
        parser = Mock()
        parser.parse = Mock()
        parser.parse.return_value = FeedStub()
        self.fetcher = trackable_fetcher.Fetcher(
            'feedurl',
            parser=parser,
            type='movie'
        )
        self.fetcher.import_feed()

    def test_should_store_the_feed_titles_in_the_database(self):
        self.assertEqual(len(models.Trackable.objects.filter(type='movie')), 3)

    def test_should_ignore_duplicated_titles(self):
        self.fetcher.import_feed()
        self.assertEqual(len(models.Trackable.objects.filter(type='movie')), 3)

    def test_should_store_the_correct_type(self):
        self.assertEqual(models.Trackable.objects.get(id=1).type, 'movie')

class MyAnimeListParserTest(TestCase):
    def setUp(self):
        self.mock = Mock()
        tmp = self.mock.urlopen.return_value
        tmp.read.return_value = self._file_contents()

        self.parser = trackable_fetcher.MyAnimeListParser(
            urllib=self.mock
        )
        self.fetcher = trackable_fetcher.Fetcher(
            'http://myanimelist.net/anime.php?popular',
            type='anime',
            parser=self.parser
        )
        self.fetcher.import_feed()

    def _file_contents(self):
        path = os.path.join(os.path.dirname(__file__), 'test_myanilist')
        with open(path, 'r') as f:
            return f.read()

    def test_should_call_urllib_correctly(self):
        args, kwds = self.mock.urlopen.call_args
        self.assertEqual(
            args[0],
            'http://myanimelist.net/anime.php?popular'
        )

    def test_should_create_the_trackables(self):
        ani_list =  [
            u"Bleach", u"Naruto: Shippuuden", u"One Piece",
            u"Fullmetal Alchemist: Brotherhood", u"Valkyria Chronicles",
            u"Soul Eater", u"K-ON!", u"07-Ghost", u"Katekyo Hitman Reborn!",
            u"Higashi no Eden", u"Gintama",
            u"The Melancholy of Haruhi-chan Suzumiya",
            u"Hatsukoi Limited", u"Code Geass - Hangyaku no Lelouch R2",
            u"Hetalia Axis Powers", u"Toradora!", u"Pandora Hearts",
            u"Code Geass - Hangyaku no Lelouch", u"Clannad ~After Story~",
            u"Kuroshitsuji", u"Naruto", u"Death Note",
            u"Phantom ~Requiem for the Phantom~", u"Shangri-La",
            u"Fullmetal Alchemist", u"The Melancholy of Haruhi Suzumiya 2",
            u"Hajime no Ippo: New Challenger", u"Darker than BLACK",
            u"Lucky ☆ Star", u"Tengen Toppa Gurren Lagann",
            u"Ouran High School Host Club",
            u"The Melancholy of Haruhi Suzumiya", u"Chrome Shelled Regios",
            u"D.Gray-man", u"Clannad", "Higurashi no Naku Koro ni",
            u"Eureka Seven", u"Hajime no Ippo", u"Dragon Ball Kai",
            u"Kurokami", u"Hayate the Combat Butler!", u"NANA", u"Basquash!",
            u"Guin Saga", u"Asura Cryin'", u"Fate/stay night",
            u"Neon Genesis Evangelion", u"Great Teacher Onizuka",
            u"Skip Beat!", u"Sora wo Kakeru Shoujo"
        ]
        self.assertTrue(all(map(
            lambda a: models.Trackable.objects.get(
                type='anime', name=a) != None,
            ani_list
        )))


#!/usr/bin/env python3

import re
import sys
import os
from pathlib import Path

DEFAULT_DIR = Path("~/Desktop").expanduser()

def request_file_name(init_dir):
    from tkinter import filedialog, Tk

    root = Tk()
    root.withdraw()
    md_file = filedialog.askopenfilename(
        initialdir=init_dir, filetypes=[("Markdown files", ".md .MD")]
    )
    if md_file:
        return md_file

def translate(pattern="{}", g=1):
    def inline(match):
        s = match.group(g)
        return pattern.format(s)
    return inline

def markdown_to_bbcode(s):
    codes = []

    s = re.sub(r"(?m)\[(.*?)\]\((https?:\/\/\S+)\)", "[url=\\2]\\1[/url]", s)
    s = re.sub(r"(?m)([*_]{2})(\w+?)\1", "[b]\\2[/b]", s)
    s = re.sub(r"(?m)(?:^| )[^@#\s_`]?_([^_]+)_", "[i]\\1[/i]", s)
    s = re.sub(r"(?m)\B([*])\b(\S.+?)\1", "[i]\\2[/i]", s)
    s = re.sub(r"(?m)\B@(.*?)(['\s.,:!?\"])", "[mention]\\1[/mention]\\2", s)
    s = re.sub(r"(?m) {4}(.*)$", "~[code]\\1[/code]", s)
    s = re.sub(r"(?m)^!\[\]\((.*?)\)$", "~[img]\\1[/img]", s)
    s = re.sub(r"(?m)^(\S.*)\n=+\s*$", translate("~[size=200][b]{}[/b][/size]"), s)
    s = re.sub(r"(?m)(`)(.*?)(`)", "[c]\\2[/c]", s)
    s = re.sub(r"(?m)^(\S.*)\n-+\s*$", translate("~[size=100][b]{}[/b][/size]"), s)
    s = re.sub(r"(?m)^#\s+(.*?)\s*#*$", translate("~[size=200][b]{}[/b][/size]"), s)
    s = re.sub(r"(?m)^##\s+(.*?)\s*#*$", translate("~[size=100][b]{}[/b][/size]"), s)
    s = re.sub(r"(?m)^###\s+(.*?)\s*#*$", translate("~[b]{}[/b]"), s)
    s = re.sub(r"(?m)^> (.*)$", translate("~[quote]{}[/quote]"), s)
    s = re.sub(r"(?m)^[-+*]\s+(.*)$", translate("~[list]\n[*]{}\n[/list]"), s)
    s = re.sub(r"(?m)^\d+\.\s+(.*)$", translate("~[list=1]\n[*]{}\n[/list]"), s)
    s = re.sub(r"(?m)^((?!~).*)$", translate(), s)
    s = re.sub(r"(?m)^~\[", "[", s)
    s = re.sub(r"(?m)\[/code]\n\[code(=.*?)?]", "\n", s)
    s = re.sub(r"(?m)\[code(=.*?)?]\[/code]", "", s)
    s = re.sub(r"(?m)\[/quote]\n\[quote]", "\n", s)
    s = re.sub(r"(?m)\[/list]\n\[list(=1)?]\n", "", s)

    return s

def markdown_to_html(text=None):
    try:
        from markdown import markdown

        text = markdown(text)
    except ImportError:
        print(
            "to convert text to HTML, install markdown package with\n"
            "`pip install markdown`"
        )
    return text

def write_file(file_name, text, suffix):
    with open(file_name + suffix, "w") as out:
        out.write(text)
        print(f"[md2Reactor] created {out.name}")

def main(file):
    if not file or not file.exists() or not file.suffix.lower() == ".md":
        print("no markdown file selected")
        return

    with open(file, "r") as fp:
        text = fp.read()

    file_name = os.path.splitext(file)[0]

    bbcode_text = markdown_to_bbcode(text)
    write_file(file_name, bbcode_text, "_bbcode.txt")

    atom_text = markdown_to_html(text)
    if atom_text:
        write_file(file_name, atom_text, "_atom.html")

    print("Done!")

if __name__ == "__main__":
    if len(sys.argv) >= 2:
        for file_path in sys.argv[1:]:
            file_path = Path(file_path).absolute()
            main(file_path)
    else:
        try:
            import BlackmagicFusion as bmd

            fu = bmd.scriptapp("Fusion")
        except ImportError:
            print("no Fusion app found")

        folder = DEFAULT_DIR
        if fu:
            folder = fu.GetData("md2reactor.path")
        file_path = Path(request_file_name(folder))
        if file_path:
            if fu:
                fu.SetData("md2reactor.path", str(file_path.parent))
            main(file_path)


import asyncio
from typing import cast
from uuid import UUID

import orjson
from edgedb import AsyncIOExecutor
from pydantic import BaseModel, parse_raw_as

EDGEQL_QUERY = r"""
select Companies {
    id,
    name,
    facility: {
        id,
        address,
        city,
        name,
        state
    }
}
filter .id=<uuid>$company_id
"""

class GetFacilitiesResultFacility(BaseModel):
    id: UUID
    address: str | None
    city: str | None
    name: str
    state: str | None

class GetFacilitiesResult(BaseModel):
    id: UUID
    name: str
    facility: list[GetFacilitiesResultFacility]

async def get_facilities(
    executor: AsyncIOExecutor,
    *,
    company_id: UUID,
) -> GetFacilitiesResult | None:
    resp = await executor.query_single_json(
        EDGEQL_QUERY,
        company_id=company_id,
    )
    parsed = await asyncio.to_thread(
        parse_raw_as, GetFacilitiesResult | None, resp, json_loads=orjson.loads
    )
    return cast(GetFacilitiesResult | None, parsed)