import pandas as pd
import numpy as np
from tqdm.auto import tqdm
import rasterio
from pyproj import Proj, transform
from os import listdir
from datetime import datetime
import json
import math
from math import atan,degrees,sqrt
from shapely import geometry
from multiprocessing import Pool

from PIL import Image, ImageDraw
import scipy.misc as smp
import imageio

from GeoLibrary import *
from utilfunc import *

GRID_WIDTH = 512
GRID_HEIGHT = 512

with open("FullSugar.geojson") as f:
	features = json.load(f)["features"]

# generate latlon coordinates for each grid in the tile
def generate_positions(filepath):
	width,height = get_size(filepath)

	# absolute latlon for the tile
	latlon_tile = [(147.95529899839866, -19.893321306080015), \
			   (149.01671779369045, -19.893321306080015), \
			   (149.01671779369045, -20.876176661128618), \
				(147.95529899839866, -20.876176661128618)]

	top_left_lat_long, top_right_lat_long, bottom_right_lat_long, bottom_left_lat_long = latlon_tile[0], latlon_tile[1],\
																		latlon_tile[2], latlon_tile[3]

	fullImageWidth, fullImageHeight = width,height

	numOfXSquares=fullImageWidth//GRID_WIDTH
	numOfYSquares=fullImageHeight//GRID_HEIGHT
	grid_latlon_dict = {}
	for x in list(range(numOfXSquares)):
		for y in list(range(numOfYSquares)):
			fourLatLongPositions = [GetLatLongForCoords(r[0],r[1], top_left_lat_long, top_right_lat_long,\
												bottom_right_lat_long, bottom_left_lat_long, \
												fullImageWidth, fullImageHeight) for r in GetFourPositions(x,y)]
			grid_latlon_dict["{}-{}".format(x,y)] = fourLatLongPositions

	return grid_latlon_dict

# get sugarcane xy positions in a given tile
# only need to run once for each tile
# store it in disk
def generate_sugarcane_position(filepath):
	grid_latlon_dict = generate_positions(filepath)

	# absolute coordinate for the tile

	latlon_tile = [(147.95529899839866, -19.893321306080015), \
			   (149.01671779369045, -19.893321306080015), \
			   (149.01671779369045, -20.876176661128618), \
				(147.95529899839866, -20.876176661128618)]

	top_left_lat_long, top_right_lat_long, bottom_right_lat_long, bottom_left_lat_long = latlon_tile[0], latlon_tile[1],\
																		latlon_tile[2], latlon_tile[3]

	fullImageWidth = 10980
	fullImageHeight = 10980

	cnt = 0
	total_sugarcane_positions = []
	for key, value in grid_latlon_dict.items():
		# top_left_lat_long, top_right_lat_long,  bottom_right_lat_long, bottom_left_lat_long = list(value[0]), list(value[1]), list(value[2]), list(value[3])
		# fullImageWidth = GRID_WIDTH
		# fullImageHeight = GRID_HEIGHT

		gridGeo = { "type": "Polygon", "coordinates": [[ list(value[0]), \
													 list(value[1]), \
													 list(value[2]), \
													 list(value[3]), \
													 list(value[0]) ]]  }

		gridGeo_go = geometry.GeometryCollection([geometry.shape(gridGeo).buffer(0)])

		result=geometry.GeometryCollection()
		for k in features:
			if geometry.shape(k["geometry"]).intersects(gridGeo_go):
				result=result.union(geometry.shape(k["geometry"]).intersection(gridGeo_go))

		if gridGeo_go.intersects(result):
			cnt+=1
			# print(True)
			print("############## This iteration is for the {}th grid, key {} ##############".format(cnt, key))
			print(value)
			needed_ij_list = []
			# find the mask in the input region
			print(top_left_lat_long, top_right_lat_long,  bottom_right_lat_long, bottom_left_lat_long )

			xy_pair = key.split('-') # relative position
			grid_x, grid_y = int(xy_pair[0]), int(xy_pair[1])
			print( GetFourPositions(grid_x,grid_y) )

			grid_x_abs, grid_y_abs = grid_x * GRID_WIDTH, grid_y * GRID_HEIGHT

			print(grid_x_abs, grid_y_abs)

			for i in tqdm(list(range( grid_x_abs, grid_x_abs + GRID_WIDTH ))):
				for j in list(range( grid_y_abs, grid_y_abs + GRID_HEIGHT )):

					lat_long=GetLatLongForCoords(i,j, top_left_lat_long, top_right_lat_long,  bottom_right_lat_long, bottom_left_lat_long, fullImageWidth, fullImageHeight)
					if result.intersects(geometry.Point(lat_long)):
						# this coordinate is needed

						needed_ij_list.append((i,j))
						# print(True)

			total_sugarcane_positions += needed_ij_list
			# print(needed_ij_list)

			# data = np.zeros( (512,512,3), dtype=np.uint8 )

			# for pair in needed_ij_list:
			# 	i = pair[0]
			# 	j = pair[1]
			# 	newi = i - grid_x * GRID_WIDTH
			# 	newj = j - grid_y * GRID_HEIGHT

			# 	data[newj,newi] = (255,255,255)
			# imageio.imwrite("test.png", data)

		# else:
			# print(False)

		# if cnt == 1:
		# 	break

	print(cnt)
	return total_sugarcane_positions

if __name__ == '__main__':
	filepath = "/mnt/volume_sgp1_01/pepsL2A_processed_img/T55KFT/split_dates/"
	tile_filepath = filepath+"20161222.tif"

	# grid_latlon_dict = generate_positions(tile_filepath)
	# print(grid_latlon_dict)

	total_sugarcane_positions = generate_sugarcane_position(tile_filepath)
	tile1_dict = { "sugarcane_positions": total_sugarcane_positions }
	with open("tile1_sugarcane_positions.json", "w") as fp:
		json.dump(tile1_dict, fp)


#!/usr/bin/env python3

import argparse
import glob
import os
import os.path
import re
import shutil
import subprocess
import sys
import tempfile

def get_config(modes, engine, top, srcs, depth, params):
  config_str = ''
  config_str = '[tasks]\n'
  tasks = ['task_{:s}'.format(m) for m in modes]
  config_str += '\n'.join(tasks)
  config_str += '\n\n'

  config_str += '[options]\n'
  options = ['task_{:s}: mode {:s}'.format(m, m) for m in modes]
  config_str += '\n'.join(options)
  config_str += '\n'
  options = ['task_{:s}: depth {:d}'.format(m, depth) for m in modes]
  config_str += '\n'.join(options)
  config_str += '\n\n'

  config_str += '[engines]\n'
  config_str += '{:s}\n'.format(engine)
  config_str += '\n'

  config_str += '[script]\n'
  for f in srcs:
    _, extension = os.path.splitext(f)
    sv_flag = ' -sv' if extension == '.sv' else ''
    config_str += 'read -formal{:s} -D{:s} {:s}\n'.format(sv_flag, top.upper(), os.path.basename(f))

  for k, v in params.items():
    config_str += 'chparam -set {:s} {} {:s}\n'.format(k, v, top)

  config_str += 'prep -top {:s}\n'.format(top)
  config_str += '\n'

  config_str += '[files]\n'
  config_str += '\n'.join(srcs)

  return config_str

class ParamAction(argparse.Action):
  def __call__(self, parser, namespace, values, option_string=None):
    setattr(namespace, self.dest, dict())
    for value in values:
      parts = value.split('=')

      if len(parts) == 1:
        parser.error('Argument "{}" contains no "=".'.format(value))
      if len(parts) > 2:
        parser.error('Argument "{}" contains multiple "=".'.format(value))

      getattr(namespace, self.dest)[parts[0]] = parts[1]

def main():
  parser = argparse.ArgumentParser(description='Configure and run symbiyosys.')
  parser.add_argument('--sby_path', required=True, help='Path to sby executable.')
  parser.add_argument('--yosys_path', required=True, help='Path to yosys executable.')
  parser.add_argument('--abc_path', required=True, help='Path to yosys-abc executable.')
  parser.add_argument('--smtbmc_path', required=True, help='Path to yosys-smtbmc executable.')
  parser.add_argument('--solver_paths', nargs='*', help='Solver paths to make available to Yosys.')
  parser.add_argument('--modes', nargs='+', required=True, help='Task modes.')
  parser.add_argument('--engine', default='smtbmc', help='Proof engine.')
  parser.add_argument('--top', required=True, help='Top module name.')
  parser.add_argument('--params', nargs='*', action=ParamAction, default={},
      help='Params for top module. e.g. key=value')
  parser.add_argument('--depth', type=int, default=20, help='Solver depth.')
  parser.add_argument('--vcd_dir', help='Directory for output trace files.')
  parser.add_argument('--ignore_failure', action='store_true',
      help='Do not report error code from Symbiyosys.')
  parser.add_argument('srcs', nargs='+', help='(System) verilog sources.')

  args = parser.parse_args()

  with tempfile.TemporaryDirectory() as directory:
    with open(os.path.join(directory, 'config.sby'), 'w') as f:
      config = get_config(args.modes, args.engine, args.top, args.srcs, args.depth, args.params)
      f.write(config)

    sby_args = [
        os.path.abspath(args.sby_path),
        '--yosys',
        os.path.abspath(args.yosys_path),
        '--abc',
        os.path.abspath(args.abc_path),
        '--smtbmc',
        os.path.abspath(args.smtbmc_path),
        os.path.join(directory, 'config.sby'),
    ]

    env = os.environ.copy()
    paths = ':'.join([os.path.abspath(path) for path in args.solver_paths])
    if paths:
      env['PATH'] = paths + ':' + env['PATH']

    completed = subprocess.run(sby_args, env=env)

    if args.vcd_dir:
      try:
        os.mkdir(args.vcd_dir)
      except FileExistsError:
        pass

      traces = glob.glob(os.path.join(directory, 'config_task_*/engine_0/*.vcd'))

      for trace in traces:
        match = re.search(r'config_task_(\w+)', trace)
        if not match:
          raise RuntimeError('Malformed trace file: {:s}'.format(trace))

        mode = match.group(1)
        name = '{:s}_{:s}'.format(mode, os.path.basename(trace))
        shutil.copyfile(trace, os.path.join(args.vcd_dir, name))

    if not args.ignore_failure:
      sys.exit(completed.returncode)

if __name__ == '__main__':
  main()


import numpy as np
import torch

# Functions that convert pybind11 objects to serializable formats

def torchify(obj):
    r"""
    Convert to nested dictionary of torch tensors for use with
    torch.save. Roughly 6.3x file size of original Parasolid .x_t
    """

    if torch.is_tensor(obj):
        return obj

    primitive = (int, str, bool, float)
    number = (int, float)
    if isinstance(obj, primitive):
        return obj
    if isinstance(obj, np.ndarray):
        return torch.from_numpy(obj)
    if isinstance(obj, list):
        if len(obj) > 0:
            if isinstance(obj[0], number):
                return torch.tensor(obj)
            if isinstance(obj[0], np.ndarray):
                return torch.tensor(np.stack(obj))
            if isinstance(obj[0], list):
                if len(obj[0]) > 0:
                    if isinstance(obj[0][0], np.ndarray):
                        return torch.tensor(
                            np.stack([
                                np.stack(l) for l in obj
                            ])
                        )
                else:
                    return [[]]
        return [torchify(x) for x in obj]

    keys = [x for x in dir(obj) if not x.startswith('__')]

    if 'name' in keys and 'value' in keys: # this is an enum
        return {
            'value': getattr(obj, 'value'),
            'name': getattr(obj, 'name'),
            'enum_size': len(keys) - 2 # the other keys are all enum opts
        }

    return dict(zip(
        keys,
        [torchify(getattr(obj, key)) for key in keys]
    ))

def jsonify(obj):
    r"""
    Convert to nested dictionary of python primitives for use with
    json.dump. Roughly 10x file size of original Parasolid .x_t
    """
    primitive = (int, str, bool, float)
    if isinstance(obj, primitive):
        return obj
    if isinstance(obj, np.ndarray):
        return obj.tolist()
    if isinstance(obj, list):
        return [jsonify(x) for x in obj]

    keys = [x for x in dir(obj) if not x.startswith('__')]

    if 'name' in keys and 'value' in keys: # this is an enum
        return {
            'value': getattr(obj, 'value'),
            'name': getattr(obj, 'name'),
            'enum_size': len(keys) - 2 # the other keys are all enum opts
        }

    return dict(zip(
        keys,
        [jsonify(getattr(obj, key)) for key in keys]
    ))


from __future__ import print_function
import copy
import subprocess
import os
import yaml
import math
import pickle
import random

import numpy as np
import numpy.ma as ma
import pandas as pd

from sklearn.decomposition import PCA, FastICA, NMF
from sklearn.preprocessing import normalize

import pyclass
import pgutils
from sicparse import OptionParser

def main():

    # Input parameters
    parser = OptionParser()
    parser.add_option("-n", "--n_components",
                      dest="number_components", nargs=1, default=5)

    try:
        (options, args) = parser.parse_args()
    except:
        pyclass.message(pyclass.seve.e, "PCA", "Invalid option")
        pyclass.sicerror()
        return
    if (not pyclass.gotgdict()):
        pyclass.get(verbose=False)

    # Setup parameters
    number_components = int(options.number_components)+1

    redo_index = True
    if input_file:
        pyclass.comm('file in "{}"'.format(input_file))
        pyclass.comm('find')
        modification_times_yaml_file = ".{}_modification_times_pca.yaml".format(input_file.replace("/", "_"))
        modification_time = os.path.getmtime(input_file)

        if os.path.exists(modification_times_yaml_file):
            previous_modification_times = yaml.safe_load(
                open(modification_times_yaml_file))
        else:
            previous_modification_times = {}
        if previous_modification_times is None:
            previous_modification_times = {}
        if input_file in previous_modification_times.keys():
            previous_modification_time = previous_modification_times[
                input_file]
            if (round(previous_modification_time, 0) >= round(
                    modification_time, 0)):
                redo_index = False

        previous_modification_times[input_file] = modification_time
        with open(modification_times_yaml_file, 'w') as outfile:
            yaml.dump(previous_modification_times, outfile)

    idx_list = []
    idx_list.append(pyclass.gdict.idx.num)
    idx_list.append(pyclass.gdict.idx.teles)
    idx_list.append(pyclass.gdict.idx.scan)
    idx_list.append(pyclass.gdict.idx.subscan)
    idx_list.append(pyclass.gdict.idx.sourc)
    idx_list.append(pyclass.gdict.idx.line)
    idx_list.append(pyclass.gdict.idx.boff)
    idx_list.append(pyclass.gdict.idx.loff)
    idx_list.append(pyclass.gdict.idx.ver)
    idx_list = np.asarray(idx_list)
    df = pd.DataFrame(
        idx_list.T,
        columns=["number", "telescope", "scan", "subscan",
                 "source", "line", "boff", "loff", "version"]
    )

    pyclass.comm("set var user")
    pyclass.comm("import sofia")
    scan_group = df.groupby(["scan"])
    df["mission_id"] = None
    for name, group in scan_group:
        number = group.number.iloc[0]
        pyclass.comm("get {}".format(number))
        mission_id = copy.deepcopy(
            pyclass.gdict.r.user.sofia.mission_id.__sicdata__)
        df.loc[df["scan"] == group.scan.iloc[0],
               "mission_id"] = str(mission_id).strip()

    df.source = df.source.astype(str).str.strip()
    with open(pca_index_file, "wb") as filehandler:
        pickle.dump(df, filehandler)

main()


from selenium import webdriver
from selenium.webdriver.common.by import By
import time
class calender2:

    def test(self):

        driver = webdriver.Chrome()
        driver.maximize_window()
        driver.get("https://www.expedia.co.in")
        driver.implicitly_wait(4)

        #Click on Flight Tab
        flightTab = driver.find_element(By.XPATH,"//a[@id='tab-flight-tab']")
        flightTab.click()

        time.sleep(5)

        #Click on flight Departure text box
        departingtxt = driver.find_element(By.XPATH,"//input[@id='flight-departing']")
        departingtxt.click()
        time.sleep(2)
       # if driver.find_element(By.XPATH,"//div[@class='datepicker-cal-month'][position()=1]") is True:
        #    print("the date picker is diaplayed ")
        pickedDt = driver.find_element(By.XPATH,"//div[@class='datepicker-cal-month'][position()=1]//button[text()='9']")
        pickedDt.click()

        time.sleep(10)

        departingtxt.click()
        dateList = driver.find_elements(By.XPATH,"//div[@class='datepicker-cal-month'][position()=1]//button[@class ='datepicker-cal-date']")

        for dt in dateList:
            if dt.text == "10":
                dt.click()
                print("Clicked the date" )
                break

        time.sleep(5)
cc = calender2()
cc.test()


'''
Databases for battleball
'''

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save

class UserProfile(models.Model):
    ''' elements of the user profile '''
    user = models.OneToOneField(User, unique=True)

    picture = models.ImageField(upload_to='profile_images', blank=True)

    def __str__(self):
        return self.user.username

def create_profile(sender, instance, created, **kwargs):
    ''' created profile '''
    if created:
        profile, created = UserProfile.objects.get_or_create(user=instance)

post_save.connect(create_profile, sender=User)

class Piece(models.Model):
    ''' piece on the team '''
    def __init__(self, *args, **kwargs):
        return super(Piece, self).__init__(*args, **kwargs)
    name = models.CharField(max_length=30)
    piece_size = models.IntegerField(default=1)
    has_ball = models.BooleanField(default=False)
    injury = models.IntegerField(default='0')
    str_position = models.CharField(max_length=20, default='{"xpos":-1, "ypos":-1}')
    roll_size = models.IntegerField(default=20)

    def __unicode__(self):
        return self.name

class Game(models.Model):
    ''' crucial items for game board '''
    title = models.CharField("Title", max_length=100, default='untitled')
    url = models.URLField("URL", max_length=250, blank=True)
    boardFile = models.CharField(max_length=30, default=0)
    homeTeam = models.CharField(max_length=30)
    awayTeam = models.CharField(max_length=30)
    turn = models.BooleanField(default=True)
    homeScore = models.IntegerField(default=0)
    awayScore = models.IntegerField(default=0)

    def instatiate_pieces():
        '''
        All 20 pieces for full game
        '''
        heavy_tackle_h = Piece(roll_size=6, piece_size=2, name='heavy tackle')
        tackle_h = Piece(roll_size=6, piece_size=1, name='tackle')
        lineman1_h = Piece(roll_size=8, piece_size=1, name='lineman 1')
        lineman2_h = Piece(roll_size=8, piece_size=1, name='lineman 2')
        linebacker1_h = Piece(roll_size=10, piece_size=1, name='linebacker 1')
        linebacker2_h = Piece(roll_size=10, piece_size=1, name='linebacker 2')
        safety1_h = Piece(roll_size=12, piece_size=1, name='safety 1')
        safety2_h = Piece(roll_size=12, piece_size=1, name='safety 2')
        running_back1_h = Piece(roll_size=20, piece_size=1, name='running back 1')
        running_back2_h = Piece(roll_size=20, piece_size=1, name='running back 2')
        running_back3_h = Piece(roll_size=20, piece_size=1, name='running back 3')

        heavy_tackle_a = Piece(roll_size=6, piece_size=2, name='heavy tackle')
        tackle_a = Piece(roll_size=6, piece_size=1, name='tackle')
        lineman1_a = Piece(roll_size=8, piece_size=1, name='lineman 1')
        lineman2_a = Piece(roll_size=8, piece_size=1, name='lineman 2')
        linebacker1_a = Piece(roll_size=10, piece_size=1, name='linebacker 1')
        linebacker2_a = Piece(roll_size=10, piece_size=1, name='linebacker 2')
        safety1_a = Piece(roll_size=12, piece_size=1, name='safety 1')
        safety2_a = Piece(roll_size=12, piece_size=1, name='safety 2')
        running_back1_a = Piece(roll_size=20, piece_size=1, name='running back 1')
        running_back2_a = Piece(roll_size=20, piece_size=1, name='running back 2')
        running_back3_a = Piece(roll_size=20, piece_size=1, name='running back 3')

        player_dict = {'home': [heavy_tackle_h, tackle_h, lineman1_h, lineman2_h,
                                linebacker1_h, linebacker2_h, safety1_h, safety2_h,
                                running_back1_h, running_back2_h, running_back3_h],

                       'away': [heavy_tackle_a, tackle_a, lineman1_a, lineman2_a,
                                linebacker1_a, linebacker2_a, safety1_a, safety2_a,
                                running_back1_a, running_back2_a, running_back3_a]}

        return player_dict

    pieces = instatiate_pieces()

    def __unicode__(self):
        return self.title

class Coach(models.Model):
    ''' users can create a coach '''
    name = models.CharField(max_length=30)
    user = models.OneToOneField(User, unique=True)

    def __unicode__(self):
        return self.name

# These blocks of code is added by Tenzin
class Team(models.Model):
    ''' Team name and stats '''
    teamName = models.CharField(max_length=30)
    gamesPlayed = models.IntegerField(default=0)
    gamesWon = models.IntegerField(default=0)
    rank = models.IntegerField(default=0)
    def __str__(self):
        return self.teamName


import requests
from bs4 import BeautifulSoup
import math

LIMIT = 20

def get_last_page(url):
    request = requests.get(url)
    soup = BeautifulSoup(request.text, "html.parser")
    total_count = soup.find(
        "strong", {"class": "dev_tot"}).get_text()
    last_page = math.ceil(int(total_count.replace(',', ""))/LIMIT)
    return last_page

def extract_job(li):
    company = li.find(
        "div", {"class": "post-list-corp"}).find("a")["title"]
    job_name = li.find(
        "div", {"class": "post-list-info"}).find("a")["title"]
    location = li.find("p", {"class": "option"}).find(
        "span", {"class": "loc long"}).get_text(strip=True)
    job_id = li["data-gno"]
    return {"name": job_name, "company": company, "location": location, "link": f"http://www.jobkorea.co.kr/Recruit/GI_Read/{job_id}"}

def extract_jobs(url, last_page):
    extracted_jobs = []
    for page in range(last_page):
        print(f"Scrapping page:{page}")
        request = requests.get(f"{url}&Page_No={page}")
        soup = BeautifulSoup(request.text, "html.parser")
        infos = soup.find("div", {"class": "recruit-info"})
        results = infos.find_all("li", {"class": "list-post"})
        for result in results:
            job = extract_job(result)
            extracted_jobs.append(job)
    return extracted_jobs

def get_jobs(word):
    url = f"http://www.jobkorea.co.kr/Search/?stext={word}"
    last_page = get_last_page(url)
    jobs = extract_jobs(url, last_page)
    return jobs


import argparse
from pathlib import Path
import functools as f
import multiprocessing

import cv2
import pickle
import numpy as np
import pandas as pd
import lmdb
import tqdm

# https://community.drivendata.org/t/python-code-to-find-the-roi/4499
def get_rect(row, root, mode):
    _, item = row
    frames = []
    cap = cv2.VideoCapture(str(root / mode / item.filename))
    xs, ys, ws, hs = [], [], [], []
    v_len = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    for i in range(v_len):
        success, image = cap.read()

        mask = cv2.inRange(image, (9, 13, 104), (98, 143, 255))
        points = np.where(mask > 0)
        p2 = [p for p in zip(points[0], points[1])]
        x, y, w, h = cv2.boundingRect(np.float32(p2))
        xs.append(x)
        ys.append(y)
        ws.append(w)
        hs.append(h)
        frames.append(image[..., -1])

    cap.release()

    frames = np.array(frames)
    x = min(xs)
    y = min(ys)
    w = max(ws)
    h = max(hs)

    frames = frames[:, x:x + w, y:y + h]
    out = {'frames': np.array(frames).transpose(1, 2, 0)}

    if 'stalled' in item:
        out.update({'label': item.stalled})

    return item.filename.split('.')[0], out

def parse_args():
    parser = argparse.ArgumentParser()

    parser.add_argument('mode', choices=['test', 'micro'])
    parser.add_argument('--data', type=str, required=True)
    parser.add_argument('--save', type=str, required=True)

    return parser.parse_args()

def main():
    args = parse_args()

    data_root = Path(args.data)
    args.save = Path(args.save)
    mode = args.mode

    if mode == 'test':
        meta = pd.read_csv(data_root / 'test_metadata.csv')
    else:
        meta = pd.read_csv(data_root / 'train_metadata.csv')
        meta = meta[meta[mode]].copy()
        meta = pd.merge(
            meta[meta[mode]].copy(),
            pd.read_csv(data_root / 'train_labels.csv'),
            on='filename',
        )

    with tqdm.tqdm(meta.iterrows(), total=len(meta)) as pbar:
        with multiprocessing.Pool(40) as p:
            features = dict(p.imap_unordered(func=f.partial(get_rect, root=data_root, mode=mode), iterable=pbar))

    map_size = sum(features[f]['frames'].nbytes for f in features)
    map_size = int(1.1*map_size)

    env = lmdb.open(
        str(args.save / f'{mode}_croped2.lmdb'),
        map_size=map_size,
    )

    with env.begin(write=True) as txn:
        txn.put(('keys').encode(), pickle.dumps(list(features.keys())))

        with tqdm.tqdm(features) as pbar:
            for key in pbar:
                txn.put(key.encode(), pickle.dumps(features[key]))

if __name__ == '__main__':
    main()


import requests
import json
import yaml
import request

def symbol(authtoken):
    endpoint="/symbol"
    response = requests.get(
                request.client.url+endpoint,
                headers={'content-type': 'application/json',"Authorization":authtoken})
    output=yaml.load(json.dumps(response.json()))
    if output["success"]==True:
            return output["data"]
    else:
            return "error"


#! /usr/bin/env python3
import rospy
from torchvision import transforms
import torch
import cv2 as cv
# from std_msgs.msg import String
from anney_melodic_pkg.msg import Order

# Load the model
model = torch.load("/home/mustar/anney-robot-melodic/src/anney_melodic_pkg/model_080622.pth",map_location=torch.device("cpu"))
model.eval()

def create_list(orders,units):
    ''' This function is to create the order list based on its respective quantity '''

    order_temp = []
    for i in range(len(orders)):
        for j in range(units[i]):
            if(orders[i] == "mi_goreng"):
                order_temp.append("mee_goreng")
            elif(orders[i] == "sate"):
                order_temp.append("satay")
            else:
                order_temp.append(orders[i])

    return order_temp

def callback(data):
    rospy.loginfo(f'Table_num: {data.table_num} {data.orders} {data.units}')

    order_temp = create_list(data.orders,data.units) # Create full foods list
    rospy.loginfo(f'This is temp list: {order_temp}')
    train_transforms = transforms.Compose([transforms.ToTensor()])
    classes = ["mee_goreng", "nasi_goreng", "nasi_lemak", "roti_canai", "satay"]

    can_remove = True

    capture = cv.VideoCapture(2) # Initialize video capturing object with camera device index as the parameter

    # The initial tracker and global variables
    tracker = cv.TrackerKCF_create()
    tracked_bounding_box = None
    label = None

    while (len(order_temp) != 0):
        isTrue, frame = capture.read()

        # If there is an existing object, update and track the object.
        if tracked_bounding_box is not None:
            (success, box) = tracker.update(frame)

            if success:
                if(can_remove and label in order_temp):
                    rospy.loginfo(f'{label} for table {data.table_num} is done!')
                    order_temp.remove(label)
                    rospy.loginfo(f'This is temp list: {order_temp}')
                    can_remove = False

                (x, y, w, h) = [int(v) for v in box]
                cv.rectangle(frame, (x, y), (x + w, y + h),(0, 255, 0), 2)
                cv.putText(frame, label, (x, y),cv.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

            # If the object has disappeared from the frame, remove the previous tracker and create a new one.
            else:
                del tracker
                tracker = cv.TrackerKCF_create()
                tracked_bounding_box = None
                can_remove = True

        # If there are no current objects, use the model to detect possible food images in the capture.
        else:
            frame_transformed = train_transforms(cv.cvtColor(frame, cv.COLOR_BGR2RGB))
            prediction = model([frame_transformed])[0] # The model detects from the frame

            if len(prediction["scores"]) > 0:
                highest_confidence = torch.argmax(prediction["scores"], axis=0)
                label_idx = prediction["labels"][highest_confidence].item()
                label = classes[label_idx]
                box = prediction["boxes"][highest_confidence]

                # Initialise the tracker with the predicted bounding box.
                tracked_bounding_box = [round(i.item()) for i in box]
                tracker.init(frame, tracked_bounding_box)

                print(f"{label} detected. Attempting to track the object.")

                start_point = (round(box[0].item()), round(box[1].item()))
                end_point = (round(box[2].item()), round(box[3].item()))

                cv.rectangle(frame, start_point, end_point, (0, 255, 0), 2)
                cv.putText(frame, label, start_point,
                        cv.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

        cv.imshow("Video", frame)

        if cv.waitKey(20) & 0xFF == ord("d"):
            break

    rospy.loginfo(f'All orders are done, can start to serve to table {data.table_num} now!')
    capture.release()
    cv.destroyAllWindows()

def listener():
    # Initialize subscriber node and let it subscribe to a topic
    rospy.init_node("Subscriber_Node", anonymous=True)
    rospy.Subscriber("order_topic", Order, callback)
    rospy.spin()

if __name__ == "__main__":
    try:
        listener()
    except rospy.ROSInterruptException:
        pass


#coding=utf8
__author__ = 'xujun'
from utils.MapHelper import genMap, mapMerge
import json
from types import BooleanType, StringTypes
# datas

class LicenseDataGenerator(object):
    def __init__(self, config, minfo):
        self.config = config
        self.minfo = minfo

    def gen(self):
        lines = []
        dMap = {}
        for key, value in self.config.iteritems():
            if  key.find("/") == -1:
                lines.append("%s=%s" % (key, value))
            else:
                m = genMap(key, value, "/")
                dMap = mapMerge(dMap, m)
        for key, value in dMap.iteritems():
            lines.append("%s=%s" % (key, json.dumps(value)))
        lines.append("minfo=%s" %self.minfo)
        str = ";".join(lines)
        return str


import datetime
import os
import shutil
import re

from django.conf import settings
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse as urlreverse
import django.test
from StringIO import StringIO
from pyquery import PyQuery

from ietf.utils.test_utils import login_testing_unauthorized
from ietf.utils.test_data import make_test_data
from ietf.utils.mail import outbox

from ietf.person.models import Person, Email
from ietf.group.models import Group, Role
from ietf.doc.models import *
from ietf.submit.models import IdSubmissionDetail, Preapproval

class SubmitTestCase(django.test.TestCase):
    fixtures = ['names', 'idsubmissionstatus']

    def setUp(self):
        self.staging_dir = os.path.abspath("tmp-submit-staging-dir")
        os.mkdir(self.staging_dir)
        settings.IDSUBMIT_STAGING_PATH = self.staging_dir

        self.repository_dir = os.path.abspath("tmp-submit-repository-dir")
        os.mkdir(self.repository_dir)
        settings.INTERNET_DRAFT_PATH = settings.IDSUBMIT_REPOSITORY_PATH = self.repository_dir

        self.archive_dir = os.path.abspath("tmp-submit-archive-dir")
        os.mkdir(self.archive_dir)
        settings.INTERNET_DRAFT_ARCHIVE_DIR = self.archive_dir

    def tearDown(self):
        shutil.rmtree(self.staging_dir)
        shutil.rmtree(self.repository_dir)
        shutil.rmtree(self.archive_dir)

    def do_submission(self, name, rev):
        # break early in case of missing configuration
        self.assertTrue(os.path.exists(settings.IDSUBMIT_IDNITS_BINARY))

        # get
        url = urlreverse('submit_index')
        r = self.client.get(url)
        self.assertEquals(r.status_code, 200)
        q = PyQuery(r.content)
        self.assertEquals(len(q('input[type=file][name=txt]')), 1)

        # construct appropriate text draft
        f = open(os.path.join(settings.BASE_DIR, "submit", "test_submission.txt"))
        template = f.read()
        f.close()

        submission_text = template % dict(
            date=datetime.date.today().strftime("%d %B %Y"),
            expire=(datetime.date.today() + datetime.timedelta(days=100)).strftime("%Y-%m-%d"),
            year=datetime.date.today().strftime("%Y"),
            month_year=datetime.date.today().strftime("%B, %Y"),
            filename="%s-%s" % (name, rev),
            )

        test_file = StringIO(str(submission_text))
        test_file.name = "somename.txt"

        # submit
        r = self.client.post(url,
                             dict(txt=test_file))
        self.assertEquals(r.status_code, 302)
        supply_submitter_url = r["Location"]
        self.assertTrue(os.path.exists(os.path.join(self.staging_dir, u"%s-%s.txt" % (name, rev))))
        self.assertEquals(IdSubmissionDetail.objects.filter(filename=name).count(), 1)
        submission = IdSubmissionDetail.objects.get(filename=name)
        self.assertEquals(submission.tempidauthors_set.count(), 1)
        self.assertTrue(re.search('\s+Summary:\s+0\s+errors|No nits found', submission.idnits_message))
        author = submission.tempidauthors_set.all()[0]
        self.assertEquals(author.first_name, "Test Name")

        return supply_submitter_url

    def supply_submitter(self, name, supply_submitter_url):
        # check the page
        r = self.client.get(supply_submitter_url)
        q = PyQuery(r.content)
        self.assertEquals(len(q('input[type=submit][name=autopost]')), 1)

        # post submitter info
        r = self.client.post(supply_submitter_url,
                             dict(autopost="1",
                                  name="Test Name",
                                  email="testname@example.com",
                                  ))
        # submitter is saved as author order 0
        submission = IdSubmissionDetail.objects.get(filename=name)
        self.assertEquals(submission.tempidauthors_set.count(), 2)
        self.assertEquals(submission.tempidauthors_set.get(author_order=0).first_name, "Test Name")

        return r

    def test_submit_new(self):
        # submit new -> supply submitter info -> approve
        draft = make_test_data()

        name = "draft-ietf-mars-testing-tests"
        rev = "00"

        supply_submitter_url = self.do_submission(name, rev)

        # supply submitter info, then draft should be in and ready for approval
        mailbox_before = len(outbox)
        r = self.supply_submitter(name, supply_submitter_url)

        self.assertEquals(r.status_code, 302)
        status_url = r["Location"]
        self.assertEquals(len(outbox), mailbox_before + 1)
        self.assertTrue("New draft waiting for approval" in outbox[-1]["Subject"])
        self.assertTrue(name in outbox[-1]["Subject"])

        # as chair of WG, we should see approval button
        self.client.login(remote_user="marschairman")

        r = self.client.get(status_url)
        self.assertEquals(r.status_code, 200)
        q = PyQuery(r.content)
        approve_submit = q('input[type=submit][value*="Approve"]')
        self.assertEquals(len(approve_submit), 1)

        # approve submission
        mailbox_before = len(outbox)
        approve_url = approve_submit.parents("form").attr("action")
        r = self.client.post(approve_url, dict())
        self.assertEquals(r.status_code, 302)

        draft = Document.objects.get(docalias__name=name)
        self.assertEquals(draft.rev, rev)
        new_revision = draft.latest_event()
        self.assertEquals(draft.group.acronym, "mars")
        self.assertEquals(new_revision.type, "new_revision")
        self.assertEquals(new_revision.by.name, "Test Name")
        self.assertTrue(not os.path.exists(os.path.join(self.staging_dir, u"%s-%s.txt" % (name, rev))))
        self.assertTrue(os.path.exists(os.path.join(self.repository_dir, u"%s-%s.txt" % (name, rev))))
        self.assertEquals(draft.type_id, "draft")
        self.assertEquals(draft.stream_id, "ietf")
        self.assertTrue(draft.expires >= datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE - 1))
        self.assertEquals(draft.get_state("draft-stream-%s" % draft.stream_id).slug, "wg-doc")
        self.assertEquals(draft.authors.count(), 1)
        self.assertEquals(draft.authors.all()[0].get_name(), "Test Name")
        self.assertEquals(draft.authors.all()[0].address, "testname@example.com")
        self.assertEquals(len(outbox), mailbox_before + 2)
        self.assertTrue((u"I-D Action: %s" % name) in outbox[-2]["Subject"])
        self.assertTrue("Test Name" in unicode(outbox[-2]))
        self.assertTrue("New Version Notification" in outbox[-1]["Subject"])
        self.assertTrue(name in unicode(outbox[-1]))
        self.assertTrue("mars" in unicode(outbox[-1]))

    def test_submit_existing(self):
        # submit new revision of existing -> supply submitter info -> confirm
        draft = make_test_data()

        # pretend IANA reviewed it
        draft.set_state(State.objects.get(used=True, type="draft-iana-review", slug="not-ok"))

        # pretend it was approved to check that we notify the RFC Editor
        e = DocEvent(type="iesg_approved", doc=draft)
        e.time = draft.time
        e.by = Person.objects.get(name="(System)")
        e.desc = "The IESG approved the document"
        e.save()

        # make a discuss to see if the AD gets an email
        ballot_position = BallotPositionDocEvent()
        ballot_position.ballot = draft.latest_event(BallotDocEvent, type="created_ballot")
        ballot_position.pos_id = "discuss"
        ballot_position.type = "changed_ballot_position"
        ballot_position.doc = draft
        ballot_position.ad = ballot_position.by = Person.objects.get(user__username="ad2")
        ballot_position.save()

        name = draft.name
        rev = "%02d" % (int(draft.rev) + 1)

        # write the old draft in a file so we can check it's moved away
        old_rev = draft.rev
        with open(os.path.join(self.repository_dir, "%s-%s.txt" % (name, old_rev)), 'w') as f:
            f.write("a" * 2000)

        supply_submitter_url = self.do_submission(name, rev)

        # supply submitter info, then we get a confirmation email
        mailbox_before = len(outbox)
        r = self.supply_submitter(name, supply_submitter_url)

        self.assertEquals(r.status_code, 200)
        self.assertTrue("Your submission is pending email authentication" in r.content)

        self.assertEquals(len(outbox), mailbox_before + 1)
        confirmation = outbox[-1]
        self.assertTrue("Confirmation for" in confirmation["Subject"])
        self.assertTrue(name in confirmation["Subject"])

        # dig out confirmation link
        msg = confirmation.get_payload(decode=True)
        line_start = "Confirmation URL:"
        self.assertTrue(line_start in msg)
        confirm_url = None
        for line in msg.split("\n"):
            if line.startswith(line_start):
                confirm_url = line[len(line_start):].strip()

        # go to confirm page
        r = self.client.get(confirm_url)
        q = PyQuery(r.content)
        self.assertEquals(len(q('input[type=submit][value=Auto-Post]')), 1)

        # confirm
        mailbox_before = len(outbox)
        r = self.client.post(confirm_url)
        self.assertEquals(r.status_code, 200)
        self.assertTrue('Authorization key accepted' in r.content)

        draft = Document.objects.get(docalias__name=name)
        self.assertEquals(draft.rev, rev)
        self.assertEquals(draft.group.acronym, name.split("-")[2])
        self.assertEquals(draft.docevent_set.all()[1].type, "new_revision")
        self.assertEquals(draft.docevent_set.all()[1].by.name, "Test Name")
        self.assertTrue(not os.path.exists(os.path.join(self.repository_dir, "%s-%s.txt" % (name, old_rev))))
        self.assertTrue(os.path.exists(os.path.join(self.archive_dir, "%s-%s.txt" % (name, old_rev))))
        self.assertTrue(not os.path.exists(os.path.join(self.staging_dir, u"%s-%s.txt" % (name, rev))))
        self.assertTrue(os.path.exists(os.path.join(self.repository_dir, u"%s-%s.txt" % (name, rev))))
        self.assertEquals(draft.type_id, "draft")
        self.assertEquals(draft.stream_id, "ietf")
        self.assertEquals(draft.get_state_slug("draft-stream-%s" % draft.stream_id), "wg-doc")
        self.assertEquals(draft.get_state_slug("draft-iana-review"), "changed")
        self.assertEquals(draft.authors.count(), 1)
        self.assertEquals(draft.authors.all()[0].get_name(), "Test Name")
        self.assertEquals(draft.authors.all()[0].address, "testname@example.com")
        self.assertEquals(len(outbox), mailbox_before + 3)
        self.assertTrue((u"I-D Action: %s" % name) in outbox[-3]["Subject"])
        self.assertTrue((u"I-D Action: %s" % name) in draft.message_set.order_by("-time")[0].subject)
        self.assertTrue("Test Name" in unicode(outbox[-3]))
        self.assertTrue("New Version Notification" in outbox[-2]["Subject"])
        self.assertTrue(name in unicode(outbox[-2]))
        self.assertTrue("mars" in unicode(outbox[-2]))
        self.assertTrue(draft.ad.role_email("ad").address in unicode(outbox[-2]))
        self.assertTrue(ballot_position.ad.role_email("ad").address in unicode(outbox[-2]))
        self.assertTrue("New Version Notification" in outbox[-1]["Subject"])
        self.assertTrue(name in unicode(outbox[-1]))
        self.assertTrue("mars" in unicode(outbox[-1]))

    def test_submit_new_wg_with_dash(self):
        draft = make_test_data()

        group = Group.objects.create(acronym="mars-special", name="Mars Special", type_id="wg", state_id="active")

        name = "draft-ietf-%s-testing-tests" % group.acronym

        self.do_submission(name, "00")

        self.assertEquals(IdSubmissionDetail.objects.get(filename=name).group_acronym.acronym, group.acronym)

    def test_submit_new_irtf(self):
        draft = make_test_data()

        group = Group.objects.create(acronym="saturnrg", name="Saturn", type_id="rg", state_id="active")

        name = "draft-irtf-%s-testing-tests" % group.acronym

        self.do_submission(name, "00")

        self.assertEquals(IdSubmissionDetail.objects.get(filename=name).group_acronym.acronym, group.acronym)
        self.assertEquals(IdSubmissionDetail.objects.get(filename=name).group_acronym.type_id, group.type_id)

    def test_submit_new_iab(self):
        draft = make_test_data()

        name = "draft-iab-testing-tests"

        self.do_submission(name, "00")

        self.assertEquals(IdSubmissionDetail.objects.get(filename=name).group_acronym.acronym, "iab")

    def test_cancel_submission(self):
        # submit -> cancel
        draft = make_test_data()

        name = "draft-ietf-mars-testing-tests"
        rev = "00"

        supply_submitter_url = self.do_submission(name, rev)

        # check we got cancel button
        r = self.client.get(supply_submitter_url)
        self.assertEquals(r.status_code, 200)
        q = PyQuery(r.content)
        cancel_submission = q('input[type=submit][value*="Cancel"]')
        self.assertEquals(len(cancel_submission), 1)

        cancel_url = cancel_submission.parents("form").attr("action")

        # cancel
        r = self.client.post(cancel_url)
        self.assertTrue(not os.path.exists(os.path.join(self.staging_dir, u"%s-%s.txt" % (name, rev))))

    def test_edit_submission(self):
        # submit -> edit
        draft = make_test_data()

        name = "draft-ietf-mars-testing-tests"
        rev = "00"

        supply_submitter_url = self.do_submission(name, rev)

        # check we got edit button
        r = self.client.get(supply_submitter_url)
        self.assertEquals(r.status_code, 200)
        q = PyQuery(r.content)
        self.assertEquals(len(q('input[type=submit][value*="Adjust"]')), 1)

        # go to edit, we do this by posting, slightly weird
        r = self.client.post(supply_submitter_url)
        self.assertEquals(r.status_code, 302)
        edit_url = r['Location']

        # check page
        r = self.client.get(edit_url)
        self.assertEquals(r.status_code, 200)
        q = PyQuery(r.content)
        self.assertEquals(len(q('input[name=title]')), 1)

        # edit
        mailbox_before = len(outbox)
        creation_date = datetime.date.today() - datetime.timedelta(days=-3)
        r = self.client.post(edit_url,
                             dict(title="some title",
                                  version="00",
                                  creation_date=creation_date.strftime("%Y-%m-%d"),
                                  abstract="some abstract",
                                  pages="123",
                                  name="Some Random Test Person",
                                  email="random@example.com",
                                  comments="no comments",
                                  name_0="Person 1",
                                  email_0="person1@example.com",
                                  name_1="Person 2",
                                  email_1="person2@example.com",
                                  ))
        self.assertEquals(r.status_code, 302)

        submission = IdSubmissionDetail.objects.get(filename=name)
        self.assertEquals(submission.id_document_name, "some title")
        self.assertEquals(submission.creation_date, creation_date)
        self.assertEquals(submission.abstract, "some abstract")
        self.assertEquals(submission.txt_page_count, 123)
        self.assertEquals(submission.comment_to_sec, "no comments")

        authors = submission.tempidauthors_set
        self.assertEquals(authors.count(), 3)
        # first one is submitter
        self.assertEquals(authors.get(author_order=0).first_name, "Some Random Test Person")
        self.assertEquals(authors.get(author_order=0).email_address, "random@example.com")
        self.assertEquals(authors.get(author_order=1).first_name, "Person 1")
        self.assertEquals(authors.get(author_order=1).email_address, "person1@example.com")
        self.assertEquals(authors.get(author_order=2).first_name, "Person 2")
        self.assertEquals(authors.get(author_order=2).email_address, "person2@example.com")

        self.assertEquals(len(outbox), mailbox_before + 1)
        self.assertTrue("Manual Post Requested" in outbox[-1]["Subject"])
        self.assertTrue(name in outbox[-1]["Subject"])

    def test_request_full_url(self):
        # submit -> request full URL to be sent
        draft = make_test_data()

        name = "draft-ietf-mars-testing-tests"
        rev = "00"

        self.do_submission(name, rev)

        submission = IdSubmissionDetail.objects.get(filename=name)
        url = urlreverse('draft_status', kwargs=dict(submission_id=submission.submission_id))

        # check we got request full URL button
        r = self.client.get(url)
        self.assertEquals(r.status_code, 200)
        q = PyQuery(r.content)
        request_button = q('input[type=submit][value*="Request full access"]')
        self.assertEquals(len(request_button), 1)

        request_url = request_button.parents("form").attr("action")

        # request URL to be sent
        mailbox_before = len(outbox)
        r = self.client.post(request_url)
        self.assertEquals(r.status_code, 200)

        self.assertEquals(len(outbox), mailbox_before + 1)
        self.assertTrue("Full URL for managing submission" in outbox[-1]["Subject"])
        self.assertTrue(name in outbox[-1]["Subject"])

class ApprovalsTestCase(django.test.TestCase):
    fixtures = ['names', 'idsubmissionstatus']

    def test_approvals(self):
        make_test_data()

        url = urlreverse('submit_approvals')
        self.client.login(remote_user="marschairman")

        from ietf.submit.views import POSTED, INITIAL_VERSION_APPROVAL_REQUESTED

        Preapproval.objects.create(name="draft-ietf-mars-foo", by=Person.objects.get(user__username="marschairman"))
        Preapproval.objects.create(name="draft-ietf-mars-baz", by=Person.objects.get(user__username="marschairman"))

        IdSubmissionDetail.objects.create(filename="draft-ietf-mars-foo",
                                          group_acronym_id=Group.objects.get(acronym="mars").pk,
                                          submission_date=datetime.date.today(),
                                          revision="00",
                                          status_id=POSTED)
        IdSubmissionDetail.objects.create(filename="draft-ietf-mars-bar",
                                          group_acronym_id=Group.objects.get(acronym="mars").pk,
                                          submission_date=datetime.date.today(),
                                          revision="00",
                                          status_id=INITIAL_VERSION_APPROVAL_REQUESTED)

        # get
        r = self.client.get(url)
        self.assertEquals(r.status_code, 200)
        q = PyQuery(r.content)

        self.assertEquals(len(q('.approvals a:contains("draft-ietf-mars-foo")')), 0)
        self.assertEquals(len(q('.approvals a:contains("draft-ietf-mars-bar")')), 1)
        self.assertEquals(len(q('.preapprovals td:contains("draft-ietf-mars-foo")')), 0)
        self.assertEquals(len(q('.preapprovals td:contains("draft-ietf-mars-baz")')), 1)
        self.assertEquals(len(q('.recently-approved a:contains("draft-ietf-mars-foo")')), 1)

    def test_add_preapproval(self):
        make_test_data()

        url = urlreverse('submit_add_preapproval')
        login_testing_unauthorized(self, "marschairman", url)

        # get
        r = self.client.get(url)
        self.assertEquals(r.status_code, 200)
        q = PyQuery(r.content)
        self.assertEquals(len(q('input[type=submit]')), 1)

        # faulty post
        r = self.client.post(url, dict(name="draft-test-nonexistingwg-something"))
        self.assertEquals(r.status_code, 200)
        self.assertTrue("errorlist" in r.content)

        # add
        name = "draft-ietf-mars-foo"
        r = self.client.post(url, dict(name=name))
        self.assertEquals(r.status_code, 302)

        self.assertEquals(len(Preapproval.objects.filter(name=name)), 1)

    def test_cancel_preapproval(self):
        make_test_data()

        preapproval = Preapproval.objects.create(name="draft-ietf-mars-foo", by=Person.objects.get(user__username="marschairman"))

        url = urlreverse('submit_cancel_preapproval', kwargs=dict(preapproval_id=preapproval.pk))
        login_testing_unauthorized(self, "marschairman", url)

        # get
        r = self.client.get(url)
        self.assertEquals(r.status_code, 200)
        q = PyQuery(r.content)
        self.assertEquals(len(q('input[type=submit]')), 1)

        # cancel
        r = self.client.post(url, dict(action="cancel"))
        self.assertEquals(r.status_code, 302)

        self.assertEquals(len(Preapproval.objects.filter(name=preapproval.name)), 0)


import gzip
import json
import re
from pprint import pprint
obj = []
pattern = r'\[\[Category:.+\]\]'
repattern = re.compile(pattern)

with gzip.open('jawiki-country.json.gz', 'rt', 'utf-8') as f:
    for i, line in enumerate(f):
        obj.append(json.loads(line))
        if(obj[i]['title'] == 'イギリス'):
            england  = obj[i]['text']

matchList = repattern.findall(england)
if matchList:
    pprint(matchList)


from django.urls import path
from . import views

app_name = 'project'
urlpatterns = [
    path('', views.Project_List.as_view(), name='index'),
    path('<int:pk>', views.Project_DetailView.as_view(), name='detail'),
    path('create/', views.Create_Project.as_view(), name='create'),
    path('update/<int:pk>/', views.Project_UpdateView.as_view(), name='update'),
    path('delete/<int:pk>/', views.Project_DeleteView.as_view(), name='delete'),
    path('upload/<int:pk>/', views.model_form_upload, name='upload'),
    path('document/<int:pk>/delete/', views.document_delete, name='doc_delete'),
    ]


import cv2 as cv
import csv
from datetime import datetime
import time

# The purpose of this function is to scan qr code.....
def scan():
    timeout = 100             # seconds  # to stop scanning after 10 seconds of inactivity
    triggered_time = time.time()
    uid = ""
    scanned = False
    cap = cv.VideoCapture(0)
    detector = cv.QRCodeDetector()
    print("Reading qr code using raspberry pi")

    while scanned == False:
        if (time.time()<triggered_time+timeout):
            isTrue, frame = cap.read()
            data,bbox,retr = detector.detectAndDecode(frame)
            cv.imshow("video",frame)
            if bbox is not None:
                if data:
                    print("Data found "+data)
                    uid = data
                    scanned=True
                    cap.release()
                    cv.destroyAllWindows()
                    return uid
            if cv.waitKey(20) & 0xFF == ord('d'):
                break
        else:
            return

# the purpose of this function is to change the encoding of the rows from csv file from utf-8 to ascii..
def convert_row( row ):
    row_dict = {}
    for key, value in row.items():
        keyAscii = key.encode('ascii', 'ignore' ).decode()
        valueAscii = value.encode('ascii','ignore').decode()
        row_dict[ keyAscii ] = valueAscii
    return row_dict

# The purpose of this function is to verify the scanned UID with the existing database..
def verify(uid):
    details = {}
    with open("database.csv",mode="r") as database:
        reader = csv.DictReader(database)
        for row in reader:
            row  = convert_row(row)
            if (row['uid'] == uid):
                details['name'] = row['name']
                details['uid'] = uid
                details['roll no'] = row['roll_no']
                details['email'] = row['email']
                details['verification status'] = True
                return details
        else:
            details['verification status'] = False

    return details

# The purpose of this function is to detect the face and store the image in the current working directory..
def face_detect():
    haar_cascades = cv.CascadeClassifier("haar_cascades.xml")
    # The purpose of this function is to detect any faces that are appearing in front of the camera...
    def detect_face(img):
        gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
        face_rect = haar_cascades.detectMultiScale(gray,scaleFactor = 1.1, minNeighbors = 10)
        if len(face_rect) == 1:
            return True
        return False

    video = cv.VideoCapture(0)
    count = 0
    while count != 2:
        isTrue, frames = video.read()
        cv.imshow("video",frames)
        if (detect_face(frames)):
            time.sleep(0.5)
            count += 1    # here i'm waiting for the next to frames to get a clear image without any noises..
            if (count == 2):
                cv.imwrite("DetectedImage.jpg",frames)  # saving the image....
                return (True,"DetectedImage.jpg")   # It return true after the successful detection of face detection
                #returning image location also for email attachment
        if cv.waitKey(20) & 0xFF == ord('d'):
            break
    video.release()
    video.destroyAllWindows()

# The purpose of this function is to get the current date and time.....
def getDateAndTime():
    today = datetime.now()
    today = today.strftime("%d/%m/%Y %H:%M:%S")
    date_time = {'date':today.split(' ')[0],'time': today.split(" ")[1]}
    # print(date_time)
    return date_time

# The purpose of this function is to log the attendance in the separate excel sheet locally...
def logInTime(details):
    with open("log.csv", mode = "a", newline="\n") as file:
        keys = ['date','name','status','uid','roll no','in time','out time']
        writer = csv.DictWriter(file,keys,delimiter = ",")
        # assuming that the file already has the headers so I'm leaving the part of assigning them..
        dateAndTime = getDateAndTime()
        date = dateAndTime['date']
        time_now = dateAndTime['time']
        values = {'date':date,'name':details['name'],'status':'in','uid':details['uid'],'roll no': details['roll no'],'in time':time_now,'out time':""}
        writer.writerow(values)
        return (date,time_now)       #returning entry time and date for email use

# The purpose of this function is to update the status and assign out time for the user...
def logOutTime(uid):
    temp = []  # temp array to copy the data and rewriting them in the same file with the updation of out time....
    with open('log.csv', mode='r') as file:
        reader = csv.DictReader(file)
        for row in reader:
            if ((row['status'] == 'in') & (row['uid'] == uid)):
                row['status'] = 'out'
                dateAndTime = getDateAndTime()
                date = dateAndTime['date']
                time_now = dateAndTime['time']
                row['out time'] = time_now
                temp.append(row)

            else:
                temp.append(row)
    with open("log.csv",mode="w", newline="\n") as file:
        keys = ['date','name','status','uid','roll no','in time','out time']
        writer = csv.DictWriter(file, fieldnames=keys, delimiter = ",")
        writer.writeheader()
        writer.writerows(temp)
    return(date,time_now)       #returning exit time and date for email use

def check_status(uid):
    with open('log.csv', mode='r') as file:
        ct = 0
        reader = csv.DictReader(file)
        for row in reader:
            if row['uid'] == uid:
                ct += 1
                if row['status'] == 'in':
                    return True

        else:
            return False

# read data continuously from Ultrasonic sensor
# once the distance becomes less trigger scan function
# msg in lcd
# if qr code is scanned successfully then verify the qr code
# msg in lcd
# After verification take the photo of the user
# msg in lcd
# log in time in the csv file if the user enters the club for the first time..
# msg in lcd
# send mail
# log the out time in the csv file once the user leaves the club
# msg in lcd
# send mail

# Main code


from typing import Callable, Iterable, List, Optional, Protocol, Sequence, Tuple, Union
import manim as mn
import numpy as np

PointType = Union[Sequence[float], np.ndarray]
PointTransformFunction = Callable[[PointType], PointType]

class SpaceManager(Protocol):

  def get_mobjects(self) -> List[mn.Mobject]:
    ...

  def anime_apply_function_to_plane(
      self, func: PointTransformFunction) -> List[mn.Animation]:
    ...

class Basic2DSpaceManager:
  background_plane: mn.NumberPlane
  plane: mn.NumberPlane

  def __init__(self,
               background_plane: Optional[mn.NumberPlane] = None,
               plane: Optional[mn.NumberPlane] = None):
    if background_plane is None:
      background_plane = mn.NumberPlane(
          color=mn.GRAY,
          axis_config={
              'color': mn.GRAY,
          },
          background_line_style={
              'stroke_color': mn.GRAY,
              'stroke_width': 1,
          },
      )
      background_plane.add_coordinates()

    if plane is None:
      plane = mn.NumberPlane(
          x_range=np.array([-10, 10, 1.0]),
          y_range=np.array([-10, 10, 1.0]),
          faded_line_ratio=1,
      )

    self.background_plane = background_plane
    self.plane = plane

  def get_mobjects(self) -> List[mn.Mobject]:
    return [
        self.background_plane,
        self.plane,
    ]

  def anime_apply_function_to_plane(
      self, func: PointTransformFunction) -> List[mn.Animation]:
    new_plane = self.plane.copy()
    new_plane.apply_function(func)
    return [mn.Transform(self.plane, new_plane)]

class Basic3DSpaceManager:
  background_space: mn.ThreeDAxes

  def __init__(self, background_space: Optional[mn.ThreeDAxes] = None):
    if background_space is None:
      background_space = mn.ThreeDAxes(
          num_axis_pieces=1,
          axis_config={
              'color': mn.GRAY,
              'unit_size': 1,
              'numbers_with_elongated_ticks': [0, 1, 2],
              'stroke_width': 2,
          },
      )
      background_space.add_coordinates()

    self.background_space = background_space

  def get_mobjects(self) -> List[mn.Mobject]:
    return [
        self.background_space,
    ]

  def anime_apply_function_to_plane(
      self, func: PointTransformFunction) -> List[mn.Animation]:
    _ = func
    return []

class LabelManager(Protocol):

  def get_label(self) -> List[mn.Mobject]:
    ...

  def anime_apply_matrix(
      self,
      matrix: np.ndarray,
      matrix_display: Iterable | None = None,
  ) -> Tuple[List[mn.Animation], List[mn.Animation]]:
    '''return: (create_matrix_animes, apply_matrix_animes)
    '''

class Label2DManager:
  xy_label: mn.Matrix

  def __init__(self, label: mn.Matrix | None = None):
    if label is None:
      label = mn.Matrix(
          [['x'], ['y']],
          left_bracket='(',
          right_bracket=')',
      )
    self.xy_label = label
    self.xy_label.to_corner(mn.RIGHT + mn.UP)

  def get_label(self):
    return [self.xy_label]

  def anime_apply_matrix(self,
                         matrix: np.ndarray,
                         matrix_display: Iterable | None = None):
    matrix_mobject = mn.Matrix(
        matrix_display if matrix_display else matrix,
        left_bracket='(',
        right_bracket=')',
    ).next_to(self.xy_label, mn.LEFT)
    create_anime = mn.Write(matrix_mobject)
    created_label = mn.Group(matrix_mobject, self.xy_label)
    apply_anime = mn.Transform(created_label, self.xy_label)
    self.xy_label = created_label
    return [create_anime], [apply_anime]

class Label3DManager:
  xyz_label: mn.Matrix
  camera_inv_matrix: np.ndarray

  def __init__(self,
               camera_rotation_matrix: np.ndarray,
               label: mn.Matrix | None = None):
    self.camera_inv_matrix = np.linalg.inv(camera_rotation_matrix)
    if label is None:
      label = mn.Matrix(
          [['x'], ['y'], ['z']],
          left_bracket='(',
          right_bracket=')',
      )
    self.xyz_label = label
    self.xyz_label.to_corner(mn.RIGHT + mn.UP)
    self.xyz_label.apply_matrix(self.camera_inv_matrix)

  def get_label(self):
    return [self.xyz_label]

  def anime_apply_matrix(self,
                         matrix: np.ndarray,
                         matrix_display: Iterable | None = None):
    matrix_mobject = mn.Matrix(
        matrix_display if matrix_display else matrix,
        left_bracket='(',
        right_bracket=')',
    )
    fake_label = self.xyz_label.copy()
    fake_label.apply_matrix(np.linalg.inv(self.camera_inv_matrix))
    matrix_mobject.next_to(fake_label, mn.LEFT)
    matrix_mobject.apply_matrix(self.camera_inv_matrix)
    # matrix_mobject.next_to(self.xyz_label, self.camera_inv_matrix @ mn.LEFT)
    create_anime = mn.Create(matrix_mobject)

    created_label = mn.Group(matrix_mobject, self.xyz_label)
    apply_anime = mn.Transform(created_label, self.xyz_label)
    self.xyz_label = created_label

    return [create_anime], [apply_anime]

class LinearTransformManager:
  space_manager: SpaceManager
  moving_vectors: List[mn.Vector] = []
  transformable_mobjects: List[mn.Mobject] = []

  def __init__(self, dimension: int):
    if dimension == 2:
      self.space_manager = Basic2DSpaceManager()
    elif dimension == 3:
      self.space_manager = Basic3DSpaceManager()
    else:
      raise ValueError('Dimension must be 2 or 3')

  def setup(self) -> List[mn.Mobject]:
    return self.space_manager.get_mobjects()

  def add_vector(self, vector: List | np.ndarray, color=mn.RED):
    v = mn.Vector(vector, color=color)
    self.moving_vectors.append(v)
    return v

  def add_transformable_mobject(self, mobject: mn.Mobject):
    self.transformable_mobjects.append(mobject)
    return mobject

  def anime_apply_matrix(self, matrix: np.ndarray):
    f = self.get_matrix_apply_function(matrix)
    animes = [
        *self.anime_apply_function_to_plane(f),
        *self.anime_apply_function_to_vector(f),
        *self.anime_apply_function_to_moving_mobjects(f),
    ]
    return animes

  def anime_apply_function_to_vector(self, func: PointTransformFunction):
    new_vectors = [
        mn.Vector(func(v.get_end()), color=v.color) for v in self.moving_vectors
    ]
    return [
        mn.Transform(old_v, new_v)
        for (old_v, new_v) in zip(self.moving_vectors, new_vectors)
    ]

  def anime_apply_function_to_plane(self, func: PointTransformFunction):
    return self.space_manager.anime_apply_function_to_plane(func)

  def anime_apply_function_to_moving_mobjects(self,
                                              func: PointTransformFunction):
    return [
        mn.ApplyPointwiseFunction(func, mobj)
        for mobj in self.transformable_mobjects
    ]

  def get_matrix_apply_function(self,
                                matrix: np.ndarray) -> PointTransformFunction:
    if matrix.shape == (2, 2):
      new_matrix = np.identity(3)
      new_matrix[:2, :2] = matrix
      matrix = new_matrix

    if matrix.shape == (3, 3):
      return lambda p: matrix @ p

    if matrix.shape == (4, 4):

      def func(p):
        point_4d = np.append(p, 1)
        point_4d = matrix @ point_4d
        return np.array(point_4d[:3]) / point_4d[3]

      return func

    raise ValueError('Matrix has bad dimensions')

class BasicLinearSpaceScene(mn.ThreeDScene):

  mobj_manager: LinearTransformManager
  label_manager: LabelManager

  def setup(self):
    self.mobj_manager = LinearTransformManager(2)
    default_mobj = self.mobj_manager.setup()
    self.add(*default_mobj)
    self.label_manager = Label2DManager()
    # label_group = mn.VGroup(label)
    self.add(*self.label_manager.get_label())

  def play_2d_to_3d(self):
    '''animate 2d space to 3d space, moving xy plane to w = 1
    '''
    old_2d_space = self.mobj_manager.space_manager
    old_2d_label = self.label_manager
    assert isinstance(old_2d_space, Basic2DSpaceManager)
    assert isinstance(old_2d_label, Label2DManager)

    self.mobj_manager.space_manager = Basic3DSpaceManager()
    self.mobj_manager.add_transformable_mobject(old_2d_space.plane)
    new_axis_animes = [
        mn.Create(axis_mobj)
        for axis_mobj in self.mobj_manager.space_manager.get_mobjects()
    ]

    f = self.mobj_manager.get_matrix_apply_function(
        np.array([
            [1, 0, 0, 0],
            [0, 1, 0, 0],
            [0, 0, 1, 1],
            [0, 0, 0, 1],
        ]))
    animes = [
        *new_axis_animes,
        mn.FadeOut(old_2d_space.background_plane),
        *self.mobj_manager.anime_apply_function_to_vector(f),
        *self.mobj_manager.anime_apply_function_to_moving_mobjects(f),
    ]
    self.move_camera(
        phi=2 * mn.PI / 5, theta=-mn.PI / 3, run_time=2, added_anims=animes)

    self.label_manager = Label3DManager(self.camera.get_rotation_matrix())
    new_xyz_label = self.label_manager.xyz_label

    self.play(mn.Transform(old_2d_label.xy_label, new_xyz_label), run_time=1)
    self.label_manager.xyz_label = old_2d_label.xy_label

  def add_vector(self, vector: List | np.ndarray, color=mn.RED):
    vector_mobjs = self.mobj_manager.add_vector(vector, color=color)
    self.add(*vector_mobjs)

  def add_transformable_mobject(self, mobjects: mn.Mobject):
    res_mobjs = self.mobj_manager.add_transformable_mobject(mobjects)
    self.add(*res_mobjs)

  def apply_matrix(self,
                   matrix: np.ndarray,
                   matrix_display: Optional[Iterable] = None):
    '''play anime for applying matrix to mobjects

    1. create matrix label
    2. apply matrix to mobjects and combine matrix label
    '''
    (create_label_anime,
     apply_label_anime) = self.label_manager.anime_apply_matrix(
         matrix, matrix_display)

    # create matrix label
    self.play(*create_label_anime, run_time=0.5)
    self.wait(0.5)

    # apply matrix to mobjects and combine matrix label
    apply_matrix_animes = self.mobj_manager.anime_apply_matrix(matrix)
    self.play(
        *apply_matrix_animes,
        *apply_label_anime,
        run_time=0.5,
    )
    self.wait(0.5)

class OnOneLineWillStillOneLine(BasicLinearSpaceScene):
  '''图：在同一直线上的点，经过同一线性变换后还在同一直线上
  '''

  def add_vectors_on_line(self, line_fn: Callable[[int], int], start_x: int,
                          end_x: int, color: str):
    to_point = lambda x: [x, line_fn(x)]
    for x in range(start_x, end_x):
      self.add_vector(to_point(x), color=color)

    vec_line = mn.Line(
        start=[*to_point(-10), 0], end=[*to_point(10), 0], color=color)
    self.add_transformable_mobject(vec_line)

  def construct(self):
    self.add_vectors_on_line(lambda x: 2, -1, 3, mn.RED)
    self.add_vectors_on_line(lambda x: x - 2, -1, 3, mn.GREEN)

    matrix1 = np.array([[2, -1], [0, 1]])
    self.apply_matrix(matrix1)

    matrix2 = np.array([[1 / 2, 1 / 2], [-1 / 2, 1 / 2]])
    self.apply_matrix(matrix2)

    matrix3 = np.linalg.inv(matrix2 @ matrix1)
    self.apply_matrix(matrix3)

class SliceScaleRotateForOrigin(BasicLinearSpaceScene):
  '''动图：切边、伸缩、旋转以及其逆变换变回原样
  '''

  def construct(self):
    self.add_vector([1, 0], color=mn.RED)
    self.add_vector([0, 1], color=mn.GREEN)

    matrix1 = np.array([[1, 1], [0, 1]])
    self.apply_matrix(matrix1)
    self.apply_matrix(np.linalg.inv(matrix1))

    matrix2 = np.array([[2, 0], [0, 1 / 2]])
    self.apply_matrix(matrix2)
    self.apply_matrix(np.linalg.inv(matrix2))

    angle = np.pi / 3
    matrix3 = np.array([[np.sin(angle), -np.cos(angle)],
                        [np.cos(angle), np.sin(angle)]])
    self.apply_matrix(
        matrix3,
        matrix_display=[[r'\frac{\sqrt{3}}{2}', r'-\frac{1}{2}'],
                        [r'\frac{1}{2}', r'\frac{\sqrt{3}}{2}']])
    self.apply_matrix(
        np.linalg.inv(matrix3),
        matrix_display=[[r'\frac{\sqrt{3}}{2}', r'\frac{1}{2}'],
                        [r'-\frac{1}{2}', r'\frac{\sqrt{3}}{2}']])

class HomogeneousTransform(BasicLinearSpaceScene):
  '''图：三位坐标w=1平面，三角形
  '''

  def construct(self):
    # ax = mn.ThreeDAxes()
    # lab = ax.get_z_axis_label(mn.Tex('$z$-label'))
    # self.set_camera_orientation(phi=0, theta=-mn.PI / 2)
    triangle = mn.Polygon([-2, 0, 0], [2, 0, 0], [0, 2, 0], color=mn.RED)
    self.add_transformable_mobject(triangle)
    self.play_2d_to_3d()
    self.add_vector([0, 0, 1], color=mn.GREEN)
    self.apply_matrix(np.array([[1, 0, 1], [0, 1, 0], [0, 0, 1]]))
    self.apply_matrix(np.array([[1, 0, -1], [0, 1, -1], [0, 0, 1]]))
    self.apply_matrix(np.array([[1, 0, 0], [0, 1, 1], [0, 0, 1]]))

class SliceOnHomogeneousWithGraph(BasicLinearSpaceScene):
  '''图：还是三维空间上切变，平面上有图案
  '''

  def construct(self):
    circle = mn.Circle(
        radius=1, color=mn.RED).move_to([2, -2, 0]).set_fill(
            color=mn.RED_C, opacity=0.5)
    triangle = mn.Polygon([-2, 0, 0], [-1, 0, 0], [-2, 1, 0],
                          color=mn.GREEN).set_fill(
                              color=mn.GREEN_C, opacity=0.5)
    square = mn.Polygon([2, 2, 0], [2, 1, 0], [3, 1, 0], [3, 2, 0],
                        color=mn.BLUE).set_fill(
                            color=mn.BLUE_C, opacity=0.5)
    star = mn.Star(color=mn.PURPLE).move_to([-2, -2, 0]).set_fill(
        color=mn.PURPLE_C, opacity=0.5)
    self.add_transformable_mobject(circle)
    self.add_transformable_mobject(triangle)
    self.add_transformable_mobject(square)
    self.add_transformable_mobject(star)
    self.play_2d_to_3d()
    self.add_vector([0, 0, 1], color=mn.GREEN)
    self.apply_matrix(np.array([[1, 0, 1], [0, 1, 0], [0, 0, 1]]))
    self.apply_matrix(np.array([[1, 0, -1], [0, 1, -1], [0, 0, 1]]))
    self.apply_matrix(np.array([[1, 0, 0], [0, 1, 1], [0, 0, 1]]))


from django.db import models

class Player(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=200)

class Field(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=200)

class Match(models.Model):
    id = models.AutoField(primary_key=True)
    date_and_time = models.DateField(auto_now_add=True)
    player1 = models.ForeignKey(Player, related_name="player1")
    player2 = models.ForeignKey(Player, related_name="player2")
    player1_score = models.IntegerField(default=0)
    player2_score = models.IntegerField(default=0)
    field = models.ForeignKey(Field, related_name="field")


import pandas as pd
from datetime import datetime as dt
from pypdf import PdfReader

# TODO: Create another Receipt class to be inherited (in case of other receipts)

class SainsburysReceipt():

    def __init__(self, pdf_file):

        self._file = pdf_file

        self._content = None           # A list of PDF lines (Raw)
        self._filtered_content = None  # A list of strings for items
        self._order_id = None          # Order ID
        self._order_date = None        # Order Date
        self._quantities = None        # List of quantities for each item
        self._weights = None           # List of weights for each item
        self._names = None             # List of names for each item
        self._prices = None            # List of prices for each item

        self._item_df = None           # Pandas Dataframe of all orders

        self._parse_receipt()
        # Order ID and time
        self._find_order_id_time()
        # Order Items
        self._filter_content_to_items()
        self._find_items_info()
        self._process_item_info()

    def _parse_receipt(self):
        """
        Uses the PdfReader module to read and parse the receipts pdf into a list, each element
        representing a line in the receipt.
        """
        reader = PdfReader(self._file)

        pdf_content = []
        for page in reader.pages:
            text = page.extract_text()  # This returns a single string of everything on the pdf
            lines = text.split("\n")    # This creates a list for each line
            pdf_content.extend(lines)   # Extend it to the pdf_content list
        self._content = pdf_content

    def _find_order_id_time(self):
        """
        Uses the PdfReader module to read and parse the receipts pdf into a list, each element
        representing a line in the receipt.
        """

        for line in self._content:

            # Look for order ID by splitting by colon ":"
            if line.startswith("Your receipt for order: "):
                _, order_id = line.split(':')  # Split into ["Your receipt for order:", order_id]
                order_id = order_id.strip()    # Use strip to remove any leading/trailing whitespace

            # The time contains multiple colons. Therefore we look for the first colon only.
            if line.startswith("Slot time:"):
                first_colon_index = line.index(":")
                order_time = line[first_colon_index + 1:]
                order_time = order_time.strip()  # Use strip to remove any leading/trailing whitespace
                break

        # Convert the date string into a datetime object.
        # ----------
        # Split the time information into a two components [date (Thursday 3rd August 2023), time (9:00pm - 10:00pm)]
        order_date, order_hours = order_time.split(',')
        # Further split the date information into day, date, month and year
        day, date, month, year = order_date.split()
        # Remove the suffixes from order_date by removing last two characters (st, nd, rd, th)
        date = date[:-2]
        # Rejoin the date information into a single string, then convert it into a datetime object
        order_date = f"{day} {date} {month} {year}"
        order_date = dt.strptime(order_date, r'%A %d %B %Y')

        # Save permanently as attributes
        self._order_id = order_id
        self._order_date = order_date

    def _filter_content_to_items(self):
        """
        Remove unnecessary information within the receipt besides the orders. This is located between
        "Delivery summary" and "Order summary".
        """
        # The order starts after the line "Delivery summary" and ends after "Order summary".
        # Only retain whatever is in between.
        for index, line in enumerate(self._content):
            if line.startswith("Delivery summary"):
                start_index = index
            elif line.startswith("Order summary"):
                end_index = index

        self._filtered_content = self._content[start_index + 1: end_index]

    def _find_items_info(self):
        """
        With a filtered list (e.g. returned from find_orders(content_list)), decouple each line into
        the "Quantity", "Item" and "Price" of each Item.

        Logic:
            1. The "amount" of an item is either:
                - Quantity
                - Weight
            2. Item name starts with a capital letter. This works most of the time since quantities are
            numeric, sometimes with lowercase units such as kg, g etc.
            3. Prices are the numeric values occuring after £
            4. For long orders (multi-lines) check whether the £ symbol appears. If it does not, append it to the next line
        """

        # Initialize lists
        quantities = []
        weights = []
        names = []
        prices = []

        previous_line = ''         # In case a single item spans multiple rows. See logic below.
        previous_line_length = 0   # To adjust pound index in case of multi-line rows

        for order in self._filtered_content:

            # Find the index of the pound symbol. Everything after this is assumed to be the price.
            pound_index = order.rfind('£')

            # 1. If there is no pound symbol, pound_index will return -1. If this is the case, save the
            #    current line as a variable named "previous_line". As long as the pound symbol is not found,
            #    it will keep adding to 'previous_line'.
            # 2. Variable previous_line_length is to readjust for pound_index since the multi-line order
            #    is appended together, so the index where the pound occurs is:
            #               previous_line_length + current_line_pound_index
            if pound_index == -1:
                previous_line = previous_line + order
                previous_line_length = len(order)
                continue   # Skip this loop

            # Whenever the pound_symbol is found, reset variables to an empty string to prepare
            # for additional multi-line orders.
            else:
                # Aggregate multi-line order into a single string
                order = previous_line + order
                pound_index = previous_line_length + pound_index

                # Reset variables
                previous_line = ''
                previous_line_length = 0

                # Analyse each character within the string.
                for index, char in enumerate(order):

                    # Find the index of the item name. Item name is assumed to be the first capital letter
                    # (units are usually in ml, kg etc. that are not uppercase)
                    if char.isupper():
                        item_index = index
                        break

                # Using indices, categorize the information with their respective rows
                amount = order[: item_index]
                name = order[item_index: pound_index - 1]
                price = order[pound_index + 1:]

                # Amount can either be quantity or weight. Store it as 'weight' if it ends with 'kg'.
                # Add other units in the future.
                if amount.endswith("kg"):
                    weight = amount
                    quantity = None
                else:
                    weight = None
                    quantity = int(amount)             # Type conversion here to prevent performing `int(None)``

                # Append to each list
                quantities.append(quantity)            # Quantity stored as integers
                weights.append(weight)                 # Weight stored as strings
                names.append(name)                     # Item names stored as strings
                prices.append(float(price))            # Price stored as floats

        self._quantities = quantities
        self._weights = weights
        self._names = names
        self._prices = prices

    def _process_item_info(self):
        """
        With the quantities, weights, names and prices of each item, process the data such that each item
        always take one row (an item with a quantity of two will become two items of one quantity each).
        This is to ensure each item can be split separately.
        """

        # For rows with a quantity above one (quantity = n), split this into
        # n rows and divide the price by n to obtain individual prices
        # ----------

        # New lists to store the decoupled information
        decoupled_weights = []
        decoupled_items = []
        decoupled_prices = []

        for quantity, weight, item, price in zip(self._quantities, self._weights, self._names, self._prices):
            # When quantity exceeds 1, split that order into individual items
            if (quantity) and (quantity > 1):
                decoupled_weights.extend([weight] * quantity)
                decoupled_items.extend([item] * quantity)
                # Prices are summed so these are divided by quantity
                decoupled_prices.extend([price/quantity] * quantity)

            # If quantity is one then just append it normally
            else:
                decoupled_weights.append(weight)
                decoupled_items.append(item)
                decoupled_prices.append(price)

        # Convert to dataframe as a viewable form
        self._item_df = pd.DataFrame(
            {
                # Append the order_id (which is equal throughout) for referencing other datatables
                'order_id': [self._order_id] * len(decoupled_items),
                'weight': decoupled_weights,
                'item_name': decoupled_items,
                'price': decoupled_prices
            }
        )

    @property
    def order_id(self):
        return self._order_id

    @property
    def order_date(self):
        return self._order_date

    @property
    def item_df(self):
        return self._item_df


from sqlalchemy.orm.session import Session
from flask import request, jsonify

# from sqlalchemy.exc import NoResultFound
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound

# from flask import current_app
from http import HTTPStatus
from werkzeug.exceptions import NotFound

from app.models.call_record_model import CallRecord
from app.configs.database import db
import ipdb

def get_record_by_id(call_record_id: int):
    session: Session = db.session
    base_query = session.query(CallRecord)

    # record = session.query(CallRecord).filter(CallRecord.id == call_record_id).first()
    # record = session.query(CallRecord).get(call_record_id)
    # record = base_query.filter_by(id=call_record_id).first()
    # record = base_query.filter_by(source=111111113).all()

    # if not record:
    #     return {"error": f"id {call_record_id} not found"}, HTTPStatus.NOT_FOUND

    # try:
    #     # record = base_query.filter_by(id=call_record_id).one()
    #     record = base_query.filter_by(source=111111113).one()
    # except NoResultFound:
    #     return {"error": f"id {call_record_id} not found"}, HTTPStatus.NOT_FOUND
    # except MultipleResultsFound:
    #     return {"error": f"multiple results found"}, HTTPStatus.OK
    try:
        record = base_query.filter_by(id=call_record_id).first_or_404(
            description="id not found"
        )
    except NotFound as e:
        return {"error": e.description}, HTTPStatus.NOT_FOUND

    return jsonify(record), HTTPStatus.OK

def get_records():
    session: Session = db.session
    base_query = session.query(CallRecord)

    page = request.args.get("page", 1, type=int)
    per_page = request.args.get("per_page", 3, type=int)

    source = request.args.get("source", type=int)
    destination = request.args.get("destination")

    query_params = dict(request.args)
    query_params.pop("page", None)
    query_params.pop("per_page", None)

    # 1. existe source
    # 2. existe destination
    # 3. existe tanto source quanto destination
    # request.args -> ImultableMultiDict
    # request.args.pop() -> nao consigo por ser imutavel
    if source or destination:
        records = base_query.filter_by(**query_params).order_by(CallRecord.id)
    else:
        records = base_query.order_by(CallRecord.id)

    records = records.paginate(page, per_page)

    return jsonify(records.items), HTTPStatus.OK

def create_record():
    data = request.get_json()

    record = CallRecord(**data)
    # print(record)

    db.session.add(record)
    db.session.commit()
    # print(record.__dict__)
    # ipdb.set_trace()

    # return record.serializer(), HTTPStatus.CREATED
    return jsonify(record), HTTPStatus.CREATED

def update_record(record_id: int):
    data = request.get_json()
    session: Session = db.session
    base_query = session.query(CallRecord)

    record = base_query.get(record_id)

    if not record:
        return {"error": "id not found"}, HTTPStatus.NOT_FOUND

    for key, value in data.items():
        setattr(record, key, value)

    print(record.chave_random)

    session.add(record)
    session.commit()

    return jsonify(record), HTTPStatus.OK

def delete_record(record_id: int):
    session: Session = db.session
    base_query = session.query(CallRecord)

    record = base_query.get(record_id)

    if not record:
        return {"error": "id not found"}, HTTPStatus.NOT_FOUND

    session.delete(record)
    session.commit()

    # return "", HTTPStatus.NO_CONTENT
    return jsonify(record), HTTPStatus.OK


__all__ = ['PrologixSocketResource']

import os
import numpy as np
import socket
import functools
from auspex.log import logger
from pyvisa.util import _converters, from_ascii_block, to_ascii_block, to_ieee_block, from_binary_block

class PrologixError(Exception):
    """Error interacting with the Prologix GPIB-ETHERNET controller."""

class PrologixSocketResource(object):
    """A resource representing a GPIB instrument controlled through a PrologixError
    GPIB-ETHERNET controller. Mimics the functionality of a pyVISA resource object.

    See http://prologix.biz/gpib-ethernet-controller.html for more details
    and a utility that will discover all prologix instruments on the network.

    Attributes:
        timeout: Timeout duration for TCP comms. Default 5s.
        write_termination: Character added to each outgoing message.
        read_termination: Character which denotes the end of a reponse message.
        idn_string: GPIB identification command. Defaults to '*IDN?'
        bufsize: Maximum amount of data to be received in one call, in bytes.
    """
    def __init__(self, ipaddr=None, gpib=None):
        super(PrologixSocketResource, self).__init__()
        if ipaddr is not None:
            self.ipaddr = ipaddr
        if gpib is not None:
            self.gpib = gpib
        self.sock = None
        self._timeout = 5
        self.read_termination = "\r\n"
        self.write_termination = "\r\n"
        self.idn_string = "*IDN?"
        self.bufsize = 4096

    @property
    def timeout(self):
        return self._timeout

    @timeout.setter
    def timeout(self, value):
        self._timeout = timeout
        if self.sock is not None:
            self.sock.settimeout(self._timeout)

    def connect(self, ipaddr=None, gpib=None):
        """Connect to a GPIB device through a Prologix GPIB-ETHERNET controller.
        box.

        Args:
            ipaddr: The IP address of the Prologix GPIB-ETHERNET.
            gpib: The GPIB address of the instrument to be controlled.
        Returns:
            None.
        """
        if ipaddr is not None:
            self.ipaddr = ipaddr
        if gpib is not None:
            self.gpib = gpib
        try:
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
                socket.IPPROTO_TCP)
            self.sock.settimeout(self._timeout)
            self.sock.connect((self.ipaddr, 1234)) #Prologix communicates on port 1234
        except socket.error as err:
            logger.error("Cannot open socket to Prologix at {0}: {1}".format(self.ipaddr,
                err.msg))
            raise PrologixError(self.ipaddr) from err
        self.sock.send(b"++ver\r\n")
        whoami = self.sock.recv(128).decode()
        if "Prologix" not in whoami:
            logger.error("The device at {0} does not appear to be a Prologix; got {1}.".format(self.ipaddr, whoami))
            raise PrologixError(whoami)
        self.sock.send(b"++mode 1\r\n") #set to controller mode
        self.sock.send(b"++auto 1\r\n") #enable read-after-write
        self._addr()
        self.sock.send(b"++clr\r\n")
        idn = self.query(self.idn_string)
        if idn == '':
            logger.error(("Did not receive response to GPIB command {0} " +
                "from GPIB device {1} on Prologix at {2}.").format(self.idn_string,
                self.gpib, self.ipaddr))
            raise PrologixError(idn)
        else:
            logger.debug(("Succesfully connected to device {0} at GPIB port {1} on" +
                " Prologix controller at {2}.").format(idn, self.gpib, self.ipaddr))

    def close(self):
        """Close the connection to the Prologix."""
        if self.sock is not None:
            self.sock.shutdown(socket.SHUT_RDWR)
            self.sock.close()

    def _addr(self):
        """Set PROLOGIX to address of instrument we want to control."""
        self.sock.send(('++addr %d\n' % self.gpib).encode())

    def read(self):
        """Read an ASCII value from the instrument.

        Args:
            None.
        Returns:
            The instrument data with termination character stripped.
        """
        self._addr()
        ans = self.sock.recv(self.bufsize).decode()
        return ans.rstrip(self.read_termination)

    def query(self, command):
        """Query instrument with ASCII command then read response.

        Args:
            command: Message to be sent to instrument.
        Returns:
            The instrument data with termination character stripped.
        """
        self._addr()
        self.sock.send((command + self.write_termination).encode())
        ans = self.sock.recv(self.bufsize).decode()
        return ans.rstrip(self.read_termination)

    def write(self, command):
        """Write a string message to device in ASCII format.

        Args:
            command: The message to be sent.
        Returns:
            The number of bytes in the message.
        """
        self._addr()
        self.sock.send((command + self.write_termination).encode())
        return len(command)

    def read_raw(self, bufsize=None):
        """Read bytes from instrument.

        Args:
            bufsize: Number of bytes to read from instrument. Defaults to resource
            bufsize if None.
        Returns:
            Instrument data. Nothing is stripped from response.
        """
        if bufsize is None:
            bufsize = self.bufsize
        self._addr()
        return self.socket.recv(bufsize)

    def write_raw(self, command):
        """Write a string message to device as raw bytes. No termination
        character is appended.

        Args:
            command: The message to be sent.
        Returns:
            The number of bytes in the message.
        """
        self._addr()
        self.sock.send(command)
        return len(command)

    def write_ascii_values(self, command, values, converter='f', separator=','):
        """Write a string message to device followed by values in ASCII format.

        Args:
            command: Message to be sent to device.
            values: Data to be written to device (as an iterable)
            converter: String format code to be used to convert values.
            separator: Separator between values -- separator.join(data).

        Returns:
            Total number of bytes sent to instrument.
        """
        ascii_vals = to_ascii_block(values, converter, separator)
        return self.write(command + ascii_vals + self.write_termination)

    def query_ascii_values(self, command, converter='f', separator=',',
        container=list, bufsize=None):
        """Write a string message to device and return values as iterable.

        Args:
            command: Message to be sent to device.
            values: Data to be written to device (as an interable)
            converter: String format code to be used to convert values.
            separator: Separator between values -- data.split(separator).
            container: Iterable type to use for output.
            bufsize: Number of bytes to read from instrument. Defaults to resource
            bufsize if None.
        Returns:
            Iterable of values converted from instrument response.
        """
        if bufsize is None:
            bufsize = self.bufsize
        ascii = self.query(command, bufsize=bufsize)
        return from_ascii_block(ascii, convereter, separator, container)

    def write_binary_values(self, command, values, datatype='f',
        is_big_endian=False):
        """Write a string message to device followed by values in binary IEEE
        format using a pyvisa utility function.)

        Args:
            command: String command sent to instrument.
            values: Data to be sent to instrument.
            datatype: Format string for single element.
            is_big_endian: Bool indicating endianness.
        Returns:
            Number of bytes written to instrument.
        """
        data = to_ieee_block(values, datatype=datatype, is_big_endian=is_big_endian)
        return self.write_raw(command.encode()+data)

    def query_binary_values(self, command, datatype='f', container=np.array,
        is_big_endian=False, bufsize=None):
        """Write a string message to device and read binary values, which are
        returned as iterable. Uses a pyvisa utility function.

        Args:
            command: String command sent to instrument.
            values: Data to be sent to instrument.
            datatype: Format string for single element.
            container: Iterable to return number of as.
            is_big_endian: Bool indicating endianness.

        Returns:
            Iterable of data values to be retuned
        """
        if bufsize is None:
            bufsize = self.bufsize
        self.write(command, bufsize=bufsize)
        block = self.read_raw()
        return from_binary_block(block, datatype=datatype,
            is_big_endian=is_big_endian, container=container)


# LeetCode
# Longest Subarray of 1's After Deleting One Element
# https://leetcode.com/problems/longest-subarray-of-1s-after-deleting-one-element/?envType=study-plan-v2&envId=leetcode-75

from typing import List

class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        left, right, k = 0, 0, 1
        for right in range(len(nums)):
            if nums[right] == 0:
                k -= 1
            if k < 0:
                if nums[left] == 0:
                    k += 1
                left += 1

        return right - left

# Test Cases
sol = Solution()
nums = [1,1,0,1]
print(sol.longestSubarray(nums)) # Output: 3

nums = [0,1,1,1,0,1,1,0,1]
print(sol.longestSubarray(nums)) # Output: 5

nums = [1,1,1]
print(sol.longestSubarray(nums)) # Output: 2

LeetCode/Sliding Window/Longest Subarray of 1's After Deleting One Element.py


from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt
from pathlib import Path
from PyQt5.QtWidgets import (
    QDialog,
    QPushButton,
    QMainWindow
)
from typing import (
    TYPE_CHECKING,
    Optional as O
)

from .ui_picker import Ui_GamePickerDialog
from ..constants import PATH_ICON

if TYPE_CHECKING:
    from ..gamelibrary import GameLibrary

class GamePicker(Ui_GamePickerDialog):
    dlg: QDialog
    game_lib: "GameLibrary"
    gpths: dict[str, Path]
    gpath: O[Path] = None

    def __init__(self, parent: QMainWindow, game_lib: "GameLibrary", gpths: dict[str, Path]):
        self.game_lib = game_lib
        self.gpths = gpths
        self.dlg = QDialog(parent)
        self.dlg.setWindowIcon(QIcon(PATH_ICON))
        self.dlg.setWindowFlags(self.dlg.windowFlags() | Qt.WindowFlags(
            Qt.FramelessWindowHint))
        self.setupUi(self.dlg)
        self.fill()
        self.dlg.exec()

    def fill(self):
        for title, pth in self.gpths.items():
            btn = QPushButton(self.scrollAreaContents)
            btn.setText(title)
            btn.clicked.connect(lambda *_, p=pth: self.startGame(p))
            self.vLayout_contents.addWidget(btn)

    def startGame(self, gpath: Path):
        self.gpath = gpath
        self.dlg.close()