import os
import testinfra.utils.ansible_runner
import pytest

testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
    os.environ['MOLECULE_INVENTORY_FILE']
).get_hosts('all')

@pytest.mark.parametrize("name", [
    ("apt-transport-https"),
    ("software-properties-common"),
    ("unattended-upgrades"),
    ("mailutils"),
    ("bsd-mailx"),
])
def test_default_packages(host, name):
    pkg = host.package(name)
    assert pkg.is_installed

def test_default_config_files_present(host):
    f = host.file("/etc/apt/apt.conf.d/50unattended-upgrades")
    assert f.exists
    assert f.is_file


#!/usr/bin/env python

from graph import DiGraph, before_after_calculations
import os
import json
import threading
import random
from datetime import date

def read_graphml_files():
    with open('tmp/interesting_graphs.txt') as fh:
        lines = [line.rstrip() for line in fh]

    return [(line, DiGraph.from_graphml(f"graphml/{line}")) for line in lines]

def process_graph(name, G, results):
    print(f"-- Processing graph {name}")
    rand_ports = [random.randrange(1, 65535) for i in range(50)]
    G_simulation, G_attack, stats = G.simulate_traffic(amount_of_rules=50, rand_ports=rand_ports)
    print("Finished processing")

    results.append(
        (
            before_after_calculations(
                f"{name} simulated",
                f"{name} simulated + attack",
                G_simulation,
                G_attack
            ),
            stats
        )
    )

def main():
    graphs = read_graphml_files()
    thread_list = []
    results = []

    for name, graph in graphs:
        thread = threading.Thread(target=process_graph, args=(name, graph, results))
        thread_list.append(thread)

    for thread in thread_list:
        thread.start()

    for thread in thread_list:
        thread.join()

    filename = f"networks_simulation_results_{date.today()}.json"

    # Überprüfen, ob Datei bereits existiert
    i = 0
    while os.path.isfile(filename):
        i += 1
        filename = f"networks_simulation_results_{date.today()}.{i}.json"

    # results = [process_graph(name, graph) for name, graph in graphs]
    with open(f"tmp/{filename}", 'a') as fh:
        fh.write(json.dumps(results))

if __name__ == "__main__":
    main()


import numpy as np
import gym
import cv2

class StackedEnv(gym.Wrapper):
    def __init__(self, env, width, height, n_img_stack, n_action_repeats):
        super(StackedEnv, self).__init__(env)
        self.width = width
        self.height = height
        self.n_img_stack = n_img_stack
        self.n_action_repeats = n_action_repeats
        self.stack = []

    def reset(self):
        img_rgb = super(StackedEnv, self).reset()
        img_gray = self.preprocess(img_rgb)
        self.stack = [img_gray] * self.n_img_stack
        return np.rollaxis(np.stack(self.stack, axis=2), 2, 0)

    def step(self, action):
        total_reward = 0
        done = False
        img_rgb = None
        info = None
        for i in range(self.n_action_repeats):
            img_rgb, reward, done, info = super(StackedEnv, self).step(action)
            total_reward += reward
            if done:
                break
        img_gray = self.preprocess(img_rgb)
        self.stack.pop(0)
        self.stack.append(img_gray)
        assert len(self.stack) == self.n_img_stack
        return np.rollaxis(np.stack(self.stack, axis=2), 2, 0), total_reward, done, info

    def preprocess(self, rgb_img):
        gray = np.dot(rgb_img[..., :], [0.299, 0.587, 0.114])
        gray = gray / 128. - 1.
        res = cv2.resize(gray, dsize=(self.height, self.width), interpolation=cv2.INTER_CUBIC)
        return res


import sys,re, os, io, codecs
from _collections import defaultdict

def loadModelfile():
    modelfile = sys.argv[1]
    features = defaultdict()

    #load model file into features
    with open(modelfile,"r", encoding = "ISO-8859-1") as modelhandler:
        model = modelhandler.readlines()
        for cldata in model:
            cldata = cldata.strip()
            cldata = cldata.split(" ")
            clname = cldata[0]
            cldata = cldata[1:]
            weights = defaultdict(float)
            for ft in cldata:
                ft = ft.split("=|")
                weights[ft[0]] = float(ft[1])
            features[clname] = weights

    input_stream = io.TextIOWrapper(sys.stdin.buffer,encoding = "ISO-8859-1")
    calculate_accuracy(input_stream,features)

def calculate_accuracy(lines,features):

    for line in lines:

        output=""
        line = line.strip()

        line = " ".join(line.split())

        data = line.split(" ")
        length = len(data)

        bos = "*BOS*"
        eos = "*EOS*"

        prevpos = bos
        prev2pos= bos
        prevclass= bos
        prev2class=bos

        i=0
        while(i<length):

            word = data[i]
            pos = word.rfind("/")
            postag = word[pos+1:]
            crnt = word[:pos]

            if(i==length-1):
                next =eos
                nextpos=eos
            else:
                nextdata = data[i+1]
                rpos = nextdata.rfind("/")
                nextpos = nextdata[rpos+1:]
                next = nextdata[:rpos]

            wshape = wordshape(crnt)

            ftarray = ["crnt|"+crnt, "crntpos|"+postag, "prevpos|"+prevpos,
                       "prevcls|"+prevclass, "prev2pos|"+prev2pos,"prev2cls|"+prev2class,
                       "next|"+next, "nextpos|"+nextpos, "wshape|"+wshape]

            scores = defaultdict()
            for key in features.keys():
                score = calculateScore(ftarray,features[key])
                scores[key]=score

            predClass = max(scores.keys(), key=(lambda key: scores[key] ))

            if(next == eos):
                prev2pos = bos
                prevpos= bos
                prevclass = bos
                prev2class = bos
            else:
                prev2pos = prevpos
                prev2class = prevclass
                prevpos = postag
                prevclass = predClass
            output+=word+"/"+predClass+" "

            #calculate Fscore and accuracy

            i+=1
        output=output.strip()+ os.linesep
        sys.stdout.write(output)
        sys.stdout.flush()

def wordshape(word):
    wshape = word
    wshape = re.sub("[A-Z]+","A",wshape)
    wshape = re.sub("[a-z]+","a",wshape)
    wshape = re.sub("[0-9]+","0",wshape)
    wshape = re.sub("[^A-Za-z0-9]+","_",wshape)
    return wshape

def calculateScore(data,weightVector):
    score = 0.0
    for ft in data:
        if(ft in weightVector.keys()):
            score+=weightVector[ft]
    return score

loadModelfile()


from components import decorators
from components import endpoints_webapp2

import webapp2

import api
import config
import notifications
import service
import swarming

README_MD = (
  'https://chromium.googlesource.com/infra/infra/+/master/'
  'appengine/cr-buildbucket/README.md')

class MainHandler(webapp2.RequestHandler):  # pragma: no cover
  """Redirects to README.md."""

  def get(self):
    return self.redirect(README_MD)

class CronResetExpiredBuilds(webapp2.RequestHandler):
  """Resets expired builds."""

  @decorators.require_cronjob
  def get(self):
    service.reset_expired_builds()

class CronUpdateBuckets(webapp2.RequestHandler):  # pragma: no cover
  """Updates buckets from configs."""

  @decorators.require_cronjob
  def get(self):
    config.cron_update_buckets()

class BuildHandler(webapp2.RequestHandler):  # pragma: no cover
  """Redirects to API explorer to see the build."""

  def get(self, build_id):
    api_path = '/_ah/api/buildbucket/v1/builds/%s' % build_id
    return self.redirect(api_path)

def get_frontend_routes():  # pragma: no cover
  routes = [
    webapp2.Route(r'/', MainHandler),
    webapp2.Route(r'/b/<build_id:\d+>', BuildHandler),
    endpoints_webapp2.discovery_service_route(),
  ]
  routes += endpoints_webapp2.api_routes(api.BuildBucketApi)
  routes += endpoints_webapp2.api_routes(swarming.SwarmbucketApi)
  return routes

def get_backend_routes():
  return [
    webapp2.Route(
      r'/internal/cron/buildbucket/reset_expired_builds',
      CronResetExpiredBuilds),
    webapp2.Route(
      r'/internal/cron/buildbucket/update_buckets',
      CronUpdateBuckets),
    webapp2.Route(
      r'/internal/task/buildbucket/notify/<build_id:\d+>',
      notifications.TaskPublishNotification),
  ]


import datetime
from PySide2.QtWidgets import QDialog

from ui_add_update import Ui_Dialog

class addDialog(QDialog):
    def __init__(self, *args, **kvargs):
        super().__init__(*args, **kvargs)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)

        self.ui.OkButton.clicked.connect(self.accept)
        self.ui.CancelButton.clicked.connect(self.reject)
        self.ui.dateEdit.setDate(datetime.date.today())
        self.ui.OkButton.clicked.connect(self.get_data)
        self.ui.sc1000.valueChanged.connect(self.set_label)
        self.ui.sc500.valueChanged.connect(self.set_label)
        self.ui.sc200.valueChanged.connect(self.set_label)
        self.ui.sc100.valueChanged.connect(self.set_label)
        self.ui.sc50.valueChanged.connect(self.set_label)

    def set_label(self):
        self.ui.lsc1000.setNum(1000*self.ui.sc1000.value())
        self.ui.lsc500.setNum(500*self.ui.sc500.value())
        self.ui.lsc200.setNum(200*self.ui.sc200.value())
        self.ui.lsc100.setNum(100*self.ui.sc100.value())
        self.ui.lsc50.setNum(50*self.ui.sc50.value())
        self.ui.label.setNum(1000*self.ui.sc1000.value()+500*self.ui.sc500.value()+200*self.ui.sc200.value()+100*self.ui.sc100.value()+50*self.ui.sc50.value())

    def get_data(self):
        return {
            "c_date": self.ui.dateEdit.date().toPython(),
            "c_1000": self.ui.sc1000.value(),
            "c_500": self.ui.sc500.value(),
            "c_200": self.ui.sc200.value(),
            "c_100": self.ui.sc100.value(),
            "c_50": self.ui.sc50.value()
        }


import numpy as np
import pandas as pd
from scipy import ndimage
from scipy.interpolate import interp1d

import astropy.units as u
import astropy.coordinates as coord
from astropy.cosmology import FlatLambdaCDM
from astropy.constants import M_sun

import tensorflow as tf
from flowpm import utils as ut

import copy
import time
from sys import argv,exit,byteorder

from field_util import Field

class FGPA(object):
    def __init__(self, fn, box_size = 512*u.Mpc, box_res = 256, origin = [3550*u.Mpc, -256*u.Mpc, -256*u.Mpc],
                 tau_0 = 1, T_0 = 1, beta = 1.6, gamma = 1.6, from_npy = True):
        if from_npy:
            self.dark = self.read_from_npy(fn)
        else:
            self.header, self.gas, self.dark, self.star = self.tipsy_read(fn)
            self.auxilinary(box_size, box_res)
        self.set_origin(origin)
        self.set_FGPA_param(tau_0, T_0, beta, gamma)

    def set_FGPA_param(self, tau_0 = None, T_0 = None, beta = None, gamma = None):
        if tau_0 is not None:
            self.tau_0 = tau_0 # TBD
        if T_0 is not None:
            self.T_0   = T_0 # TBD
        if beta is not None:
            self.beta = beta
        if gamma is not None:
            self.gamma = gamma
        return

    def set_origin(self, orig_pos):
        '''
        Set a offset value (move the origin point to the given [x0, y0, z0])
        add units!
        '''
        self.x0, self.y0, self.z0 =orig_pos
        return

    def auxilinary(self, box_size, box_res, N_particles = None):
        # settings of the simulation
        self.box_size = box_size # unit: Mpc
        self.box_res = box_res # unit: none
        self.res = box_size/box_res # unit: Mpc
        if N_particles is None:
            self.n_den = self.header['N'] / self.box_size**3
        else:
            self.n_den = N_particles / self.box_size**3
        #Do general cosmo things
        self.cosmo = FlatLambdaCDM(H0=100, Om0=0.315)
        self.mass_res = self.cosmo.critical_density0.to(u.M_sun/u.Mpc**3)*(self.box_size)**3/self.box_res**3*self.cosmo.Om(0.)

        #get speed of light in km/s
        self.ckms = 299792
        self.velkms = (self.box_size/8677.2079486362706)*self.ckms

    def read_from_npy(self, fn, costco_style = True):
        '''
        use this function to read reduced data, and recover the data to tipsy style.
        '''
        dark = np.load(fn)
        self.auxilinary(box_size = 512*u.Mpc, box_res = 256, N_particles = len(dark))

        dark = pd.DataFrame(dark,columns=dark.dtype.names)

        # basically what we do in the rev function
        dark['x'] = dark['x'] / self.box_size - 0.5
        dark['y'] = dark['y'] / self.box_size - 0.5
        dark['z'] = dark['z'] / self.box_size - 0.5
        dark['x'].units = None
        dark['y'].units = None
        dark['z'].units = None

        dark['vx'] = dark['vx'] / self.velkms
        dark['vy'] = dark['vy'] / self.velkms
        dark['vz'] = dark['vz'] / self.velkms
        dark['vx'].units = None
        dark['vy'].units = None
        dark['vz'].units = None

        if costco_style:
            dark['x'], dark['y'], dark['z'] = dark['y'], dark['x'], dark['z'] # ?
            dark['vx'], dark['vy'], dark['vz'] = dark['vy'], dark['vx'], dark['vz'] # dont forget the vel data!

        return dark

    def tipsy_read(self, fn, costco_style = True):
        tipsy = open(fn, 'rb')
        header_type = np.dtype([('time', '>f8'),('N', '>i4'), ('Dims', '>i4'), ('Ngas', '>i4'), ('Ndark', '>i4'), ('Nstar', '>i4'), ('pad', '>i4')])
        gas_type  = np.dtype([('mass','>f4'), ('x', '>f4'),('y', '>f4'),('z', '>f4'), ('vx', '>f4'),('vy', '>f4'),('vz', '>f4'),
                            ('rho','>f4'), ('temp','>f4'), ('hsmooth','>f4'), ('metals','>f4'), ('phi','>f4')])
        dark_type = np.dtype([('mass','>f4'), ('x', '>f4'),('y', '>f4'),('z', '>f4'), ('vx', '>f4'),('vy', '>f4'),('vz', '>f4'),
                            ('eps','>f4'), ('phi','>f4')])
        star_type  = np.dtype([('mass','>f4'), ('x', '>f4'),('y', '>f4'),('z', '>f4'), ('vx', '>f4'),('vy', '>f4'),('vz', '>f4'),
                            ('metals','>f4'), ('tform','>f4'), ('eps','>f4'), ('phi','>f4')])

        header = np.fromfile(tipsy,dtype=header_type,count=1)
        header = dict(zip(header_type.names,header[0]))

        gas  = np.fromfile(tipsy,dtype=gas_type,count=header['Ngas'])
        dark = np.fromfile(tipsy,dtype=dark_type,count=header['Ndark'])
        star = np.fromfile(tipsy,dtype=star_type,count=header['Nstar'])

        if byteorder == 'little':
            gas  =   gas.byteswap().newbyteorder('=')
            dark =   dark.byteswap().newbyteorder('=')
            star =   star.byteswap().newbyteorder('=')

        gas  = pd.DataFrame(gas,columns=gas.dtype.names)
        dark = pd.DataFrame(dark,columns=dark.dtype.names) # here is the raw data
        # in raw_data:
        # x - RA
        # y - DEC
        # z - red

        # what we want:
        # x - red
        # y - RA
        # z - DEC
        if costco_style:
            dark['x'], dark['y'], dark['z'] = dark['y'], dark['x'], dark['z'] # ?
            dark['vx'], dark['vy'], dark['vz'] = dark['vy'], dark['vx'], dark['vz'] # dont forget the vel data!
        star = pd.DataFrame(star,columns=star.dtype.names)
        tipsy.close()
        return header, gas, dark, star

    def process_dark(self, dark = None):
        # for painting, keep the particles in [0, 512]^3 box
        # this function write in-situ results, so be careful
        # only use if you want to ensure the particles are in reasonable positions
        if dark is None:
            dark = copy.deepcopy(self.dark)

        dark['x'] = (dark['x']+0.5) * self.box_size + self.x0
        dark['y'] = (dark['y']+0.5) * self.box_size + self.y0
        dark['z'] = (dark['z']+0.5) * self.box_size + self.z0

        dark['x'].units = u.Mpc
        dark['y'].units = u.Mpc
        dark['z'].units = u.Mpc

        dark['vx'] = dark['vx'] * self.velkms
        dark['vy'] = dark['vy'] * self.velkms
        dark['vz'] = dark['vz'] * self.velkms

        dark['vx'].units = u.km * u.s**-1
        dark['vy'].units = u.km * u.s**-1
        dark['vz'].units = u.km * u.s**-1

        dark['mass'] = self.mass_res.value
        dark['mass'].units= M_sun

        return dark

    def process_dark_rev(self, dark_processed):
        '''
        recover the input field (to raw format)
        '''

        dark_processed['x'] = (dark_processed['x']-self.x0) / self.box_size - 0.5
        dark_processed['y'] = (dark_processed['y']-self.y0) / self.box_size - 0.5
        dark_processed['z'] = (dark_processed['z']-self.z0) / self.box_size - 0.5
        dark_processed['x'].units = None
        dark_processed['y'].units = None
        dark_processed['z'].units = None

        dark_processed['vx'] = dark_processed['vx'] / self.velkms
        dark_processed['vy'] = dark_processed['vy'] / self.velkms
        dark_processed['vz'] = dark_processed['vz'] / self.velkms
        dark_processed['vx'].units = None
        dark_processed['vy'].units = None
        dark_processed['vz'].units = None
        return dark_processed

    def particle_paint(self, nc, weight_col = None):
        '''
        nc: # of cells along any direction
        raw_part_data: *raw* particle data from the simuation (x, y, z, \\in [-0.5, 0.5])
        weight_col: pick one col in raw_data as weight; default value is 1 for all the particles
        '''

        mesh = tf.zeros([1, nc, nc, nc], dtype = float)
        dark_raw = self.dark

        dark_pos = tf.convert_to_tensor([dark_raw['x'], dark_raw['y'], dark_raw['z']], dtype = float)
        dark_pos = tf.transpose((dark_pos + 0.5) * nc)
        dark_pos = tf.expand_dims(dark_pos, axis = 0) # [1, partN, 3]

        partN = dark_pos.shape[1]
        n_den = partN / nc**3

        if weight_col is None:
            weight = tf.ones([1, partN])
        else:
            weight = tf.convert_to_tensor(dark_raw[weight_col])
            weight = tf.expand_dims(weight, axis = 0)

        return ut.cic_paint(mesh, dark_pos, weight = weight) / n_den

    def particle_paint_clip_with_real_coord(self, real_coord_start, real_coord_end, dl, dark_raw = None, weight_col = None, smooth  = False):
        '''
        translate real space box to box in [-0.5, 0.5]^3 then run particle_paint_clip
        plz add units to all the parameters

        Issue: get things wrong here
        '''
        if dark_raw is None:
            dark_raw = self.dark

        rcs_x, rcs_y, rcs_z = real_coord_start
        rce_x, rce_y, rce_z = real_coord_end

        box_scale = round((self.box_size/dl).value)

        nc = np.round([((rce_x-rcs_x)/dl).value,
                       ((rce_y-rcs_y)/dl).value,
                       ((rce_z-rcs_z)/dl).value]).astype(int)
        offset = np.round([((rcs_x-self.x0)/dl).value,
                           ((rcs_y-self.y0)/dl).value,
                           ((rcs_z-self.z0)/dl).value]).astype(int)
        n_den = self.n_den * dl**3 #  global density per grid
        field_data = self.particle_paint_clip(nc, offset, box_scale, n_den, dark_raw = dark_raw, weight_col = weight_col)[0] # [nx, ny, nz] tensor
        field = Field(rcs_x, rcs_y, rcs_z, dl, field_data)
        if smooth:
            field.smooth(dl)
        return field

    def particle_paint_clip(self, nc, offset, box_scale, n_den, dark_raw = None, weight_col = None):
        '''
        nc: [nx, ny, nz]
            the shape/physical-scale of mesh.
        offset: [ox, oy, oz]
            [0,0,0] position of the mesh; default value  ox=0, oy=0, oz=0
        box_scale: the full scale of the simulation - box coord: [0, box_scale]^3
        # raw_part_data: *raw* particle data from the simuation (x, y, z, \\in [-0.5, 0.5])
        weight_col: pick one col in raw_data as weight; default value is 1 for all the particles

        this function cutouts a box [ox, ox+nx] * [oy, oy+ny] * [oz, oz+nz] with field values.
        auto periodical condition(?)
        '''
        if dark_raw is None:
            dark_raw = self.dark

        nx, ny, nz = nc
        ox, oy, oz = offset

        mesh = tf.zeros([1, nx, ny, nz], dtype = float)

        # remove particles out of the boundary
        dark_clip = dark_raw[(dark_raw['x']<=(ox+nx)/box_scale-0.5) & (dark_raw['x']>= ox/box_scale-0.5) &
                             (dark_raw['y']<=(oy+ny)/box_scale-0.5) & (dark_raw['y']>= oy/box_scale-0.5) &
                             (dark_raw['z']<=(oz+nz)/box_scale-0.5) & (dark_raw['z']>= oz/box_scale-0.5)]

        dark_pos = tf.convert_to_tensor([(dark_clip['x']+ 0.5)*box_scale - ox,
                                         (dark_clip['y']+ 0.5)*box_scale - oy,
                                         (dark_clip['z']+ 0.5)*box_scale - oz], dtype = float)

        assert (np.max(dark_pos[0]) <= nx) & (np.max(dark_pos[1]) <= ny) & (np.max(dark_pos[2]) <= nz), print(np.max(dark_pos[0]), np.max(dark_pos[1]), np.max(dark_pos[2]))
        assert (np.min(dark_pos[0]) >= 0 ) & (np.min(dark_pos[1]) >= 0 ) & (np.min(dark_pos[2]) >= 0 )
        dark_pos = tf.transpose(dark_pos)
        dark_pos = tf.expand_dims(dark_pos, axis = 0) # [1, partN, 3]

        partN = dark_pos.shape[1]

        if weight_col is None:
            weight = tf.ones([1, partN])
        else:
            weight = tf.convert_to_tensor(dark_clip[weight_col])
            weight = tf.expand_dims(weight, axis = 0)

        paint = ut.cic_paint(mesh, dark_pos, weight = weight) / n_den

        return paint

    def RSD_catalog(self, real_coord_start, real_coord_end, dl):
        '''
        return a particle catalog with RSDed pos
        '''
        opd_clip = self.particle_paint_clip_with_real_coord(real_coord_start, real_coord_end, dl)
        fvx_clip = self.particle_paint_clip_with_real_coord(real_coord_start, real_coord_end, dl, weight_col = 'vx')
        fvy_clip = self.particle_paint_clip_with_real_coord(real_coord_start, real_coord_end, dl, weight_col = 'vy')
        fvz_clip = self.particle_paint_clip_with_real_coord(real_coord_start, real_coord_end, dl, weight_col = 'vz')

        part_new_pos  = self.field_to_part_pos(opd_clip)

        # generate a new particle catalog
        part_new = pd.DataFrame(part_new_pos[0], columns = ['x', 'y', 'z'])

        opd_tensor = tf.expand_dims(opd_clip.field_data, axis = 0)
        fvx_tensor = tf.expand_dims(fvx_clip.field_data, axis = 0)
        fvy_tensor = tf.expand_dims(fvy_clip.field_data, axis = 0)
        fvz_tensor = tf.expand_dims(fvz_clip.field_data, axis = 0)

        # flowpm.cic_readout requires a compatible mesh and coord ([nx, ny, nz] grid - [0, n*]^3 coord)
        part_pos_grid = self.mesh_to_part_pos(tf.expand_dims(opd_clip.field_data, axis = 0))
        part_new['opd'] = ut.cic_readout(opd_tensor, part_pos_grid)[0]
        part_new['vx']  = ut.cic_readout(fvx_tensor, part_pos_grid)[0]
        part_new['vy']  = ut.cic_readout(fvy_tensor, part_pos_grid)[0]
        part_new['vz']  = ut.cic_readout(fvz_tensor, part_pos_grid)[0]

        # convert to real space
        part_new = self.process_dark(part_new)

        # RSD
        # TODO: consider the effect of yz distance
        part_new['red_real'] = self.z_from_dist(part_new['x'] * u.Mpc)
        part_new['red_rs'] = part_new['red_real'] + part_new['vx'] / self.ckms
        part_new['x_red'] = self.z_to_dist(part_new['red_rs'])
        return part_new

    def FGPA_eval(self, mesh_catalog):
        # calculate tau and T for each particle
        # TODO: find out characterized tau_0 & T_0
        mesh_catalog['tau'] = self.tau_0 * mesh_catalog['opd']**self.beta

        mesh_catalog['T']   = self.T_0 * mesh_catalog['opd']**self.gamma
        return mesh_catalog

    def raw_tau_map(self, real_coord_start, real_coord_end, dl):

        # generate the particle catalog
        part_new = self.RSD_catalog(real_coord_start, real_coord_end, dl)
        # add tau / T to the catalog
        part_new = self.FGPA_eval(part_new)
        # this one in the RS space
        part_new_new = pd.DataFrame(part_new[['y', 'z', 'vx', 'vy', 'vz', 'tau', 'T']], columns = ['y', 'z',  'vx', 'vy', 'vz', 'tau', 'T'])
        part_new_new['x'] = part_new['x_red'] # not sure why this doesn't work
        # recover the raw_field
        part_new_new = self.process_dark_rev(part_new_new)
        # paint the final result
        tau_field = self.particle_paint_clip_with_real_coord(real_coord_start, real_coord_end, dl,
                                                        dark_raw = part_new_new, weight_col = 'tau', smooth = False)
        return tau_field

    def tau_map(self, real_coord_start, real_coord_end, dl, z_comp = 2.30, F_obs = 0.8447):
        # derive the A_norm by comparing the desired value in obs with calculation
        self.set_FGPA_param(tau_0=1)
        raw_tau_field = self.raw_tau_map(real_coord_start, real_coord_end, dl)
        # construct the clip coord
        # hardcode bad, but works here
        clip_start = copy.deepcopy(real_coord_start)
        clip_start[0] = self.cosmo.comoving_distance(z_comp - 0.05)
        clip_end = copy.deepcopy(real_coord_end)
        clip_end[0] = self.cosmo.comoving_distance(z_comp + 0.05)

        test_tau_field = raw_tau_field.clip_with_coord(clip_start, clip_end)

        # no newton, just interp
        tau_list = test_tau_field.field_data
        tau_list = tau_list[~np.isnan(tau_list)]
        l = []
        for A in np.arange(0, 0.5, 0.001):
            l.append(np.mean(np.exp(-tau_list * A)))
        A_func = interp1d(l, np.arange(0, 0.5, 0.001))
        A_norm = A_func(F_obs)

        tau_field = copy.deepcopy(raw_tau_field)
        tau_field.field_data = tau_field.field_data * A_norm
        return tau_field

    def trans_map(self, real_coord_start, real_coord_end, dl):
        tau_field = self.tau_map(real_coord_start, real_coord_end, dl)
        trans_field = copy.deepcopy(tau_field)
        trans_field.field_data = np.exp(-trans_field.field_data)
        trans_field.field_data = trans_field.field_data / np.mean(trans_field.field_data)
        return trans_field

    def field_to_part_pos(self, field, tensor = True):
        '''

        '''
        nx, ny, nz = field.field_data.shape
        part_mesh = np.meshgrid(np.arange(nx), np.arange(ny), np.arange(nz))
        part_mesh = np.reshape(part_mesh, [3, nx*ny*nz]).T.astype(float)
        part_mesh[:, 0] = (part_mesh[:, 0]*field.dl + field.x0 - self.x0) / self.box_size - 0.5
        part_mesh[:, 1] = (part_mesh[:, 1]*field.dl + field.y0 - self.y0) / self.box_size - 0.5
        part_mesh[:, 2] = (part_mesh[:, 2]*field.dl + field.z0 - self.z0) / self.box_size - 0.5

        if tensor:
            part_mesh = tf.convert_to_tensor(part_mesh, dtype = float)
            part_mesh = tf.expand_dims(part_mesh, 0)
        return part_mesh

    def mesh_to_part_pos(self, mesh):
        '''
        Note this function is not complete: it converts the mesh into position [0, 0, 0] ... [nx, ny, nz] regardless the position
        Obselated
        '''
        _, nx, ny, nz = mesh.shape
        part_mesh = np.meshgrid(np.arange(nx), np.arange(ny), np.arange(nz))
        part_mesh = np.reshape(part_mesh, [3, nx*ny*nz]).T.astype(float)

        part_mesh = tf.convert_to_tensor(part_mesh, dtype = float)
        part_mesh = tf.expand_dims(part_mesh, 0)
        return part_mesh

    def z_from_dist(self, distance):
        dummyred = np.linspace(0.,10.,10000)
        dummydist = self.cosmo.comoving_distance(dummyred)
        res = np.interp(distance,dummydist,dummyred)
        return (res)

    def z_to_dist(self, red):
        return self.cosmo.comoving_distance(red).value


from functools import partial
from pathlib import Path
from typing import Dict, Any, Callable, Tuple, Optional, Sequence

import PIL
import imageio
import numpy as np
import torch
from PIL import Image
from torch import Tensor
from torch.nn import Module, Tanh, Parameter
from torch.nn.functional import grid_sample, l1_loss, mse_loss
from torch.utils.tensorboard import SummaryWriter

from thre3d_atom.networks.dense_nets import SkipMLP, SkipMLPConfig
from thre3d_atom.networks.network_interface import Network
from thre3d_atom.networks.shared.layers import (
    PositionalEncodingsEmbedder,
    PixelwiseNorm,
)
from thre3d_atom.utils.constants import NUM_COLOUR_CHANNELS
from thre3d_atom.utils.imaging_utils import (
    adjust_dynamic_range,
    to8b,
    mse2psnr,
    get_2d_coordinates,
)
from thre3d_atom.utils.logging import log

class FeatureGrid2D(Module):
    def __init__(
        self,
        height: int,
        width: int,
        feature_dims: int,
        tunable: bool = True,
        device: torch.device = torch.device(
            "cuda" if torch.cuda.is_available() else "cpu"
        ),
    ) -> None:
        super().__init__()

        # state of the object:
        self._height = height
        self._width = width
        self._feature_dims = feature_dims
        self._tunable = tunable

        self.features = torch.empty(
            (1, feature_dims, height, width), device=device, requires_grad=True
        )
        torch.nn.init.xavier_uniform_(self.features)

        if self._tunable:
            self.features = Parameter(self.features)

    @classmethod
    def from_feature_tensor(cls, feature_tensor: Tensor) -> Any:
        _, feature_dims, height, width = feature_tensor.shape
        # initialize a random feature_grid
        feature_grid = cls(
            height=height,
            width=width,
            feature_dims=feature_dims,
            tunable=False,
            device=feature_tensor.device,
        )

        # use the given feature_tensor as it's features:
        feature_grid.features = feature_tensor

        return feature_grid

    def extra_repr(self) -> str:
        return (
            f"grid_dims: {self.features.shape[2:]}, "
            f"feature_dims: {self.features.shape[1]}, "
            f"tunable: {self._tunable}"
        )

    def get_save_info(self) -> Dict[str, Any]:
        return {
            "conf": {
                "height": self._height,
                "width": self._width,
                "feature_dims": self._feature_dims,
                "tunable": self._tunable,
            },
            "state_dict": self.state_dict(),
        }

    def forward(self, coords: Tensor) -> Tensor:
        """coords should be of shape => [N x 2], and be in the range [-1, 1]"""
        sam_vals = grid_sample(
            # note the convention difference between the image and sample coordinates
            self.features.permute(0, 1, 3, 2),
            coords[None, None, ...],
            mode="bilinear",
            align_corners=False,
        )
        return sam_vals.permute(0, 2, 3, 1)[0, 0, ...]

class ImageDecoderMLP(Network):
    # noinspection PyUnresolvedReferences
    def __init__(
        self,
        mlp: SkipMLP,
        feature_dims: int = 32,
        feature_embedding_dims: int = 0,
        use_local_coords: bool = False,
        local_coords_embedding_dims: int = 0,
        normalize_features: bool = False,
    ) -> None:
        super().__init__()
        self._mlp = mlp
        self._feature_dims = feature_dims
        self._feature_embedding_dims = feature_embedding_dims
        self._use_local_coords = use_local_coords
        self._local_coords_embedding_dims = local_coords_embedding_dims
        self._normalize_features = normalize_features

        # objects of modification:
        self._normalizer = PixelwiseNorm()
        self._feature_embedder = PositionalEncodingsEmbedder(
            input_dims=self._feature_dims, emb_dims=self._feature_embedding_dims
        )
        self._local_coords_embedder = PositionalEncodingsEmbedder(
            input_dims=2, emb_dims=self._local_coords_embedding_dims
        )

    @property
    def input_shape(self) -> Sequence[Tuple[int, ...]]:
        return self._mlp.input_shape

    @property
    def output_shape(self) -> Sequence[Tuple[int, ...]]:
        return self._mlp.output_shape

    @property
    def feature_dims(self) -> int:
        return self._feature_dims

    @property
    def use_local_coords(self) -> bool:
        return self._use_local_coords

    def get_save_info(self) -> Dict[str, Any]:
        return {
            "conf": {
                "feature_dims": self._feature_dims,
                "feature_embedding_dims": self._feature_embedding_dims,
                "use_local_coords": self._use_local_coords,
                "local_coords_embedding_dims": self._local_coords_embedding_dims,
                "normalize_features": self._normalize_features,
            },
            "mlp": self._mlp.get_save_info(),
            "state_dict": self.state_dict(),
        }

    def load_weights(self, weights: Dict[str, Any]) -> None:
        self._mlp.load_state_dict(weights["mlp"]["state_dict"])

    def forward(self, x: Tensor) -> Tensor:
        if self._use_local_coords:
            features, local_coords = (
                x[..., : self._feature_dims],
                x[..., self._feature_dims :],
            )
        else:
            features, local_coords = x, torch.zeros(size=(x.shape[0], 0))

        embedded_features = self._feature_embedder(features)
        embedded_local_coords = self._local_coords_embedder(local_coords)
        normalized_features = self._normalizer(features)

        if self._use_local_coords:
            feats = (
                normalized_features if self._normalize_features else embedded_features
            )
            mlp_input = torch.cat([feats, embedded_local_coords], dim=-1)
        else:
            mlp_input = (
                normalized_features if self._normalize_features else embedded_features
            )
        return self._mlp(mlp_input)

def get_default_image_decoder_mlp(
    feature_dims: int = 32,
    feature_embedding_dims: int = 0,
    use_local_coords: bool = False,
    local_coords_embedding_dims: int = 0,
    normalize_features: bool = False,
) -> ImageDecoderMLP:
    feat_inp_dims = feature_dims + (2 * feature_dims * feature_embedding_dims)
    lc_inp_dims = 2 + (2 * 2 * local_coords_embedding_dims)
    if use_local_coords:
        mlp_input_dims = feat_inp_dims + lc_inp_dims
    elif normalize_features:
        mlp_input_dims = feature_dims
    else:
        mlp_input_dims = feat_inp_dims

    mlp_config = SkipMLPConfig(
        input_dims=mlp_input_dims,
        layer_depths=[256],
        output_dims=NUM_COLOUR_CHANNELS,
        skips=[False],
        use_equalized_learning_rate=True,
        out_activation_fn=Tanh(),
    )
    return ImageDecoderMLP(
        SkipMLP(mlp_config),
        feature_dims=feature_dims,
        feature_embedding_dims=feature_embedding_dims,
        use_local_coords=use_local_coords,
        local_coords_embedding_dims=local_coords_embedding_dims,
        normalize_features=normalize_features,
    )

def decode_coords_with_fg_and_mlp(
    coords: Tensor,
    feature_grid: FeatureGrid2D,
    decoder_mlp: ImageDecoderMLP,
    image_resolution: Tuple[int, int],
) -> Tensor:
    """decodes the coords tensor into RGB pixel values"""
    orig_shape = coords.shape
    coords = coords.reshape(-1, orig_shape[-1])
    image_height, image_width = image_resolution

    local_coords = adjust_dynamic_range(coords, drange_in=(-1, 1), drange_out=(0, 1))
    local_coords[..., 0] *= image_height
    local_coords[..., 1] *= image_width
    local_coords = local_coords - torch.floor(local_coords)

    decoded_features = feature_grid(coords)
    decoder_input = (
        torch.cat([decoded_features, local_coords], dim=-1)
        if decoder_mlp.use_local_coords
        else decoded_features
    )
    return decoder_mlp(decoder_input).reshape(*orig_shape[:-1], -1)

class ImageModel:
    def __init__(
        self,
        image_height: int,
        image_width: int,
        feature_dims: int = 32,
        decoder_mlp_maker: Callable[[], Network] = get_default_image_decoder_mlp,
        device: torch.device = torch.device(
            "cuda" if torch.cuda.is_available() else "cpu"
        ),
        verbose_creation: bool = True,
    ) -> None:
        self._image_height = image_height
        self._image_width = image_width
        self._feature_dims = feature_dims
        self._device = device

        # compute the height and width of the feature-grid so as to keep the number of
        # parameters in the image and the parametric-model same:
        self._setup_feature_dims()

        # create a feature grid object (note that these are kept public):
        self.feature_grid = FeatureGrid2D(
            self._feature_height, self._feature_width, feature_dims, device=device
        )
        self.decoder_mlp = decoder_mlp_maker().to(self._device)

        # print info related to the Feature Grid and the Decoder MLP:
        if verbose_creation:
            log.info(f"Created Feature grid: {self.feature_grid}")
            log.info(f"Created Decoder MLP: {self.decoder_mlp}")

    @property
    def image_resolution(self) -> Tuple[int, int]:
        return self._image_height, self._image_width

    @staticmethod
    def compute_feature_grid_dims(
        image_resolution: Tuple[int, int], feature_dims: int
    ) -> Tuple[int, int]:
        image_height, image_width = image_resolution
        aspect_ratio = image_width / image_height
        total_image_params = image_width * image_height * NUM_COLOUR_CHANNELS
        needed_params = total_image_params / feature_dims
        feature_grid_height = int(np.ceil(np.sqrt(needed_params / aspect_ratio)))
        feature_grid_width = int(aspect_ratio * feature_grid_height)
        return feature_grid_height, feature_grid_width

    def _setup_feature_dims(self) -> None:
        self._feature_height, self._feature_width = self.compute_feature_grid_dims(
            image_resolution=(self._image_height, self._image_width),
            feature_dims=self._feature_dims,
        )

    @staticmethod
    def _shuffle_tensor_2d(tensor_2d: Tensor) -> Tensor:
        """ shuffles a 2D Tensor of shape [N x C]"""
        return tensor_2d[torch.randperm(len(tensor_2d))]

    def _infinite_data_loader(self, data: Tensor, batch_size: int) -> Tensor:
        while True:
            data = self._shuffle_tensor_2d(data)
            for batch_index in range(0, len(data), batch_size):
                data_batch = data[batch_index : batch_index + batch_size]
                if data_batch.shape[0] == batch_size:
                    yield data_batch
                else:
                    break

    @staticmethod
    def _check_log_condition(
        current_step: int, frequency_step: int, start_step: int, end_step: int
    ) -> bool:
        return (
            current_step % frequency_step == 0
            or current_step == start_step
            or current_step == end_step
        )

    def get_save_info(self) -> Dict[str, Any]:
        return {
            "conf": {
                "image_height": self._image_height,
                "image_width": self._image_width,
                "feature_dims": self._feature_dims,
            },
            "feature_grid": self.feature_grid.get_save_info(),
            "decoder_mlp": self.decoder_mlp.get_save_info(),
        }

    def render(
        self,
        render_resolution: Optional[Tuple[int, int]] = None,
        chunk_size: int = 64 * 1024,
    ) -> Tensor:
        height, width = (
            (self._image_height, self._image_width)
            if render_resolution is None
            else render_resolution
        )

        # create a coordinates mesh-grid:
        coords = get_2d_coordinates(height, width)

        # flatten the coordinates and bring them on the GPU:
        flat_coords = coords.reshape(-1, coords.shape[-1]).to(self._device)

        # decode all the coordinates into pixel values chunk by chunk:
        decoded_image = []
        with torch.no_grad():
            for chunk_index in range(0, len(flat_coords), chunk_size):
                coord_chunk = flat_coords[chunk_index : chunk_index + chunk_size]
                decoded_image.append(
                    decode_coords_with_fg_and_mlp(
                        coord_chunk,
                        self.feature_grid,
                        self.decoder_mlp,
                        self.image_resolution,
                    )
                )
        decoded_image = torch.cat(decoded_image, dim=0)
        decoded_image = decoded_image.reshape(height, width, -1)
        decoded_image = adjust_dynamic_range(
            decoded_image.cpu(),
            drange_in=(-1, 1),
            drange_out=(0, 1),
            slack=True,
        )
        return decoded_image

    def train(
        self,
        training_image: PIL.Image.Image,
        num_iterations: int = 10000,
        batch_size: int = 8192,
        learning_rate: float = 0.003,
        lr_decay_steps: int = 5000,
        feedback_frequency: int = 1000,
        loss_feedback_frequency: int = 10,
        testing_frequency: int = 1000,
        save_frequency: int = 2000,
        output_dir: Path = Path(__file__).parent.absolute() / "logs",
    ) -> None:
        # load the training image and create a dataset of pixel_coordinates -> pixel RGB values:
        image_np = np.array(training_image).astype(np.float32) / 255
        if len(image_np.shape) < 3:
            image_np = np.tile(image_np[..., None], (1, 1, 3))
        image_np = image_np[..., :3]  # in case of > 3 channel images
        real_feedback_image = image_np
        # bring the pixel range to (-1, 1) for training
        image_np = adjust_dynamic_range(image_np, drange_in=(0, 1), drange_out=(-1, 1))

        # make sure the training image is compatible with the ImageModel
        assert (
            self._image_height == image_np.shape[0]
            and self._image_width == image_np.shape[1]
        ), (
            f"The provided training image with size ({image_np.shape[:-1]}) is incompatible with the Image-Model's"
            f"image size ({self._image_height, self._image_width})"
        )

        image_coords = get_2d_coordinates(self._image_height, self._image_width)
        coord_rgb_image = torch.cat(
            [
                image_coords.to(self._device),
                torch.from_numpy(image_np).to(self._device),
            ],
            dim=-1,
        )
        training_data = coord_rgb_image.reshape(-1, coord_rgb_image.shape[-1])
        training_data_loader = iter(
            self._infinite_data_loader(training_data, batch_size=batch_size)
        )

        # setup optimizer:
        optimizer = torch.optim.Adam(
            params=[
                {"params": self.feature_grid.parameters(), "lr": learning_rate},
                {"params": self.decoder_mlp.parameters(), "lr": learning_rate},
            ],
            betas=(0, 0.99),
        )
        lr_scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.1)

        # setup output directories
        # fmt: off
        model_dir = output_dir / "saved_models"
        logs_dir = output_dir / "training_logs"
        tensorboard_dir = logs_dir / "tensorboard"
        render_dir = logs_dir / "rendered_output"
        for directory in (model_dir, logs_dir, tensorboard_dir,
                          render_dir):
            directory.mkdir(exist_ok=True, parents=True)
        # fmt: on

        # create the tensorboard directory:
        tensorboard_writer = SummaryWriter(tensorboard_dir)

        # log the real image for feedback:
        log.info(f"Logging real feedback image")
        imageio.imwrite(
            render_dir / f"1__real_log.png",
            to8b(real_feedback_image),
        )

        log.info(f"!! Beginning Training !!")
        for num_iter in range(1, num_iterations + 1):
            # load the next batch of data:
            data_batch = next(training_data_loader)
            coords, gt_rgb = (
                data_batch[..., :-NUM_COLOUR_CHANNELS],
                data_batch[..., -NUM_COLOUR_CHANNELS:],
            )

            # forward pass and compute the loss
            pred_rgb = decode_coords_with_fg_and_mlp(
                coords,
                self.feature_grid,
                self.decoder_mlp,
                self.image_resolution,
            )
            loss = l1_loss(pred_rgb, gt_rgb)

            # perform single step of optimization
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            # verbose logging per iteration:
            loss_value = loss.item()
            psnr_value = mse2psnr(mse_loss(pred_rgb, gt_rgb).item())

            # tensorboard summaries feedback (logged every iteration)
            for summary_name, summary_value in (
                ("loss", loss_value),
                ("psnr", psnr_value),
            ):
                if summary_value is not None:
                    tensorboard_writer.add_scalar(
                        summary_name, summary_value, global_step=num_iter
                    )

            # console loss feedback log
            if self._check_log_condition(
                num_iter, loss_feedback_frequency, 1, num_iterations
            ):
                loss_info_string = (
                    f"Global Iteration: {num_iter} "
                    f"Loss: {loss_value: .5f} "
                    f"PSNR: {psnr_value: .5f} "
                )
                log.info(loss_info_string)

            # step the learning rate schedulers
            if num_iter % lr_decay_steps == 0:
                lr_scheduler.step()
                new_lrs = [param_group["lr"] for param_group in optimizer.param_groups]
                log_string = f"Adjusted learning rate | learning rate: {new_lrs} "
                log.info(log_string)

            # save the rendered feedback
            if self._check_log_condition(
                num_iter, feedback_frequency, 1, num_iterations
            ):
                imageio.imwrite(
                    render_dir / f"render_log_{num_iter}.png",
                    to8b(self.render().numpy()),
                )

            # obtain and log test metrics
            if self._check_log_condition(
                num_iter, testing_frequency, 1, num_iterations
            ):
                log.info(f"Computing test score ...")
                test_psnr = mse2psnr(
                    mse_loss(
                        self.render(),
                        torch.from_numpy(real_feedback_image),
                    ).item()
                )
                log.info(f"Full image PSNR: {test_psnr: .5f}")
                tensorboard_writer.add_scalar(
                    "full_image_psnr", test_psnr, global_step=num_iter
                )

            # save the model
            if self._check_log_condition(num_iter, save_frequency, 1, num_iterations):
                torch.save(
                    self.get_save_info(),
                    model_dir / f"model_iter_{num_iter}.pth",
                )

        # save the final model
        torch.save(self.get_save_info(), model_dir / f"model_final.pth")
        log.info("!! Training complete !!")

def load_trained_image_model(
    model_path: Path, device: torch.device, verbose_creation: bool = True
) -> ImageModel:
    loaded_model = torch.load(model_path)
    if verbose_creation:
        log.info(f"loaded trained model from: {model_path}")
    img_mod = ImageModel(
        **loaded_model["conf"],
        device=device,
        verbose_creation=verbose_creation,
        decoder_mlp_maker=partial(
            get_default_image_decoder_mlp,
            **loaded_model["decoder_mlp"]["conf"],
        ),
    )
    img_mod.feature_grid.load_state_dict(loaded_model["feature_grid"]["state_dict"])
    img_mod.decoder_mlp.load_weights(loaded_model["decoder_mlp"])
    return img_mod


from flask import Flask
from flask_restful import Api, Resource

app = Flask(__name__)
api = Api(app)

class Hellocall(Resource):
    def get(self,name,number):
        return({'Name':name,'Age':number})

api.add_resource(Hellocall,"/Helloworld/<string:name>/<int:number>")

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


#!/usr/bin/env python3

import base64

from functions.aes import (
    gen_random_bytes,
    get_blocks,
    pkcs7_unpad,
    pkcs7_pad,
    PKCS7Error,
    AESCipher,
)

_STRINGS = [
    base64.b64decode(s)
    for s in [
        "MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=",
        "MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=",
        "MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==",
        "MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==",
        "MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl",
        "MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==",
        "MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==",
        "MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=",
        "MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=",
        "MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93",
    ]
]

_KEY = gen_random_bytes(16)

def _encrypt(pt: bytes) -> (bytes, bytes):
    iv = gen_random_bytes(16)
    cbc = AESCipher(AESCipher.MODE_CBC, _KEY, iv=iv)
    ct = cbc.encrypt(pkcs7_pad(pt))

    return iv, ct

def _oracle(iv: bytes, ct: bytes) -> bool:
    cbc = AESCipher(AESCipher.MODE_CBC, _KEY, iv=iv)

    try:
        pkcs7_unpad(cbc.decrypt(ct))
    except PKCS7Error:
        return False

    return True

def _attack(iv: bytes, ct: bytes) -> bytes:
    cipher_blocks = [iv] + get_blocks(ct)

    pt = b""

    for i in reversed(range(1, len(cipher_blocks))):
        ct_block_previous = cipher_blocks[i - 1]
        ct_block_current = cipher_blocks[i]
        intermediate_block = b""

        for j in reversed(range(16)):
            ctb_prefix = gen_random_bytes(j)
            ctb_suffix = b""

            for k in range(len(intermediate_block)):
                ctb_suffix += bytes([(16 - j) ^ intermediate_block[k]])

            n = 0
            for m in range(256):
                ctb = ctb_prefix + bytes([m]) + ctb_suffix

                if _oracle(ctb, ct_block_current):
                    n = m
                    break

            intermediate_block = bytes([n ^ (16 - j)]) + intermediate_block
            pt = bytes([ct_block_previous[j] ^ int(intermediate_block[0])]) + pt

    return pkcs7_unpad(pt)

def challenge17() -> bool:
    for msg in _STRINGS:
        ret = _attack(*_encrypt(msg))

        if ret not in _STRINGS:
            return False

    return True

if __name__ == "__main__":
    assert challenge17(), "The result does not match the expected value"

    print("Ok")


#!/usr/bin/env python3

import pandas as pd
import os

import rospy
import rospkg
from std_msgs.msg import Bool

from robo_demo_msgs.srv import RunPlanningTest

rospack = rospkg.RosPack()
EE_CONTROL_PATH = rospack.get_path('end_effector_control')
PLANNING_DATA_PATH = os.path.join(EE_CONTROL_PATH, 'data', 'planning')
COMMON_DATA_PATH = os.path.join(PLANNING_DATA_PATH, 'planning_data.csv')

DEFAULT_TEST_DICT = {'change_goal': 10, 'add_obstacle': 10, 'add_obstacle_change_goal': 10}

class TestAutomator():

    def __init__(self, test_dict=DEFAULT_TEST_DICT):
        self.test_dict = test_dict
        self.update_test_counts()
        self.planning_test_srv = rospy.ServiceProxy('/test_interface_service', RunPlanningTest)
        rospy.sleep(0.5)
        rospy.loginfo("TestAutomator initialized, running tests")
        self.run_tests()

    def update_test_counts(self):
        if os.path.exists(COMMON_DATA_PATH):
            df = pd.read_csv(COMMON_DATA_PATH)
            (t1, t2, t3) = ("change_goal", "add_obstacle", "add_obstacle_change_goal")
            t1_count = len(df[df["Scenario"]==t1])
            t2_count = len(df[df["Scenario"]==t2])
            t3_count = len(df[df["Scenario"]==t3])
            self.test_dict[t1] -= t1_count
            self.test_dict[t2] -= t2_count
            self.test_dict[t3] -= t3_count
            rospy.loginfo(f"counts: {t1_count}, {t2_count}, {t3_count}")

    def run_tests(self):
        for (test_type, iterations) in self.test_dict.items():
            for i in range(iterations):
                rospy.loginfo(f"Running {test_type}, iteration: {i+1}/{iterations}")
                response = self.planning_test_srv(test_type)
                rospy.loginfo(f"Received response: {response}")

if __name__ == "__main__":
    rospy.init_node("automate_testing_node")
    test_dict = {'add_obstacle': 2}
    ta = TestAutomator(test_dict)
    # ta = TestAutomator()


# Create class

from Tools.Scripts.treesync import raw_input

import datetime
from datetime import date

class Person:
    def __init__(self, name,year,month,day):
        self.__name=name
        self.__year=year
        self.__month=month
        self.__day=day

    def getage(self):
        now = datetime.datetime.now()
        c_year = now.hour
        c_month = now.month
        c_day = now.day

        current_date = date(c_year, c_month, c_day)
        print(current_date)
        dob = date(self.__year, self.__month, self.__day)
        age = current_date - dob
        print (age)

irene = Person("Irene",1988,8,19)
irene.getage()


#! /usr/bin/env python

import math
import rospy
from sensor_msgs.msg import Imu
from tf.transformations import euler_from_quaternion

def imuCallback(imu):
  quat = [imu.orientation.w, imu.orientation.x, imu.orientation.y, imu.orientation.z]
  roll, pitch, yaw = euler_from_quaternion(quat)
  rospy.loginfo('{} {} {}'.format(roll*180.0/math.pi, pitch*180.0/math.pi, yaw*180.0/math.pi))

def imuToYaw():

  rospy.init_node('imu_to_yaw')
  imu_sub = rospy.Subscriber('/android/imu', Imu, imuCallback)

  rospy.spin()

if __name__ == '__main__':
  imuToYaw()


__authors__ = ["T. Vincent"]
__license__ = "MIT"
__date__ = "03/04/2017"

# TODO
# keep aspect ratio managed here?
# smarter dirty flag handling?

import datetime as dt
import math
import weakref
import logging
import numbers
from typing import Optional, Union
from collections import namedtuple

import numpy

from .... import qt
from ...._glutils import gl, Program
from ..._utils import checkAxisLimits, FLOAT32_MINPOS
from .GLSupport import mat4Ortho
from .GLText import Text2D, CENTER, BOTTOM, TOP, LEFT, RIGHT, ROTATE_270
from ..._utils.ticklayout import niceNumbersAdaptative, niceNumbersForLog10
from ..._utils.dtime_ticklayout import calcTicksAdaptive, bestFormatString
from ..._utils.dtime_ticklayout import timestamp

_logger = logging.getLogger(__name__)

# PlotAxis ####################################################################

class PlotAxis(object):
    """Represents a 1D axis of the plot.
    This class is intended to be used with :class:`GLPlotFrame`.
    """

    def __init__(self, plotFrame,
                 tickLength=(0., 0.),
                 foregroundColor=(0., 0., 0., 1.0),
                 labelAlign=CENTER, labelVAlign=CENTER,
                 titleAlign=CENTER, titleVAlign=CENTER,
                 titleRotate=0, titleOffset=(0., 0.)):
        self._ticks = None

        self._plotFrameRef = weakref.ref(plotFrame)

        self._isDateTime = False
        self._timeZone = None
        self._isLog = False
        self._dataRange = 1., 100.
        self._displayCoords = (0., 0.), (1., 0.)
        self._title = ''

        self._tickLength = tickLength
        self._foregroundColor = foregroundColor
        self._labelAlign = labelAlign
        self._labelVAlign = labelVAlign
        self._titleAlign = titleAlign
        self._titleVAlign = titleVAlign
        self._titleRotate = titleRotate
        self._titleOffset = titleOffset

    @property
    def dataRange(self):
        """The range of the data represented on the axis as a tuple
        of 2 floats: (min, max)."""
        return self._dataRange

    @dataRange.setter
    def dataRange(self, dataRange):
        assert len(dataRange) == 2
        assert dataRange[0] <= dataRange[1]
        dataRange = float(dataRange[0]), float(dataRange[1])

        if dataRange != self._dataRange:
            self._dataRange = dataRange
            self._dirtyTicks()

    @property
    def isLog(self):
        """Whether the axis is using a log10 scale or not as a bool."""
        return self._isLog

    @isLog.setter
    def isLog(self, isLog):
        isLog = bool(isLog)
        if isLog != self._isLog:
            self._isLog = isLog
            self._dirtyTicks()

    @property
    def timeZone(self):
        """Returnss datetime.tzinfo that is used if this axis plots date times."""
        return self._timeZone

    @timeZone.setter
    def timeZone(self, tz):
        """Sets dateetime.tzinfo that is used if this axis plots date times."""
        self._timeZone = tz
        self._dirtyTicks()

    @property
    def isTimeSeries(self):
        """Whether the axis is showing floats as datetime objects"""
        return self._isDateTime

    @isTimeSeries.setter
    def isTimeSeries(self, isTimeSeries):
        isTimeSeries = bool(isTimeSeries)
        if isTimeSeries != self._isDateTime:
            self._isDateTime = isTimeSeries
            self._dirtyTicks()

    @property
    def displayCoords(self):
        """The coordinates of the start and end points of the axis
        in display space (i.e., in pixels) as a tuple of 2 tuples of
        2 floats: ((x0, y0), (x1, y1)).
        """
        return self._displayCoords

    @displayCoords.setter
    def displayCoords(self, displayCoords):
        assert len(displayCoords) == 2
        assert len(displayCoords[0]) == 2
        assert len(displayCoords[1]) == 2
        displayCoords = tuple(displayCoords[0]), tuple(displayCoords[1])
        if displayCoords != self._displayCoords:
            self._displayCoords = displayCoords
            self._dirtyTicks()

    @property
    def devicePixelRatio(self):
        """Returns the ratio between qt pixels and device pixels."""
        plotFrame = self._plotFrameRef()
        return plotFrame.devicePixelRatio if plotFrame is not None else 1.

    @property
    def title(self):
        """The text label associated with this axis as a str in latin-1."""
        return self._title

    @title.setter
    def title(self, title):
        if title != self._title:
            self._title = title
            self._dirtyPlotFrame()

    @property
    def titleOffset(self):
        """Title offset in pixels (x: int, y: int)"""
        return self._titleOffset

    @titleOffset.setter
    def titleOffset(self, offset):
        if offset != self._titleOffset:
            self._titleOffset = offset
            self._dirtyTicks()

    @property
    def foregroundColor(self):
        """Color used for frame and labels"""
        return self._foregroundColor

    @foregroundColor.setter
    def foregroundColor(self, color):
        """Color used for frame and labels"""
        assert len(color) == 4, \
            "foregroundColor must have length 4, got {}".format(len(self._foregroundColor))
        if self._foregroundColor != color:
            self._foregroundColor = color
            self._dirtyTicks()

    @property
    def ticks(self):
        """Ticks as tuples: ((x, y) in display, dataPos, textLabel)."""
        if self._ticks is None:
            self._ticks = tuple(self._ticksGenerator())
        return self._ticks

    def getVerticesAndLabels(self):
        """Create the list of vertices for axis and associated text labels.

        :returns: A tuple: List of 2D line vertices, List of Text2D labels.
        """
        vertices = list(self.displayCoords)  # Add start and end points
        labels = []
        tickLabelsSize = [0., 0.]

        font = qt.QApplication.instance().font()

        xTickLength, yTickLength = self._tickLength
        xTickLength *= self.devicePixelRatio
        yTickLength *= self.devicePixelRatio
        for (xPixel, yPixel), dataPos, text in self.ticks:
            if text is None:
                tickScale = 0.5
            else:
                tickScale = 1.

                label = Text2D(text=text,
                               font=font,
                               color=self._foregroundColor,
                               x=xPixel - xTickLength,
                               y=yPixel - yTickLength,
                               align=self._labelAlign,
                               valign=self._labelVAlign,
                               devicePixelRatio=self.devicePixelRatio)

                width, height = label.size
                if width > tickLabelsSize[0]:
                    tickLabelsSize[0] = width
                if height > tickLabelsSize[1]:
                    tickLabelsSize[1] = height

                labels.append(label)

            vertices.append((xPixel, yPixel))
            vertices.append((xPixel + tickScale * xTickLength,
                             yPixel + tickScale * yTickLength))

        (x0, y0), (x1, y1) = self.displayCoords
        xAxisCenter = 0.5 * (x0 + x1)
        yAxisCenter = 0.5 * (y0 + y1)

        xOffset, yOffset = self.titleOffset

        # Adaptative title positioning:
        # tickNorm = math.sqrt(xTickLength ** 2 + yTickLength ** 2)
        # xOffset = -tickLabelsSize[0] * xTickLength / tickNorm
        # xOffset -= 3 * xTickLength
        # yOffset = -tickLabelsSize[1] * yTickLength / tickNorm
        # yOffset -= 3 * yTickLength

        axisTitle = Text2D(text=self.title,
                           font=font,
                           color=self._foregroundColor,
                           x=xAxisCenter + xOffset,
                           y=yAxisCenter + yOffset,
                           align=self._titleAlign,
                           valign=self._titleVAlign,
                           rotate=self._titleRotate,
                           devicePixelRatio=self.devicePixelRatio)
        labels.append(axisTitle)

        return vertices, labels

    def _dirtyPlotFrame(self):
        """Dirty parent GLPlotFrame"""
        plotFrame = self._plotFrameRef()
        if plotFrame is not None:
            plotFrame._dirty()

    def _dirtyTicks(self):
        """Mark ticks as dirty and notify listener (i.e., background)."""
        self._ticks = None
        self._dirtyPlotFrame()

    @staticmethod
    def _frange(start, stop, step):
        """range for float (including stop)."""
        while start <= stop:
            yield start
            start += step

    def _ticksGenerator(self):
        """Generator of ticks as tuples:
        ((x, y) in display, dataPos, textLabel).
        """
        dataMin, dataMax = self.dataRange
        if self.isLog and dataMin <= 0.:
            _logger.warning(
                'Getting ticks while isLog=True and dataRange[0]<=0.')
            dataMin = 1.
            if dataMax < dataMin:
                dataMax = 1.

        if dataMin != dataMax:  # data range is not null
            (x0, y0), (x1, y1) = self.displayCoords

            if self.isLog:

                if self.isTimeSeries:
                    _logger.warning("Time series not implemented for log-scale")

                logMin, logMax = math.log10(dataMin), math.log10(dataMax)
                tickMin, tickMax, step, _ = niceNumbersForLog10(logMin, logMax)

                xScale = (x1 - x0) / (logMax - logMin)
                yScale = (y1 - y0) / (logMax - logMin)

                for logPos in self._frange(tickMin, tickMax, step):
                    if logMin <= logPos <= logMax:
                        dataPos = 10 ** logPos
                        xPixel = x0 + (logPos - logMin) * xScale
                        yPixel = y0 + (logPos - logMin) * yScale
                        text = '1e%+03d' % logPos
                        yield ((xPixel, yPixel), dataPos, text)

                if step == 1:
                    ticks = list(self._frange(tickMin, tickMax, step))[:-1]
                    for logPos in ticks:
                        dataOrigPos = 10 ** logPos
                        for index in range(2, 10):
                            dataPos = dataOrigPos * index
                            if dataMin <= dataPos <= dataMax:
                                logSubPos = math.log10(dataPos)
                                xPixel = x0 + (logSubPos - logMin) * xScale
                                yPixel = y0 + (logSubPos - logMin) * yScale
                                yield ((xPixel, yPixel), dataPos, None)

            else:
                xScale = (x1 - x0) / (dataMax - dataMin)
                yScale = (y1 - y0) / (dataMax - dataMin)

                nbPixels = math.sqrt(pow(x1 - x0, 2) + pow(y1 - y0, 2)) / self.devicePixelRatio

                # Density of 1.3 label per 92 pixels
                # i.e., 1.3 label per inch on a 92 dpi screen
                tickDensity = 1.3 / 92

                if not self.isTimeSeries:
                    tickMin, tickMax, step, nbFrac = niceNumbersAdaptative(
                        dataMin, dataMax, nbPixels, tickDensity)

                    for dataPos in self._frange(tickMin, tickMax, step):
                        if dataMin <= dataPos <= dataMax:
                            xPixel = x0 + (dataPos - dataMin) * xScale
                            yPixel = y0 + (dataPos - dataMin) * yScale

                            if nbFrac == 0:
                                text = '%g' % dataPos
                            else:
                                text = ('%.' + str(nbFrac) + 'f') % dataPos
                            yield ((xPixel, yPixel), dataPos, text)
                else:
                    # Time series
                    try:
                        dtMin = dt.datetime.fromtimestamp(dataMin, tz=self.timeZone)
                        dtMax = dt.datetime.fromtimestamp(dataMax, tz=self.timeZone)
                    except ValueError:
                        _logger.warning("Data range cannot be displayed with time axis")
                        return  # Range is out of bound of the datetime

                    tickDateTimes, spacing, unit = calcTicksAdaptive(
                        dtMin, dtMax, nbPixels, tickDensity)

                    for tickDateTime in tickDateTimes:
                        if dtMin <= tickDateTime <= dtMax:

                            dataPos = timestamp(tickDateTime)
                            xPixel = x0 + (dataPos - dataMin) * xScale
                            yPixel = y0 + (dataPos - dataMin) * yScale

                            fmtStr = bestFormatString(spacing, unit)
                            text = tickDateTime.strftime(fmtStr)

                            yield ((xPixel, yPixel), dataPos, text)

# GLPlotFrame #################################################################

class GLPlotFrame(object):
    """Base class for rendering a 2D frame surrounded by axes."""

    _TICK_LENGTH_IN_PIXELS = 5
    _LINE_WIDTH = 1

    _SHADERS = {
        'vertex': """
    attribute vec2 position;
    uniform mat4 matrix;

    void main(void) {
        gl_Position = matrix * vec4(position, 0.0, 1.0);
    }
    """,
        'fragment': """
    uniform vec4 color;
    uniform float tickFactor; /* = 1./tickLength or 0. for solid line */

    void main(void) {
        if (mod(tickFactor * (gl_FragCoord.x + gl_FragCoord.y), 2.) < 1.) {
            gl_FragColor = color;
        } else {
            discard;
        }
    }
    """
    }

    _Margins = namedtuple('Margins', ('left', 'right', 'top', 'bottom'))

    # Margins used when plot frame is not displayed
    _NoDisplayMargins = _Margins(0, 0, 0, 0)

    def __init__(self, marginRatios, foregroundColor, gridColor):
        """
        :param List[float] marginRatios:
            The ratios of margins around plot area for axis and labels.
            (left, top, right, bottom) as float in [0., 1.]
        :param foregroundColor: color used for the frame and labels.
        :type foregroundColor: tuple with RGBA values ranging from 0.0 to 1.0
        :param gridColor: color used for grid lines.
        :type gridColor: tuple RGBA with RGBA values ranging from 0.0 to 1.0
        """
        self._renderResources = None

        self.__marginRatios = marginRatios
        self.__marginsCache = None

        self._foregroundColor = foregroundColor
        self._gridColor = gridColor

        self.axes = []  # List of PlotAxis to be updated by subclasses

        self._grid = False
        self._size = 0., 0.
        self._title = ''

        self._devicePixelRatio = 1.

    @property
    def isDirty(self):
        """True if it need to refresh graphic rendering, False otherwise."""
        return self._renderResources is None

    GRID_NONE = 0
    GRID_MAIN_TICKS = 1
    GRID_SUB_TICKS = 2
    GRID_ALL_TICKS = (GRID_MAIN_TICKS + GRID_SUB_TICKS)

    @property
    def foregroundColor(self):
        """Color used for frame and labels"""
        return self._foregroundColor

    @foregroundColor.setter
    def foregroundColor(self, color):
        """Color used for frame and labels"""
        assert len(color) == 4, \
            "foregroundColor must have length 4, got {}".format(len(self._foregroundColor))
        if self._foregroundColor != color:
            self._foregroundColor = color
            for axis in self.axes:
                axis.foregroundColor = color
            self._dirty()

    @property
    def gridColor(self):
        """Color used for frame and labels"""
        return self._gridColor

    @gridColor.setter
    def gridColor(self, color):
        """Color used for frame and labels"""
        assert len(color) == 4, \
            "gridColor must have length 4, got {}".format(len(self._gridColor))
        if self._gridColor != color:
            self._gridColor = color
            self._dirty()

    @property
    def marginRatios(self):
        """Plot margin ratios: (left, top, right, bottom) as 4 float in [0, 1].
        """
        return self.__marginRatios

    @marginRatios.setter
    def marginRatios(self, ratios):
        ratios = tuple(float(v) for v in ratios)
        assert len(ratios) == 4
        for value in ratios:
            assert 0. <= value <= 1.
        assert ratios[0] + ratios[2] < 1.
        assert ratios[1] + ratios[3] < 1.

        if self.__marginRatios != ratios:
            self.__marginRatios = ratios
            self.__marginsCache = None  # Clear cached margins
            self._dirty()

    @property
    def margins(self):
        """Margins in pixels around the plot."""
        if self.__marginsCache is None:
            width, height = self.size
            left, top, right, bottom = self.marginRatios
            self.__marginsCache = self._Margins(
                left=int(left*width),
                right=int(right*width),
                top=int(top*height),
                bottom=int(bottom*height))
        return self.__marginsCache

    @property
    def devicePixelRatio(self):
        return self._devicePixelRatio

    @devicePixelRatio.setter
    def devicePixelRatio(self, ratio):
        if ratio != self._devicePixelRatio:
            self._devicePixelRatio = ratio
            self._dirty()

    @property
    def grid(self):
        """Grid display mode:
        - 0: No grid.
        - 1: Grid on main ticks.
        - 2: Grid on sub-ticks for log scale axes.
        - 3: Grid on main and sub ticks."""
        return self._grid

    @grid.setter
    def grid(self, grid):
        assert grid in (self.GRID_NONE, self.GRID_MAIN_TICKS,
                        self.GRID_SUB_TICKS, self.GRID_ALL_TICKS)
        if grid != self._grid:
            self._grid = grid
            self._dirty()

    @property
    def size(self):
        """Size in device pixels of the plot area including margins."""
        return self._size

    @size.setter
    def size(self, size):
        assert len(size) == 2
        size = tuple(size)
        if size != self._size:
            self._size = size
            self.__marginsCache = None  # Clear cached margins
            self._dirty()

    @property
    def plotOrigin(self):
        """Plot area origin (left, top) in widget coordinates in pixels."""
        return self.margins.left, self.margins.top

    @property
    def plotSize(self):
        """Plot area size (width, height) in pixels."""
        w, h = self.size
        w -= self.margins.left + self.margins.right
        h -= self.margins.top + self.margins.bottom
        return w, h

    @property
    def title(self):
        """Main title as a str in latin-1."""
        return self._title

    @title.setter
    def title(self, title):
        if title != self._title:
            self._title = title
            self._dirty()

        # In-place update
        # if self._renderResources is not None:
        #    self._renderResources[-1][-1].text = title

    def _dirty(self):
        # When Text2D require discard we need to handle it
        self._renderResources = None

    def _buildGridVertices(self):
        if self._grid == self.GRID_NONE:
            return []

        elif self._grid == self.GRID_MAIN_TICKS:
            def test(text):
                return text is not None
        elif self._grid == self.GRID_SUB_TICKS:
            def test(text):
                return text is None
        elif self._grid == self.GRID_ALL_TICKS:
            def test(_):
                return True
        else:
            logging.warning('Wrong grid mode: %d' % self._grid)
            return []

        return self._buildGridVerticesWithTest(test)

    def _buildGridVerticesWithTest(self, test):
        """Override in subclass to generate grid vertices"""
        return []

    def _buildVerticesAndLabels(self):
        # To fill with copy of axes lists
        vertices = []
        labels = []

        for axis in self.axes:
            axisVertices, axisLabels = axis.getVerticesAndLabels()
            vertices += axisVertices
            labels += axisLabels

        vertices = numpy.array(vertices, dtype=numpy.float32)

        # Add main title
        xTitle = (self.size[0] + self.margins.left -
                  self.margins.right) // 2
        yTitle = self.margins.top - self._TICK_LENGTH_IN_PIXELS
        labels.append(Text2D(text=self.title,
                             font=qt.QApplication.instance().font(),
                             color=self._foregroundColor,
                             x=xTitle,
                             y=yTitle,
                             align=CENTER,
                             valign=BOTTOM,
                             devicePixelRatio=self.devicePixelRatio))

        # grid
        gridVertices = numpy.array(self._buildGridVertices(),
                                   dtype=numpy.float32)

        self._renderResources = (vertices, gridVertices, labels)

    _program = Program(
        _SHADERS['vertex'], _SHADERS['fragment'], attrib0='position')

    def render(self):
        if self.margins == self._NoDisplayMargins:
            return

        if self._renderResources is None:
            self._buildVerticesAndLabels()
        vertices, gridVertices, labels = self._renderResources

        width, height = self.size
        matProj = mat4Ortho(0, width, height, 0, 1, -1)

        gl.glViewport(0, 0, width, height)

        prog = self._program
        prog.use()

        gl.glLineWidth(self._LINE_WIDTH)

        gl.glUniformMatrix4fv(prog.uniforms['matrix'], 1, gl.GL_TRUE,
                              matProj.astype(numpy.float32))
        gl.glUniform4f(prog.uniforms['color'], *self._foregroundColor)
        gl.glUniform1f(prog.uniforms['tickFactor'], 0.)

        gl.glEnableVertexAttribArray(prog.attributes['position'])
        gl.glVertexAttribPointer(prog.attributes['position'],
                                 2,
                                 gl.GL_FLOAT,
                                 gl.GL_FALSE,
                                 0, vertices)

        gl.glDrawArrays(gl.GL_LINES, 0, len(vertices))

        for label in labels:
            label.render(matProj)

    def renderGrid(self):
        if self._grid == self.GRID_NONE:
            return

        if self._renderResources is None:
            self._buildVerticesAndLabels()
        vertices, gridVertices, labels = self._renderResources

        width, height = self.size
        matProj = mat4Ortho(0, width, height, 0, 1, -1)

        gl.glViewport(0, 0, width, height)

        prog = self._program
        prog.use()

        gl.glLineWidth(self._LINE_WIDTH)
        gl.glUniformMatrix4fv(prog.uniforms['matrix'], 1, gl.GL_TRUE,
                              matProj.astype(numpy.float32))
        gl.glUniform4f(prog.uniforms['color'], *self._gridColor)
        gl.glUniform1f(prog.uniforms['tickFactor'], 0.)  # 1/2.)  # 1/tickLen

        gl.glEnableVertexAttribArray(prog.attributes['position'])
        gl.glVertexAttribPointer(prog.attributes['position'],
                                 2,
                                 gl.GL_FLOAT,
                                 gl.GL_FALSE,
                                 0, gridVertices)

        gl.glDrawArrays(gl.GL_LINES, 0, len(gridVertices))

# GLPlotFrame2D ###############################################################

class GLPlotFrame2D(GLPlotFrame):
    def __init__(self, marginRatios, foregroundColor, gridColor):
        """
        :param List[float] marginRatios:
            The ratios of margins around plot area for axis and labels.
            (left, top, right, bottom) as float in [0., 1.]
        :param foregroundColor: color used for the frame and labels.
        :type foregroundColor: tuple with RGBA values ranging from 0.0 to 1.0
        :param gridColor: color used for grid lines.
        :type gridColor: tuple RGBA with RGBA values ranging from 0.0 to 1.0

        """
        super(GLPlotFrame2D, self).__init__(marginRatios, foregroundColor, gridColor)
        self.axes.append(PlotAxis(self,
                                  tickLength=(0., -5.),
                                  foregroundColor=self._foregroundColor,
                                  labelAlign=CENTER, labelVAlign=TOP,
                                  titleAlign=CENTER, titleVAlign=TOP,
                                  titleRotate=0))

        self._x2AxisCoords = ()

        self.axes.append(PlotAxis(self,
                                  tickLength=(5., 0.),
                                  foregroundColor=self._foregroundColor,
                                  labelAlign=RIGHT, labelVAlign=CENTER,
                                  titleAlign=CENTER, titleVAlign=BOTTOM,
                                  titleRotate=ROTATE_270))

        self._y2Axis = PlotAxis(self,
                                tickLength=(-5., 0.),
                                foregroundColor=self._foregroundColor,
                                labelAlign=LEFT, labelVAlign=CENTER,
                                titleAlign=CENTER, titleVAlign=TOP,
                                titleRotate=ROTATE_270)

        self._isYAxisInverted = False

        self._dataRanges = {
            'x': (1., 100.), 'y': (1., 100.), 'y2': (1., 100.)}

        self._baseVectors = (1., 0.), (0., 1.)

        self._transformedDataRanges = None
        self._transformedDataProjMat = None
        self._transformedDataY2ProjMat = None

    def _dirty(self):
        super(GLPlotFrame2D, self)._dirty()
        self._transformedDataRanges = None
        self._transformedDataProjMat = None
        self._transformedDataY2ProjMat = None

    @property
    def isDirty(self):
        """True if it need to refresh graphic rendering, False otherwise."""
        return (super(GLPlotFrame2D, self).isDirty or
                self._transformedDataRanges is None or
                self._transformedDataProjMat is None or
                self._transformedDataY2ProjMat is None)

    @property
    def xAxis(self):
        return self.axes[0]

    @property
    def yAxis(self):
        return self.axes[1]

    @property
    def y2Axis(self):
        return self._y2Axis

    @property
    def isY2Axis(self):
        """Whether to display the left Y axis or not."""
        return len(self.axes) == 3

    @isY2Axis.setter
    def isY2Axis(self, isY2Axis):
        if isY2Axis != self.isY2Axis:
            if isY2Axis:
                self.axes.append(self._y2Axis)
            else:
                self.axes = self.axes[:2]

            self._dirty()

    @property
    def isYAxisInverted(self):
        """Whether Y axes are inverted or not as a bool."""
        return self._isYAxisInverted

    @isYAxisInverted.setter
    def isYAxisInverted(self, value):
        value = bool(value)
        if value != self._isYAxisInverted:
            self._isYAxisInverted = value
            self._dirty()

    DEFAULT_BASE_VECTORS = (1., 0.), (0., 1.)
    """Values of baseVectors for orthogonal axes."""

    @property
    def baseVectors(self):
        """Coordinates of the X and Y axes in the orthogonal plot coords.

        Raises ValueError if corresponding matrix is singular.

        2 tuples of 2 floats: (xx, xy), (yx, yy)
        """
        return self._baseVectors

    @baseVectors.setter
    def baseVectors(self, baseVectors):
        self._dirty()

        (xx, xy), (yx, yy) = baseVectors
        vectors = (float(xx), float(xy)), (float(yx), float(yy))

        det = (vectors[0][0] * vectors[1][1] - vectors[1][0] * vectors[0][1])
        if det == 0.:
            raise ValueError("Singular matrix for base vectors: " +
                             str(vectors))

        if vectors != self._baseVectors:
            self._baseVectors = vectors
            self._dirty()

    def _updateTitleOffset(self):
        """Update axes title offset according to margins"""
        margins = self.margins
        self.xAxis.titleOffset = 0, margins.bottom // 2
        self.yAxis.titleOffset = -3 * margins.left // 4, 0
        self.y2Axis.titleOffset = 3 * margins.right // 4, 0

    # Override size and marginRatios setters to update titleOffsets
    @GLPlotFrame.size.setter
    def size(self, size):
        GLPlotFrame.size.fset(self, size)
        self._updateTitleOffset()

    @GLPlotFrame.marginRatios.setter
    def marginRatios(self, ratios):
        GLPlotFrame.marginRatios.fset(self, ratios)
        self._updateTitleOffset()

    @property
    def dataRanges(self):
        """Ranges of data visible in the plot on x, y and y2 axes.

        This is different to the axes range when axes are not orthogonal.

        Type: ((xMin, xMax), (yMin, yMax), (y2Min, y2Max))
        """
        return self._DataRanges(self._dataRanges['x'],
                                self._dataRanges['y'],
                                self._dataRanges['y2'])

    def setDataRanges(self, x=None, y=None, y2=None):
        """Set data range over each axes.

        The provided ranges are clipped to possible values
        (i.e., 32 float range + positive range for log scale).

        :param x: (min, max) data range over X axis
        :param y: (min, max) data range over Y axis
        :param y2: (min, max) data range over Y2 axis
        """
        if x is not None:
            self._dataRanges['x'] = checkAxisLimits(
                x[0], x[1], self.xAxis.isLog, name='x')

        if y is not None:
            self._dataRanges['y'] = checkAxisLimits(
                y[0], y[1], self.yAxis.isLog, name='y')

        if y2 is not None:
            self._dataRanges['y2'] = checkAxisLimits(
                y2[0], y2[1], self.y2Axis.isLog, name='y2')

        self.xAxis.dataRange = self._dataRanges['x']
        self.yAxis.dataRange = self._dataRanges['y']
        self.y2Axis.dataRange = self._dataRanges['y2']

    _DataRanges = namedtuple('dataRanges', ('x', 'y', 'y2'))

    @property
    def transformedDataRanges(self):
        """Bounds of the displayed area in transformed data coordinates
        (i.e., log scale applied if any as well as skew)

        3-tuple of 2-tuple (min, max) for each axis: x, y, y2.
        """
        if self._transformedDataRanges is None:
            (xMin, xMax), (yMin, yMax), (y2Min, y2Max) = self.dataRanges

            if self.xAxis.isLog:
                try:
                    xMin = math.log10(xMin)
                except ValueError:
                    _logger.info('xMin: warning log10(%f)', xMin)
                    xMin = 0.
                try:
                    xMax = math.log10(xMax)
                except ValueError:
                    _logger.info('xMax: warning log10(%f)', xMax)
                    xMax = 0.

            if self.yAxis.isLog:
                try:
                    yMin = math.log10(yMin)
                except ValueError:
                    _logger.info('yMin: warning log10(%f)', yMin)
                    yMin = 0.
                try:
                    yMax = math.log10(yMax)
                except ValueError:
                    _logger.info('yMax: warning log10(%f)', yMax)
                    yMax = 0.

                try:
                    y2Min = math.log10(y2Min)
                except ValueError:
                    _logger.info('yMin: warning log10(%f)', y2Min)
                    y2Min = 0.
                try:
                    y2Max = math.log10(y2Max)
                except ValueError:
                    _logger.info('yMax: warning log10(%f)', y2Max)
                    y2Max = 0.

            self._transformedDataRanges = self._DataRanges(
                (xMin, xMax), (yMin, yMax), (y2Min, y2Max))

        return self._transformedDataRanges

    @property
    def transformedDataProjMat(self):
        """Orthographic projection matrix for rendering transformed data

        :type: numpy.matrix
        """
        if self._transformedDataProjMat is None:
            xMin, xMax = self.transformedDataRanges.x
            yMin, yMax = self.transformedDataRanges.y

            if self.isYAxisInverted:
                mat = mat4Ortho(xMin, xMax, yMax, yMin, 1, -1)
            else:
                mat = mat4Ortho(xMin, xMax, yMin, yMax, 1, -1)
            self._transformedDataProjMat = mat

        return self._transformedDataProjMat

    @property
    def transformedDataY2ProjMat(self):
        """Orthographic projection matrix for rendering transformed data
        for the 2nd Y axis

        :type: numpy.matrix
        """
        if self._transformedDataY2ProjMat is None:
            xMin, xMax = self.transformedDataRanges.x
            y2Min, y2Max = self.transformedDataRanges.y2

            if self.isYAxisInverted:
                mat = mat4Ortho(xMin, xMax, y2Max, y2Min, 1, -1)
            else:
                mat = mat4Ortho(xMin, xMax, y2Min, y2Max, 1, -1)
            self._transformedDataY2ProjMat = mat

        return self._transformedDataY2ProjMat

    @staticmethod
    def __applyLog(
        data: Union[float, numpy.ndarray],
        isLog: bool
    ) -> Optional[Union[float, numpy.ndarray]]:
        """Apply log to data filtering out """
        if not isLog:
            return data

        if isinstance(data, numbers.Real):
            return None if data < FLOAT32_MINPOS else math.log10(data)

        isBelowMin = data < FLOAT32_MINPOS
        if numpy.any(isBelowMin):
            data = numpy.array(data, copy=True, dtype=numpy.float64)
            data[isBelowMin] = numpy.nan

        with numpy.errstate(divide='ignore'):
            return numpy.log10(data)

    def dataToPixel(self, x, y, axis='left'):
        """Convert data coordinate to widget pixel coordinate.
        """
        assert axis in ('left', 'right')

        trBounds = self.transformedDataRanges

        xDataTr = self.__applyLog(x, self.xAxis.isLog)
        if xDataTr is None:
            return None

        yDataTr = self.__applyLog(y, self.yAxis.isLog)
        if yDataTr is None:
            return None

        # Non-orthogonal axes
        if self.baseVectors != self.DEFAULT_BASE_VECTORS:
            (xx, xy), (yx, yy) = self.baseVectors
            skew_mat = numpy.array(((xx, yx), (xy, yy)))

            coords = numpy.dot(skew_mat, numpy.array((xDataTr, yDataTr)))
            xDataTr, yDataTr = coords

        plotWidth, plotHeight = self.plotSize

        xPixel = (self.margins.left +
            plotWidth * (xDataTr - trBounds.x[0]) /
            (trBounds.x[1] - trBounds.x[0]))

        usedAxis = trBounds.y if axis == "left" else trBounds.y2
        yOffset = (plotHeight * (yDataTr - usedAxis[0]) /
                   (usedAxis[1] - usedAxis[0]))

        if self.isYAxisInverted:
            yPixel = self.margins.top + yOffset
        else:
            yPixel = self.size[1] - self.margins.bottom - yOffset

        return (
            int(xPixel) if isinstance(xPixel, numbers.Real) else xPixel.astype(numpy.int64),
            int(yPixel) if isinstance(yPixel, numbers.Real) else yPixel.astype(numpy.int64),
        )

    def pixelToData(self, x, y, axis="left"):
        """Convert pixel position to data coordinates.

        :param float x: X coord
        :param float y: Y coord
        :param str axis: Y axis to use in ('left', 'right')
        :return: (x, y) position in data coords
        """
        assert axis in ("left", "right")

        plotWidth, plotHeight = self.plotSize

        trBounds = self.transformedDataRanges

        xData = (x - self.margins.left + 0.5) / float(plotWidth)
        xData = trBounds.x[0] + xData * (trBounds.x[1] - trBounds.x[0])

        usedAxis = trBounds.y if axis == "left" else trBounds.y2
        if self.isYAxisInverted:
            yData = (y - self.margins.top + 0.5) / float(plotHeight)
            yData = usedAxis[0] + yData * (usedAxis[1] - usedAxis[0])
        else:
            yData = self.size[1] - self.margins.bottom - y - 0.5
            yData /= float(plotHeight)
            yData = usedAxis[0] + yData * (usedAxis[1] - usedAxis[0])

        # non-orthogonal axis
        if self.baseVectors != self.DEFAULT_BASE_VECTORS:
            (xx, xy), (yx, yy) = self.baseVectors
            skew_mat = numpy.array(((xx, yx), (xy, yy)))
            skew_mat = numpy.linalg.inv(skew_mat)

            coords = numpy.dot(skew_mat, numpy.array((xData, yData)))
            xData, yData = coords

        if self.xAxis.isLog:
            xData = pow(10, xData)
        if self.yAxis.isLog:
            yData = pow(10, yData)

        return xData, yData

    def _buildGridVerticesWithTest(self, test):
        vertices = []

        if self.baseVectors == self.DEFAULT_BASE_VECTORS:
            for axis in self.axes:
                for (xPixel, yPixel), data, text in axis.ticks:
                    if test(text):
                        vertices.append((xPixel, yPixel))
                        if axis == self.xAxis:
                            vertices.append((xPixel, self.margins.top))
                        elif axis == self.yAxis:
                            vertices.append((self.size[0] - self.margins.right,
                                             yPixel))
                        else:  # axis == self.y2Axis
                            vertices.append((self.margins.left, yPixel))

        else:
            # Get plot corners in data coords
            plotLeft, plotTop = self.plotOrigin
            plotWidth, plotHeight = self.plotSize

            corners = [(plotLeft, plotTop),
                       (plotLeft, plotTop + plotHeight),
                       (plotLeft + plotWidth, plotTop + plotHeight),
                       (plotLeft + plotWidth, plotTop)]

            for axis in self.axes:
                if axis == self.xAxis:
                    cornersInData = numpy.array([
                        self.pixelToData(x, y) for (x, y) in corners])
                    borders = ((cornersInData[0], cornersInData[3]),  # top
                               (cornersInData[1], cornersInData[0]),  # left
                               (cornersInData[3], cornersInData[2]))  # right

                    for (xPixel, yPixel), data, text in axis.ticks:
                        if test(text):
                            for (x0, y0), (x1, y1) in borders:
                                if min(x0, x1) <= data < max(x0, x1):
                                    yIntersect = (data - x0) * \
                                        (y1 - y0) / (x1 - x0) + y0

                                    pixelPos = self.dataToPixel(
                                        data, yIntersect)
                                    if pixelPos is not None:
                                        vertices.append((xPixel, yPixel))
                                        vertices.append(pixelPos)
                                    break  # Stop at first intersection

                else:  # y or y2 axes
                    if axis == self.yAxis:
                        axis_name = 'left'
                        cornersInData = numpy.array([
                            self.pixelToData(x, y) for (x, y) in corners])
                        borders = (
                            (cornersInData[3], cornersInData[2]),  # right
                            (cornersInData[0], cornersInData[3]),  # top
                            (cornersInData[2], cornersInData[1]))  # bottom

                    else:  # axis == self.y2Axis
                        axis_name = 'right'
                        corners = numpy.array([self.pixelToData(
                            x, y, axis='right') for (x, y) in corners])
                        borders = (
                            (cornersInData[1], cornersInData[0]),  # left
                            (cornersInData[0], cornersInData[3]),  # top
                            (cornersInData[2], cornersInData[1]))  # bottom

                    for (xPixel, yPixel), data, text in axis.ticks:
                        if test(text):
                            for (x0, y0), (x1, y1) in borders:
                                if min(y0, y1) <= data < max(y0, y1):
                                    xIntersect = (data - y0) * \
                                        (x1 - x0) / (y1 - y0) + x0

                                    pixelPos = self.dataToPixel(
                                        xIntersect, data, axis=axis_name)
                                    if pixelPos is not None:
                                        vertices.append((xPixel, yPixel))
                                        vertices.append(pixelPos)
                                    break  # Stop at first intersection

        return vertices

    def _buildVerticesAndLabels(self):
        width, height = self.size

        xCoords = (self.margins.left - 0.5,
                   width - self.margins.right + 0.5)
        yCoords = (height - self.margins.bottom + 0.5,
                   self.margins.top - 0.5)

        self.axes[0].displayCoords = ((xCoords[0], yCoords[0]),
                                      (xCoords[1], yCoords[0]))

        self._x2AxisCoords = ((xCoords[0], yCoords[1]),
                              (xCoords[1], yCoords[1]))

        if self.isYAxisInverted:
            # Y axes are inverted, axes coordinates are inverted
            yCoords = yCoords[1], yCoords[0]

        self.axes[1].displayCoords = ((xCoords[0], yCoords[0]),
                                      (xCoords[0], yCoords[1]))

        self._y2Axis.displayCoords = ((xCoords[1], yCoords[0]),
                                      (xCoords[1], yCoords[1]))

        super(GLPlotFrame2D, self)._buildVerticesAndLabels()

        vertices, gridVertices, labels = self._renderResources

        # Adds vertices for borders without axis
        extraVertices = []
        extraVertices += self._x2AxisCoords
        if not self.isY2Axis:
            extraVertices += self._y2Axis.displayCoords

        extraVertices = numpy.array(
            extraVertices, copy=False, dtype=numpy.float32)
        vertices = numpy.append(vertices, extraVertices, axis=0)

        self._renderResources = (vertices, gridVertices, labels)

    @property
    def foregroundColor(self):
        """Color used for frame and labels"""
        return self._foregroundColor

    @foregroundColor.setter
    def foregroundColor(self, color):
        """Color used for frame and labels"""
        assert len(color) == 4, \
            "foregroundColor must have length 4, got {}".format(len(self._foregroundColor))
        if self._foregroundColor != color:
            self._y2Axis.foregroundColor = color
            GLPlotFrame.foregroundColor.fset(self, color) # call parent property


from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse

from django.template import Context, loader

def index(request):
   omi = "omprakash"
   import urllib
   import json
   resp = urllib.urlopen('https://api.coursera.org/api/courses.v1?q=search&query=malware+underground').read()
   content = json.loads(resp)
   template = loader.get_template("myapp/index.html")
   context = {
      'omi': omi,
      'content' : content,
    }
   return HttpResponse(template.render(context, request))

def search(request):
   form = data = request.GET.get('squery')
   url = "https://api.coursera.org/api/courses.v1?q=search&query=" + form
   omi = "omprakash"
   import urllib
   import json
   vari = form
   resp = urllib.urlopen('https://api.coursera.org/api/courses.v1?start=1&limit=3&q=search&query='+ vari).read()
   content = json.loads(resp)
   template = loader.get_template("myapp/search.html")
   context = {
      'omi': omi,
      'content' : content,
      'form' : form,
    }
   return HttpResponse(template.render(context, request))