from collections import defaultdict as dd
from bisect import bisect as bis, bisect_left as bis2

mod = 998244353
N = 1<<20
ti = 998243401 # (2^{-20} % mod)

def ri():
    return int(input())

def rl():
    return list(map(int, input().split()))

def digsum(n):
    ans = 0
    while n:
        ans += n % 10
        n //= 10
    return ans

def get_valid(L):
    masks = [0] * N
    n = len(L)
    cutoff = (n + 1) >> 1
    counts = [0] * 5
    xors   = [0] * 5

    def backtrack(i):
        if i == n:
            if max(counts) >= cutoff:
                mask = 0
                shift = 1
                for j in range(5):
                    mask += xors[j] * shift
                    shift <<= 4
                masks[mask] += 1
        else:
            for j in range(5):
                counts[j] += 1
                xors[j] ^= L[i]
                backtrack(i + 1)
                counts[j] -= 1
                xors[j] ^= L[i]

    backtrack(0)
    return masks

def fwht(a):
    """In-place Fast Walsh–Hadamard Transform of array a."""
    h = 1
    n = len(a)
    while h < n:
        for i in range(0, n, h * 2):
            for j in range(i, i + h):
                x = a[j]
                y = a[j + h]
                # a[j] = (x + y) % mod
                # a[j + h] = (x - y) % mod
                a[j] = x + y
                a[j + h] = x - y
        h *= 2
    # for i in range(n):
        # a[i] %= mod

# main
# pre-processing
n, q = rl()
ghosts = []
for _ in range(n):
    bitset = 0
    moves = set(input().split()[1:])
    if "spook" in moves:
        bitset |= 1
    if "hide" in moves:
        bitset |= 2
    if "creep" in moves:
        bitset |= 4
    if "float" in moves:
        bitset |= 8
    ghosts.append(bitset)
scores = rl()
def get_score(m):
    total_score = 0
    i = 0
    while m:
        total_score += scores[i] * (m&1)
        m >>= 1
        i = (i + 1) % 4
    return total_score

# brute force combinatorics (backtracking)
groups = dd(list)
for i in range(n):
    groups[digsum(i+1)].append(ghosts[i])
masks = [get_valid(L) for L in groups.values()]

# using walsh-hadamard in place
# storing final result in first
# array. Not using sqrt(2), so
# in the end, need to back out
# 2^20 (mod p)
for i in range(len(masks)):
    fwht(masks[i])

for i in range(1, len(masks)):
    for j in range(N):
        masks[0][j] = (masks[0][j] * masks[i][j]) % mod

fwht(masks[0])
for i in range(N):
    masks[0][i] = (masks[0][i] * ti) % mod

# filling sparse array of counts
# of possible scores
ways = dd(int)
for i in range(N):
    v = masks[0][i]
    if v != 0:
        ways[get_score(i)] += v

S = sorted(list(ways.keys()))
m = len(S)
partials = [0] * (m + 1)
for i in range(m):
    partials[i + 1] = partials[i] + ways[S[i]]

# process queries
for _ in range(q):
    a, b = rl()
    i = bis(S, a - 1)
    j = bis(S, b)
    print ((partials[j] - partials[i]) % mod)


import random
import pygame

from settings import Settings
from cell import Cell

# settings = Settings()

def life_cycle(cell, cell_list, settings):
    """Main circle of events in cells life"""

    location = nearby_objects(cell, cell_list, settings)
    action = genome_action(cell.genome)

    if action in ('u', 'd', 'r', 'l'):
        square_moving(cell, cell_list, location, action, settings)

    if 'b' in action and cell.energy > settings.start_energy:
        birth(cell, cell_list, action, settings)
        # cell.energy -= int(action[-2:]) * 5
        cell.energy -= cell.energy * 0.5

    if action == 'c':
        collect(cell, settings)

    if "e" in action:
        eat(cell, location, cell_list, action, settings)
        cell.energy -= (cell.genome.count('er') + cell.genome.count('el') + cell.genome.count('ed') + cell.genome.count('eu')) * 3

    energy_reduce(cell, location)

    cell.life_time -= 1
    killer(cell, cell_list, location)

def square_moving(cell, cell_list, location, action, settings):
    if action == 'u' and location[0][1] == '0':
        # print(cell.y, cell.x, action, location[0][1])
        if cell.y > 0:
            cell_list[cell.y - 1][cell.x] = cell
            cell_list[cell.y][cell.x] = '0'
            cell.y -= 1
        elif cell.y == 0:
            cell_list[cell.y][cell.x] = '0'
            cell_list[settings.y_size][cell.x] = cell
            cell.y = settings.y_size

    if action == 'd' and location[2][1] == '0':
        if cell.y < settings.y_size:
            cell_list[cell.y + 1][cell.x] = cell
            cell_list[cell.y][cell.x] = '0'
            cell.y += 1
        elif cell.y == settings.y_size:
            cell_list[0][cell.x] = cell
            cell_list[cell.y][cell.x] = '0'
            cell.y = 0

    if action == 'l' and location[1][0] == '0':
        if cell.x > 0:
            cell_list[cell.y][cell.x - 1] = cell
            cell_list[cell.y][cell.x] = '0'
            cell.x -= 1
        elif cell.x == 0:
            cell_list[cell.y][cell.x] = '0'
            cell_list[cell.y][cell.settings.x_size] = cell
            cell.x = settings.x_size

    if action == 'r' and location[1][1] == '0':
        if cell.x < settings.x_size:
            cell_list[cell.y][cell.x + 1] = cell
            cell_list[cell.y][cell.x] = '0'
            cell.x += 1
        elif cell.x == settings.x_size:
            cell_list[cell.y][0] = cell
            cell_list[cell.y][cell.x] = '0'
            cell.x = 0

    cell.object = pygame.Rect((cell.x * cell.width, cell.y * cell.height, cell.width, cell.height))

def collect(cell, settings):
    if settings.y_size - settings.I_y_start_more_energy > cell.y > settings.I_y_start_more_energy and \
            settings.x_size - settings.I_x_start_more_energy > cell.x > settings.I_x_start_more_energy:
        if settings.y_size - settings.I_y_start_anymore_energy > cell.y > settings.I_y_start_anymore_energy and \
                settings.x_size - settings.I_x_start_anymore_energy > cell.x > settings.I_x_start_anymore_energy:
            cell.energy += 0.25 * settings.energy_coef

        cell.energy += 0.75 * settings.energy_coef
    else:
        cell.energy += 0.5 * settings.energy_coef

def nearby_objects(cell, cell_list, settings):
    top = ['-', '0', '-']
    middle = ['0', '0']
    bottom = ['-', '0', '-']

    # top[0] = try_to_see(cell_list, cell.y - 1, cell.x - 1)
    top[1] = try_to_see(cell_list, cell.y - 1, cell.x, settings)
    # top[2] = try_to_see(cell_list, cell.y - 1, cell.x + 1)
    middle[0] = try_to_see(cell_list, cell.y, cell.x - 1, settings)
    middle[1] = try_to_see(cell_list, cell.y, cell.x + 1, settings)
    # bottom[0] = try_to_see(cell_list, cell.y + 1, cell.x - 1)
    bottom[1] = try_to_see(cell_list, cell.y + 1, cell.x, settings)
    # bottom[2] = try_to_see(cell_list, cell.y + 1, cell.x + 1)
    return [top, middle, bottom]

def try_to_see(cell_list, original_y, original_x, settings):
    try:
        a = cell_list[original_y][original_x]
        return a
    except IndexError:
        y = original_y
        x = original_x
        if y > settings.y_size:
            y = 0
        if y < 0:
            y = settings.y_size
        if x > settings.x_size:
            x = 0
        if x < 0:
            x = settings.x_size

        return cell_list[y][x]

def birth(cell, cell_list, action, settings):
    '''Надо помнить, что мутирует ячейка только вврех, ввиду того что при мутации координата указана как у - 1'''

    if settings.y_size > cell.y > 0:
        new_genome = cell.genome.copy()
        random.shuffle(new_genome)
        y = cell.y
        cell_n = Cell(y - 1, cell.x, cell.color, new_genome, cell.kind, cell.energy * 0.5)

        if random.randint(1, 20) == 20:
            genome, kind = mutation(cell.genome, cell.kind)
            cell_n = Cell(y - 1, cell.x, color(genome, settings), genome, kind, cell.energy * 0.5)  # random.choice(settings.colors)

            try:
                if cell_list[y - 1][cell.x] == '0':
                    cell_list[y - 1][cell.x] = cell_n
            except IndexError:
                if cell_list[settings.y_size][cell.x] == '0':
                    cell_list[settings.y_size][cell.x] = cell_n
        else:
            try:
                if cell_list[y - 1][cell.x] == '0':
                    cell_list[y - 1][cell.x] = cell_n
            except IndexError:
                if cell_list[settings.y_size][cell.x] == '0':
                    cell_list[settings.y_size][cell.x] = cell_n

def energy_reduce(cell, location):
    # energy_reduce = 0  # 0 default
    # for raw in location:
    #     energy_reduce += raw.count('-') + raw.count('0')
    # cell.energy -= 1 + (8 - energy_reduce) + round(cell.energy * 0.01)
    cell.energy -= 1 + round(cell.energy * 0.01)

def killer(cell, cell_list, location):
    if cell.energy <= 0 or cell.life_time <= 0:
        # or ("b10" not in cell.genome and "b20" not in cell.genome and "b30" not in cell.genome):
        cell_list[cell.y][cell.x] = '0'

def genome_action(genome):
    action = genome.pop(0)
    genome.append(action)
    return action

def mutation(genome, kind):
    new_gen = random.choice(
        ('b10', 'b20', 'b30', 'b40', 'b50', 'u', 'd', 'l', 'r', 'c', 'el', 'er', 'el', 'ed'))
    new_genome = genome.copy()

    new_genome.pop(random.randint(0, len(new_genome) - 1))
    new_genome.append(new_gen)

    '''Добавить добавление рождаемости при его отсутсвтии'''
    kind_new = kind[:4] + chr(random.randint(65, 90)) + str(random.randint(0, 100))
    return new_genome, kind_new

def eat(cell, location, cell_list, action, settings):
    if action[-1] == 'l' and location[1][0] != '0':
        if location[1][0].kind != cell.kind:
            try:
                cell.energy += cell_list[cell.y][cell.x - 1].energy * settings.eat_coef
                cell_list[cell.y][cell.x - 1] = '0'

            except IndexError:
                pass

    if action[-1] == 'r' and location[1][1] != '0':
        if location[1][1].kind != cell.kind:
            try:
                cell.energy += cell_list[cell.y][cell.x + 1].energy * settings.eat_coef
                cell_list[cell.y][cell.x + 1] = '0'

            except IndexError:
                pass

    if action[-1] == 'u' and location[0][1] != '0':
        if location[0][1].kind != cell.kind:
            try:
                cell.energy += cell_list[cell.y - 1][cell.x].energy * settings.eat_coef
                cell_list[cell.y - 1][cell.x] = '0'

            except IndexError:
                pass

    if action[-1] == 'd' and location[2][1] != '0':
        if location[2][1].kind != cell.kind:
            try:
                cell.energy += cell_list[cell.y + 1][cell.x].energy * settings.eat_coef
                cell_list[cell.y + 1][cell.x] = '0'

            except IndexError:
                pass

def color(genome, settings):
    colozing_count = genome.count('c') + genome.count('er') + genome.count('el') + genome.count('ed') +\
                     genome.count('eu') + genome.count('b10') + genome.count('b20') + genome.count('b30') + \
                     genome.count('b40') + genome.count('b50')
    if colozing_count == 0:
        colozing_count = 1
    collect = (255 // colozing_count) * genome.count('c')
    eat = (255 // colozing_count) * (genome.count('er') + genome.count('el') + genome.count('ed')
                                          + genome.count('eu'))
    birth = (255 // colozing_count) * (genome.count('b10') + genome.count('b20') + genome.count('b30') +
                                       genome.count('b40') + genome.count('b50'))
    if eat > 255:
        eat = 255
    if collect > 255:
        collect = 255
    if birth > 255:
        birth = 255

    return [0 + eat, 0 + collect, 0 + birth]


import os
from ..modules.converter.html2pdf import Html2Pdf
from ..path import path_inicial

def test_converter_erro():
    """
    Testa a conversão do arquivo HTML para PDF quando há erro na entrada.

    Verifica se a função `convert` retorna False quando ocorre um erro na
    entrada.

    Returns:
        bool: False, se ocorreu um erro na conversão.
    """

    download_folder = os.path.join(os.path.expanduser("~"), "Downloads")
    html2pdf = Html2Pdf(html=path_inicial + "/Melissa Ribeiro Araujo.html")
    assert not html2pdf.convert(
        output_name="Melissa Ribeiro Araujo.html",
        foldername="exemplo_Melissa",
        folder_destino=download_folder,
        output_funcao="MONITOR",
    )


#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: leeyoshinari
import json
import smtplib
import shutil
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from logger import logger, cfg

def sendMsg(html, paths, failure_num=1, is_path=True, is_send=True):
    """
    发送邮件
    :param html: 邮件正文用到的html文件路径，或者html
    :param paths:
    :param failure_num: 失败的用例数
    :param is_path: bool，True表示html是一个路径，False表示html是html
    :param is_send: bool，是否发邮件，仅用于第一次发送失败后，再次发送
    :return:
    """
    flag = 0
    is_email = int(cfg.getConfig('is_email'))
    if is_email:
        if is_email == 1:
            flag = 1
        if is_email == 2:
            if failure_num > 0:
                flag = 1
            else:
                logger.info('所有用例执行成功，不发送邮件，已跳过。')
        if is_email == 3:
            if failure_num == 0:
                flag = 1
            else:
                logger.info('有执行失败的用例，不发送邮件，已跳过。')
    else:
        logger.info('设置为不自动发送邮件，已跳过。')

    if flag:
        try:
            if paths["method"] == "GET":
                shutil.copy(paths["email_file"], paths["new_email_file"])
            else:
                if paths["post_data"].get('email'):
                    replace_email(paths["email_file"], paths["post_data"]['email'], paths["new_email_file"])

            email_dict = json.load(open(paths["new_email_file"], 'r', encoding='utf-8'))
            subject = email_dict['subject']
            send_to = email_dict['receiveEmail']
            receive_name = email_dict['receiveName']
            logger.info('开始发送邮件，收件人{}'.format(send_to))
            message = MIMEMultipart()
            message['From'] = Header(cfg.getConfig('sender_name'))      # 发件人名字
            message['To'] = Header(receive_name)    # 收件人名字
            message['Subject'] = Header(subject, 'utf-8')   # 邮件主题

            if is_path:
                with open(html, 'r', encoding='utf-8') as f:
                    fail_case = f.read()
            else:
                fail_case = html

            email_text = MIMEText(fail_case, 'html', 'utf-8')
            message.attach(email_text)  # 添加邮件正文

            try:
                server = smtplib.SMTP_SSL(cfg.getConfig('smtp'), 465)
            except Exception as err:
                logger.error(err)
                server = smtplib.SMTP(cfg.getConfig('smtp'), 25)

            server.login(cfg.getConfig('sender_email'), '123456')  # 登陆邮箱
            server.sendmail(cfg.getConfig('sender_email'), send_to.split(','), message.as_string())  # 发送邮件
            server.quit()
            del fail_case, email_text, message, server
            logger.info('邮件发送成功')
        except Exception as err:
            logger.error(err)
            if is_send:
                sendMsg(html, paths, is_path=is_path, is_send=False)   # 发送失败后，重发一次

def replace_email(src, new_dict, dst):
    old_dict = json.load(open(src, 'r', encoding='utf-8'))
    for k, v in new_dict.items():
        old_dict.update({k: v})

    with open(dst, 'w', encoding='utf-8') as f:
        f.write(json.dumps(old_dict))


from django.urls import path
from blood import views

urlpatterns = [

    path('', views.home, name='home'),
    path('about/', views.about, name='about'),
    path('patient/', views.patient, name='patient'),
    path('donor/', views.donor, name='donor'),
    path('contact/', views.contact, name='contact'),
    path('register/', views.register, name='register'),
    path('forgot/', views.forgot, name='forgot'),
]


import pyrealsense2 as rs
import numpy as np

class Video(object):
    def __init__(self):
        self.points = rs.points()
        self.pipeline = rs.pipeline()
        self.dirname = ""
        self.config = rs.config()

    def start(self):
        print("Starting the video" + self.dirname)
        if self.dirname == "":
            print("Invalid Filename!")
            return
        self.config.enable_device_from_file(self.dirname, repeat_playback=False)
        profile = self.pipeline.start(self.config)
        profile.get_device().as_playback().set_real_time(False)

    def stop(self):
        self.pipeline.stop()
        print("Stopped the video")

    def get_frame(self):
        frames = self.pipeline.wait_for_frames()
        color_frame = frames.get_color_frame()
        nir_frame = frames.get_infrared_frame()
        color_out = np.asanyarray(color_frame.get_data())
        nir_out = np.asanyarray(nir_frame.get_data(), dtype='uint8')
        return color_out, nir_out


import yt
import os
import sys
import numpy as np
from scipy import ndimage #, datasets

import astropy.units as u
import matplotlib.pyplot as plt
import matplotlib.colors as colors

from emission_models import uv, xrt, xray_bremsstrahlung
from visualization.colormaps import color_tables

# Importing sunpy dependencies for a synthetic map
# See creating custom maps: https://docs.sunpy.org/en/stable/how_to/create_custom_map.html
import sunpy.map
from sunpy.map.mapbase import GenericMap, SpatialPair
import textwrap
from astropy.coordinates import SkyCoord
from sunpy.coordinates import frames
from sunpy.map.header_helper import make_fitswcs_header
from sunpy.coordinates.sun import _radius_from_angular_radius

class SyntheticImage():

    """
    Template for a parent class for the Synthetic Images
    """
    # TODO: Should this be an abstract class? So that abstract methods can be explicitly defined in each of the
    #  inheriting classes

    def __init__(self):
        pass

class SyntheticFilterImage():

    """
    Load a yt readable dataset and plot synthetic image having given the instrument name and wavelength
    """

    def __init__(self, dataset, instr, channel, hint=None, units_override=None,
                 view_settings=None, plot_settings=None, **kwargs):
        """
        :param dataset: Path of the downsampled dataset or a dataset itself
        """

        self.box = None  # Importing a region within an initial dataset

        if isinstance(dataset, str):
            self.data = yt.load(dataset, units_override=units_override, hint=hint)
        elif isinstance(dataset, yt.data_objects.static_output.Dataset):
            self.data = dataset
        elif isinstance(dataset, yt.data_objects.selection_objects.region.YTRegion):
            self.data = dataset.ds
            self.box = dataset

        self.instr = instr
        self.obs = kwargs.get('obs', "DefaultInstrument")  # Name of the observatory
        self.obstime = kwargs.get('obstime', '2017-09-10')  # Observation time
        self.channel = channel
        self.view_settings = {'normal_vector': (0.0, 0.0, 1.0),  # pass vectors as mutable arguments
                              'north_vector': (-0.7, -0.3, 0.0)}
        self.__imag_field = None
        self.image = None

        if self.box:
            self.domain_width = np.abs(self.box.right_edge - self.box.left_edge).in_units('cm').to_astropy()
        else:
            self.domain_width = self.data.domain_width.in_units("cm").to_astropy() #convert unyt to astropy.units

        self.plot_settings = {'resolution': 512,
                              'vmin': 1e-15,
                              'vmax': 1e6,
                              'cmap': 'inferno',
                              'logscale': True,
                              'figpath': './prj_plt.png',
                              'frame': None,
                              'label': None}

    def make_filter_image_field(self, **kwargs):

        cmap = {}
        imaging_model = None
        instr_list = ['xrt', 'aia']

        if self.instr not in instr_list:
            raise ValueError("instr should be in the instrument list: ", instr_list)

        if self.instr == 'xrt':
            imaging_model = xrt.XRTModel("temperature", "density", self.channel)
            cmap['xrt'] = color_tables.xrt_color_table()
        if self.instr == 'aia':
            imaging_model = uv.UVModel("temperature", "density", self.channel)
            try:
                cmap['aia'] = color_tables.aia_color_table(int(self.channel) * u.angstrom)
            except ValueError:
                raise ValueError("AIA wavelength should be one of the following:"
                                 "1600, 1700, 4500, 94, 131, 171, 193, 211, 304, 335.")

        imaging_model.make_intensity_fields(self.data)

        field = str(self.instr) + '_filter_band'
        self.__imag_field = field

        if self.plot_settings:
            self.plot_settings['cmap'] = cmap[self.instr]

    def proj_and_imag(self, plot_settings=None, view_settings=None, **kwargs):

        self.make_filter_image_field()  # Create emission fields

        if plot_settings:
            self.plot_settings = plot_settings

        if view_settings:
            self.view_settings = view_settings

        if self.box:
            region = self.box
        else:
            region = self.data

        prji = yt.visualization.volume_rendering.off_axis_projection.off_axis_projection(
            region,
            [0.0, 0.5, 0.0],  # center position in code units
            normal_vector=self.view_settings['normal_vector'],  # normal vector (z axis)
            width=self.data.domain_width[0].value,  # width in code units
            resolution=self.plot_settings['resolution'],  # image resolution
            item=self.__imag_field,  # respective field that is being projected
            north_vector=self.view_settings['north_vector'])

        self.image = np.rot90(np.array(prji), k=3)

        self.image_zoom = kwargs.get('image_zoom', None)

        if self.image_zoom:
            self.image = self.zoom_out(self.image, self.image_zoom)

        # return self.image
        self.image_shift = kwargs.get('image_shift', None)  # (xshift, yshift)

        if self.image_shift:
            self.image = np.roll(self.image, (self.image_shift[0],
                                              self.image_shift[1]), axis=(1, 0))
        #if kwargs.get('shift_imag', 'EIT')

        # Fill background
        self.bkg_fill = kwargs.get('bkg_fill', None)
        if self.bkg_fill: self.image[self.image <= 0] = self.bkg_fill

    def zoom_out(self, img, scale):
        new_arr = np.ones_like(img) * img.min()
        if scale >= 1:
            raise ValueError("Scale parameter has to be lower than 1")
        zoomed_img = ndimage.zoom(img, scale)  # scale<1

        # fill the central part of the new image
        y, x = new_arr.shape
        cropx = (zoomed_img.shape[0])
        cropy = (zoomed_img.shape[1])
        startx = (x - cropx) // 2
        starty = (y - cropy) // 2
        new_arr[starty:starty + cropy, startx:startx + cropx] = zoomed_img
        return new_arr

    def make_synthetic_map(self, **kwargs):

        """
        Creates a synthetic map object that can be loaded/edited with sunpy
        :return:
        """
        data = self.image
        self.obstime = kwargs.get('obstime')

        # Define header parameters for the synthetic image

        # Coordinates can be passed from sunpy maps that comparisons are made width
        self.reference_coord = kwargs.get('reference_coord', SkyCoord(0*u.arcsec, 0*u.arcsec,
                                   obstime=self.obstime,
                                   observer='earth',  # Temporarily 1 AU away
                                   frame=frames.Helioprojective))

        self.reference_pixel = kwargs.get('reference_pixel', u.Quantity([(data.shape[1] - 1)/2.,
            (data.shape[0] - 1)/2.], u.pixel))  # Reference pixel along each axis: Defaults to the center of data array

        asec2cm = _radius_from_angular_radius(1. * u.arcsec, 1 * u.AU).to(u.cm)  # centimeters per arcsecond at 1 AU
        resolution = self.plot_settings['resolution']
        domain_size = self.domain_width.max()
        len_asec = (domain_size/asec2cm).value
        scale_ = [len_asec/resolution, len_asec/resolution]

        self.scale = kwargs.get('scale', u.Quantity(scale_, u.arcsec/u.pixel))
        self.telescope = kwargs.get('telescope', 'EIT')
        self.observatory = kwargs.get('observatory', 'SOHO')
        self.detector = kwargs.get('detector', 'Synthetic')
        self.instrument = kwargs.get('instrument', None)
        if isinstance(self.channel, int):
            self.wavelength = int(self.channel) * u.angstrom
        else:
            self.wavelength = None
        self.exposure = kwargs.get('exposure', None)
        self.unit = kwargs.get('unit', None)

        # Creating header using sunpy
        header = make_fitswcs_header(data,
                                     coordinate=self.reference_coord,
                                     reference_pixel=self.reference_pixel,
                                     scale=self.scale,
                                     telescope=self.telescope,
                                     detector=self.detector,
                                     instrument=self.instrument,
                                     observatory=self.observatory,
                                     wavelength=self.wavelength,
                                     exposure=self.exposure,
                                     unit=self.unit)

        self.synth_map = sunpy.map.Map(data, header)
        return self.synth_map

    def __str__(self):
        return f"{self._text_summary()}\n{self.data.__repr__()}"

    def __repr__(self):
        return f"{object.__repr__(self)}\n{self}"

    def _text_summary(self):
        # similarly to sunpy.map.mapbase GenericMap(NDData)
        return textwrap.dedent("""\
        Synthetic image from the yt dataset
        ---------
        Instrument:\t\t {inst}
        Wavelength:\t\t {wave}
        """).format(inst=self.instr,
                    wave=self.channel)

#TODO: Write a parent class for Synthetic images that both SyntheticBandImage and SyntheticFilterImage can inherit from,
# so you don't need to describe the same input parameters, such as *dataset*, or *view_settings* and avoid code repetition.
# Get back to this when you will start working on nonthermal emission models, and further on gyrosynchrotron.
# IMPORTANT: proj_and_imag can be inherited from this parent class as well, however exact methods are to be redefined
# Or just inherit from SyntheticFilterImage (?)

class SyntheticBandImage():

    """
    Class to store synthetic X-ray images generated in a given *energy band*, such as ones from RHESSI.
    """

    def __init__(self, dataset, emin, emax, nbins, emission_model, hint=None, units_override=None,
                 view_settings=None, plot_settings=None, **kwargs):

        """
        :param dataset: Path of the downsampled dataset or a dataset itself
        :param emin: low energy limit in keV
        :param emax: high energy limit in keV
        :param nbins: number of energy bins to compute synthetic spectra and images
        """

        self.emin = emin
        self.emax = emax
        self.nbins = nbins
        self.emission_model = emission_model  # Thermal / Non-thermal

        self.box = None  # Importing a region within an initial dataset

        if isinstance(dataset, str):
            self.data = yt.load(dataset, units_override=units_override, hint=hint)
        elif isinstance(dataset, yt.data_objects.static_output.Dataset):
            self.data = dataset
        elif isinstance(dataset, yt.data_objects.selection_objects.region.YTRegion):
            self.data = dataset.ds
            self.box = dataset

        self.obs = kwargs.get('obs', "DefaultInstrument")  # Name of the observatory
        self.instr = kwargs.get('instr', 'RHESSI')
        self.binscale = kwargs.get('binscale', 'linear')
        self.obstime = kwargs.get('obstime', '2017-09-10')  # Observation time

        self.view_settings = {'normal_vector': (0.0, 0.0, 1.0),  # pass vectors as mutable arguments
                              'north_vector': (-0.7, -0.3, 0.0)}
        self.__imag_field = None
        self.image = None

        if self.box:
            self.domain_width = np.abs(self.box.right_edge - self.box.left_edge).in_units('cm').to_astropy()
        else:
            self.domain_width = self.data.domain_width.in_units("cm").to_astropy()  # convert unyt to astropy.units

    def make_band_image_field(self, **kwargs):

        cmap = {}
        imaging_model = None

        if self.emission_model == 'Thermal':
            imaging_model = xray_bremsstrahlung.ThermalBremsstrahlungModel

        imaging_model.make_intensity_fields(self.data)
        field = 'xray_' + str(emin) + '_' + str(emax) + '_keV_band'
        self.__imag_field = field


# dimensions 3400x5000
from PIL import Image, ImageDraw, ImageFont

#   BASE - convert

img_base = Image.open('white_sheet_5000x7000.jpg')
left, upper, right, lower = 0, 0, 3400, 5600
img_base = img_base.crop((left, upper, right, lower))
img_base.save('white_sheet_final_3400x5600.jpg')
img_final = Image.open('white_sheet_final_3400x5600.jpg')

#   BASE - outdraw

draw = ImageDraw.Draw(img_final)
draw.line((24, 0, 24, 5600), fill=(0, 0, 0), width=51)
draw.line((50, 5575, 3400, 5575), fill=(0, 0, 0), width=50)
draw.line((3375, 5575, 3375, 0), fill=(0, 0, 0), width=50)
draw.line((3350, 25, 0, 25), fill=(0, 0, 0), width=50)

#   PASTE - album cover

img_cover = Image.open('rocky_testing.jpg')
img_final.paste(img_cover, (200, 250))

#   UNDERLINE - draw

draw.line(((200, 3400), (3200, 3400)), fill=(0, 0, 0), width=10)

#   TEXT - album title

myfont = ImageFont.truetype(r'LeagueGothic-Regular.ttf', size=300)
draw.text((200, 3550), "TESTING", fill=(0, 0, 0), font=myfont, spacing=10)

#   SAVE - final

img_final.save('final_resault.jpg')
img_test = Image.open('white_sheet_3300x5000.jpg')
img_test = img_test.crop((0, 0, 3200, 5000))
img_test.save('white_sheet_3200x5000.jpg')


"""
    Created By: Norman Thien
    Creation Date: 15 Feb 2023
    Last Modified: 18 Feb 2023

    This file hosts the definitions for the tic-tac-toe domain model objects.
"""
#imports

import enum
import re
from dataclasses import dataclass
from functools import cached_property
from tic_tac_toe.logic.exceptions import InvalidMove
from tic_tac_toe.logic.validators import validate_game_state, validate_grid

#Var

WINNING_PATTERNS = (
    "???......",
    "...???...",
    "......???",
    "?..?..?..",
    ".?..?..?.",
    "..?..?..?",
    "?...?...?",
    "..?.?.?..",
)

#for game grid
"""
        defined as an immutable object for increased fault tolerance and code readability.
        issue is that the cells (object) cannot be altered once created.
"""
@dataclass(frozen=True)
class Grid:
    cells: str = " " * 9
    """
        Wrongly initialised cells can break the game so we only allow object to exist in
        a valid state only, otherwise the object won't be created at all
        following fail-fast and always-valid domain model principles.
        post initialization to perform cell validation. Method in validators.py
    """
    def __post_init__(self) -> None:
        validate_grid(self)

    #return number of crosses, naughts or empty cells

    @cached_property
    def x_count(self) -> int:
        return self.cells.count("X")

    @cached_property
    def o_count(self) -> int:
        return self.cells.count("O")

    @cached_property
    def empty_count(self) -> int:
        return self.cells.count(" ")

# Player Marks
"""
    Since there are only two symbols belonging to a fixed set of discrete values,
    you can define them within an enumerated type or enum.
    Using enums is preferable over constants due to their enhanced type safety, common namespace,
    and programmatic access to their members.
    sometimes be more convenient to think about the player
    marks in terms of strings instead of enum members.
    Because enums are glorified classes,
    you're free to put ordinary methods and properties into them
"""
class Mark(str, enum.Enum):
    CROSS = "X"
    NAUGHT = "O"

    @property
    def other(self) -> "Mark":
        return Mark.CROSS if self is Mark.NAUGHT else Mark.NAUGHT

@dataclass(frozen=True)
class Move:
    mark: Mark
    cell_index: int
    before_state: "GameState"
    after_state: "GameState"

@dataclass(frozen=True)
class GameState:
    grid: Grid
    starting_mark: Mark = Mark("X")

    def __post_init__(self) -> None:
        validate_game_state(self)

    #determine who's turn to move
    @cached_property
    def current_mark(self) -> Mark:
        if self.grid.x_count == self.grid.o_count:
            return self.starting_mark
        else:
            return self.starting_mark.other

    #identify empty cells that can be filled by the current player
    @cached_property
    def possible_moves(self) -> list[Move]:
        moves = []
        if not self.game_over:
            for match in re.finditer(r"\s", self.grid.cells):
                moves.append(self.make_move_to(match.start()))
        return moves

    """
        player make move (input), check valid then add the move to a new Grid
        Containing old Grid values and the new move.
    """
    def make_move_to(self, index: int) -> Move:
        if self.grid.cells[index] != " ":
            raise InvalidMove("Cell is not empty")
        return Move(
            mark=self.current_mark,
            cell_index=index,
            before_state=self,
            after_state=GameState(
                Grid(
                    self.grid.cells[:index]
                    + self.current_mark
                    + self.grid.cells[index + 1:]
                ),
                self.starting_mark,
            ),
        )

    #determine if game not started i.e. blank cells
    @cached_property
    def game_not_started(self) -> bool:
        return self.grid.empty_count == 9

    #in tie state or there is a winner
    @cached_property
    def game_over(self) -> bool:
        return self.winner is not None or self.tie

    #tie when no winner and no empty cells
    @cached_property
    def tie(self) -> bool:
        return self.winner is None and self.grid.empty_count == 0

    #Pattern match the winner
    @cached_property
    def winner(self) -> Mark | None:
        for pattern in WINNING_PATTERNS:
            for mark in Mark:
                if re.match(pattern.replace("?", mark), self.grid.cells):
                    return mark
        return None

    """
    @cached_property
    def winning_cells(self) -> list[int]:
        for pattern in WINNING_PATTERNS:
            for mark in Mark:
                if re.match(pattern.replace("?", mark), self.grid.cells):
                    return [
                        match.start()
                        for match in re.finditer(r"\?", pattern)
                    ]
        return []

    """


from datetime import date, datetime

from django.http import HttpRequest, QueryDict
from django.test import SimpleTestCase, TestCase
from django.utils.http import urlencode

from dimagi.utils.dates import DateSpan

from corehq.apps.locations.tests.util import LocationHierarchyTestCase
from corehq.apps.locations.util import (
    load_locs_json,
    location_hierarchy_config,
)
from corehq.apps.reports_core.exceptions import FilterValueException
from corehq.apps.reports_core.filters import (
    REQUEST_USER_KEY,
    Choice,
    ChoiceListFilter,
    DatespanFilter,
    DynamicChoiceListFilter,
    LocationDrilldownFilter,
    NumericFilter,
    PreFilter,
)
from corehq.apps.userreports.datatypes import (
    DATA_TYPE_DATE,
    DATA_TYPE_DATETIME,
)
from corehq.apps.userreports.exceptions import BadSpecError
from corehq.apps.userreports.models import (
    DataSourceConfiguration,
    ReportConfiguration,
)
from corehq.apps.userreports.reports.filters.factory import ReportFilterFactory
from corehq.apps.userreports.reports.filters.specs import create_filter_value
from corehq.apps.userreports.reports.filters.values import (
    SHOW_ALL_CHOICE,
    DateFilterValue,
    LocationDrilldownFilterValue,
    NumericFilterValue,
    PreFilterValue,
)
from corehq.apps.userreports.reports.view import (
    ConfigurableReportView,
    query_dict_to_dict,
)
from corehq.apps.userreports.tasks import rebuild_indicators
from corehq.apps.userreports.tests.test_view import ConfigurableReportTestMixin
from corehq.apps.userreports.util import get_indicator_adapter
from corehq.apps.users.models import CommCareUser

class FilterTestCase(SimpleTestCase):

    def test_no_type(self):
        with self.assertRaises(BadSpecError):
            ReportFilterFactory.from_spec({
                "field": "some_field",
                "slug": "some_slug",
                "display": "Some display name"
            })

    def test_bad_type(self):
        with self.assertRaises(BadSpecError):
            ReportFilterFactory.from_spec({
                "type": "invalid_type",
                "field": "some_field",
                "slug": "some_slug",
                "display": "Some display name"
            })

    def test_missing_field(self):
        with self.assertRaises(BadSpecError):
            ReportFilterFactory.from_spec({
                "type": "date",
                "slug": "some_slug",
                "display": "Some display name"
            })

    def test_missing_slug(self):
        with self.assertRaises(BadSpecError):
            ReportFilterFactory.from_spec({
                "type": "date",
                "field": "some_field",
                "display": "Some display name"
            })

    def test_translation(self):
        shared_conf = {
            "type": "date",
            "field": "some_field",
            "slug": "some_slug",
        }

        # Plain string
        conf = {"display": "foo"}
        conf.update(shared_conf)
        filter = ReportFilterFactory.from_spec(conf)
        self.assertEqual(filter.context({}, None, lang=None)['label'], "foo")
        self.assertEqual(filter.context({}, None, lang="fr")['label'], "foo")

        # Translation
        conf = {"display": {"en": "english", "fr": "french"}}
        conf.update(shared_conf)
        filter = ReportFilterFactory.from_spec(conf)
        self.assertEqual(filter.context({}, None, lang=None)['label'], "english")
        self.assertEqual(filter.context({}, None, lang="fr")['label'], "french")
        self.assertEqual(filter.context({}, None, lang="en")['label'], "english")
        self.assertEqual(filter.context({}, None, lang="es")['label'], "english")

class DateFilterTestCase(SimpleTestCase):

    def test_date_filter(self):
        filter = ReportFilterFactory.from_spec({
            "type": "date",
            "field": "modified_on_field",
            "slug": "modified_on_slug",
            "display": "Date Modified"
        })
        self.assertEqual(DatespanFilter, type(filter))
        self.assertEqual('modified_on_slug', filter.name)
        self.assertEqual('Date Modified', filter.label)

    def test_compare_as_string_option(self):

        def get_query_value(compare_as_string):

            spec = {
                "type": "date",
                "field": "modified_on_field",
                "slug": "my_slug",
                "display": "date Modified",
                "compare_as_string": compare_as_string,
            }
            reports_core_filter = ReportFilterFactory.from_spec(spec)
            reports_core_value = reports_core_filter.get_value({
                "my_slug-start": "2015-06-07",
                "my_slug-end": "2015-06-08",
                "date_range_inclusive": True,
            })

            return create_filter_value(spec, reports_core_value).to_sql_values()

        val = get_query_value(compare_as_string=False)
        self.assertEqual(type(val['my_slug_startdate']), datetime)
        self.assertEqual(type(val['my_slug_enddate']), datetime)

        val = get_query_value(compare_as_string=True)
        self.assertEqual(type(val['my_slug_startdate']), str)
        self.assertEqual(type(val['my_slug_enddate']), str)

class DateFilterDBTest(ConfigurableReportTestMixin, TestCase):

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls._create_data()
        cls._create_data_source()
        cls.report_config = cls._create_report()

    @classmethod
    def _create_data(cls):
        cls._new_case({"my_date": date(2017, 1, 1), "my_datetime": datetime(2017, 1, 1, 9)}).save()

    @classmethod
    def _create_data_source(cls):
        cls.config = DataSourceConfiguration(
            domain=cls.domain,
            display_name=cls.domain,
            referenced_doc_type='CommCareCase',
            table_id="foo",
            configured_filter={
                "type": "boolean_expression",
                "operator": "eq",
                "expression": {
                    "type": "property_name",
                    "property_name": "type"
                },
                "property_value": cls.case_type,
            },
            configured_indicators=[
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'my_date'
                    },
                    "column_id": 'date_as_string',
                    "display_name": 'date_as_string',
                    "datatype": "string"
                },
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'my_date'
                    },
                    "column_id": 'date_as_date',
                    "datatype": "date"
                },
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": "my_datetime",
                    },
                    "column_id": "datetime_as_datetime",
                    "datatype": "datetime"
                }
            ],
        )
        cls.config.validate()
        cls.config.save()
        cls.addClassCleanup(cls.config.delete)

        cls.adapter = get_indicator_adapter(cls.config)
        rebuild_indicators(cls.config._id)
        cls.addClassCleanup(cls.adapter.drop_table)

    @classmethod
    def _create_report(cls):
        report_config = ReportConfiguration(
            domain=cls.domain,
            config_id=cls.config._id,
            title='foo',
            filters=[
                {
                    "type": "date",
                    "field": "date_as_date",
                    "slug": "date_as_date_filter",
                    "display": "Date as Date filter"
                },
                {
                    "type": "date",
                    "field": "date_as_string",
                    "slug": "date_as_string_filter",
                    "display": "Date as String filter",
                    "compare_as_string": True,
                },
                {
                    "type": "date",
                    "field": "datetime_as_datetime",
                    "slug": "datetime_as_datetime_filter",
                    "display": "Datetime as Datetime filter",
                    "compare_as_string": False,
                }
            ],
            aggregation_columns=['doc_id'],
            columns=[{
                # We don't really care what columns are returned, we're testing the filters
                "type": "field",
                "display": "doc_id",
                "field": 'doc_id',
                'column_id': 'doc_id',
                'aggregation': 'simple'
            }],
        )
        report_config.save()
        cls.addClassCleanup(report_config.delete)
        return report_config

    def _create_view(self, filter_values):
        request = HttpRequest()
        request.method = 'GET'
        request.GET.update(filter_values)
        view = ConfigurableReportView(request=request)
        view._domain = self.domain
        view._lang = "en"
        view._report_config_id = self.report_config._id
        return view

    def docs_returned(self, export_table):
        rows = export_table[0][1]
        return len(rows) - 1  # the first row is the headers, not a document

    def test_standard_date_filter(self):
        # Confirm that date filters include rows that match the start and/or end date.
        view = self._create_view({
            "date_as_date_filter": "2017-01-01 to 2017-01-01",
            "date_as_date_filter-start": "2017-01-01",
            "date_as_date_filter-end": "2017-01-01",
        })
        self.assertEqual(1, self.docs_returned(view.export_table))

    def test_string_date_filter(self):
        # Confirm that "compare_as_string" date filters include rows that match the start and/ord end date
        view = self._create_view({
            "date_as_string_filter": "2017-01-01 to 2017-01-01",
            "date_as_string_filter-start": "2017-01-01",
            "date_as_string_filter-end": "2017-01-01",
        })
        self.assertEqual(1, self.docs_returned(view.export_table))

    def test_standard_datetime_filter(self):
        view = self._create_view({
            "datetime_as_datetime_filter": "2017-01-01 to 2017-01-01",
            "datetime_as_datetime_filter-start": "2017-01-01",
            "datetime_as_datetime_filter-end": "2017-01-01",
        })
        self.assertEqual(1, self.docs_returned(view.export_table))

class QuarterFilterTestCase(SimpleTestCase):

    def test_date_filter(self):
        def get_query_value(year, quarter):
            spec = {
                "type": "quarter",
                "field": "modified_on_field",
                "slug": "my_slug",
                "display": "date Modified",
            }
            reports_core_filter = ReportFilterFactory.from_spec(spec)
            reports_core_value = reports_core_filter.get_value({
                "my_slug-year": year,
                "my_slug-quarter": quarter
            })

            return create_filter_value(spec, reports_core_value).to_sql_values()

        value = get_query_value(2016, 1)
        self.assertEqual(value['my_slug_startdate'], datetime(2016, 1, 1))
        self.assertEqual(value['my_slug_enddate'], datetime(2016, 4, 1))

        value = get_query_value(2016, 2)
        self.assertEqual(value['my_slug_startdate'], datetime(2016, 4, 1))
        self.assertEqual(value['my_slug_enddate'], datetime(2016, 7, 1))

        value = get_query_value(2016, 3)
        self.assertEqual(value['my_slug_startdate'], datetime(2016, 7, 1))
        self.assertEqual(value['my_slug_enddate'], datetime(2016, 10, 1))

        value = get_query_value(2016, 4)
        self.assertEqual(value['my_slug_startdate'], datetime(2016, 10, 1))
        self.assertEqual(value['my_slug_enddate'], datetime(2017, 1, 1))

class NumericFilterTestCase(SimpleTestCase):

    def test_numeric_filter(self):
        filter = ReportFilterFactory.from_spec({
            "type": "numeric",
            "field": "number_of_children_field",
            "slug": "number_of_children_slug",
            "display": "Number of Children",
        })
        self.assertEqual(NumericFilter, type(filter))
        self.assertEqual("number_of_children_slug", filter.name)
        self.assertEqual("Number of Children", filter.label)

    def test_numeric_filter_value(self):
        filter = {
            "type": "numeric",
            "field": "number_of_children_field",
            "slug": "number_of_children_slug",
            "display": "Number of Children",
        }
        NumericFilterValue(filter, None)
        NumericFilterValue(filter, {'operator': '<', 'operand': 3})
        with self.assertRaises(AssertionError):
            NumericFilterValue(filter, {'operator': 'sql injection', 'operand': 3})

class PreFilterTestCase(SimpleTestCase):

    def test_pre_filter(self):
        filter_ = ReportFilterFactory.from_spec({
            'type': 'pre',
            'field': 'at_risk_field',
            'slug': 'at_risk_slug',
            'datatype': 'string',
            'pre_value': 'true'
        })
        self.assertEqual(type(filter_), PreFilter)
        self.assertEqual(filter_.name, 'at_risk_slug')
        self.assertEqual(filter_.default_value(), {'operator': '=', 'operand': 'true'})

    def test_pre_filter_value(self):
        pre_value = 'yes'
        filter_ = {
            'type': 'pre',
            'field': 'at_risk_field',
            'slug': 'at_risk_slug',
            'datatype': 'string',
            'pre_value': pre_value
        }
        filter_value = PreFilterValue(filter_, {'operand': pre_value})
        self.assertEqual(filter_value.to_sql_values(), {'at_risk_slug': 'yes'})

    def test_pre_filter_value_empty(self):
        pre_values = ['', None]
        operators = ['', '=']
        for pre_value in pre_values:
            for operator in operators:
                filter_ = {
                    'type': 'pre',
                    'field': 'empty_field',
                    'slug': 'empty_field_slug',
                    'datatype': 'string',
                    'pre_value': pre_value,
                    'pre_operator': operator
                }
                filter_value = PreFilterValue(filter_, {'operand': pre_value, 'operator': operator})
                self.assertEqual(filter_value.to_sql_values(), {'empty_field_slug': ''})
                self.assertEqual(
                    str(filter_value.to_sql_filter().build_expression()),
                    'empty_field = :empty_field_slug OR empty_field IS NULL'
                )

    def test_pre_filter_value_empty_date_types(self):
        pre_values = ['', None]
        operators = ['', '=']
        date_types = [DATA_TYPE_DATE, DATA_TYPE_DATETIME]
        for pre_value in pre_values:
            for operator in operators:
                for datatype in date_types:
                    filter_ = {
                        'type': 'pre',
                        'field': 'empty_field',
                        'slug': 'empty_field_slug',
                        'datatype': datatype,
                        'pre_value': pre_value,
                        'pre_operator': operator
                    }
                    filter_value = PreFilterValue(filter_, {'operand': pre_value, 'operator': operator})
                    self.assertEqual(filter_value.to_sql_values(), {})
                    self.assertEqual(
                        str(filter_value.to_sql_filter().build_expression()),
                        'empty_field IS NULL'
                    )

    def test_pre_filter_value_exists(self):
        pre_values = ['', None]
        operator = '!='
        for pre_value in pre_values:
            filter_ = {
                'type': 'pre',
                'field': 'exists_field',
                'slug': 'exists_field_slug',
                'datatype': 'string',
                'pre_value': pre_value,
                'pre_operator': operator
            }
            filter_value = PreFilterValue(filter_, {'operand': pre_value, 'operator': operator})
            self.assertEqual(filter_value.to_sql_values(), {'exists_field_slug': ''})
            # != '' filters out null data in postgres which is why the expression doesn't need to check nulls
            self.assertEqual(
                str(filter_value.to_sql_filter().build_expression()),
                'exists_field != :exists_field_slug'
            )

    def test_pre_filter_value_exists_date_types(self):
        pre_values = ['', None]
        operator = '!='
        date_types = [DATA_TYPE_DATE, DATA_TYPE_DATETIME]
        for pre_value in pre_values:
            for datatype in date_types:
                filter_ = {
                    'type': 'pre',
                    'field': 'exists_field',
                    'slug': 'exists_field_slug',
                    'datatype': datatype,
                    'pre_value': pre_value,
                    'pre_operator': operator
                }
                filter_value = PreFilterValue(filter_, {'operand': pre_value, 'operator': operator})
                self.assertEqual(filter_value.to_sql_values(), {})
                self.assertEqual(
                    str(filter_value.to_sql_filter().build_expression()),
                    'exists_field IS NOT NULL'
                )

    def test_pre_filter_value_array(self):
        pre_value = ['yes', 'maybe']
        filter_ = {
            'type': 'pre',
            'field': 'at_risk_field',
            'slug': 'at_risk_slug',
            'datatype': 'array',
            'pre_value': pre_value
        }
        filter_value = PreFilterValue(filter_, {'operand': pre_value})
        self.assertEqual(filter_value.to_sql_values(), {'at_risk_slug_0': 'yes', 'at_risk_slug_1': 'maybe'})
        self.assertEqual(
            str(filter_value.to_sql_filter().build_expression()),
            'at_risk_field IN (:at_risk_slug_0, :at_risk_slug_1)'
        )

    def test_pre_filter_operator(self):
        value = {'operator': '<=', 'operand': '99'}
        filter_ = ReportFilterFactory.from_spec({
            'type': 'pre',
            'field': 'risk_indicator_field',
            'slug': 'risk_indicator_slug',
            'datatype': 'integer',
            'pre_value': value['operand'],
            'pre_operator': value['operator'],
        })
        self.assertEqual(type(filter_), PreFilter)
        self.assertEqual(filter_.default_value(), {'operator': '<=', 'operand': 99})  # operand will be coerced

    def test_pre_filter_invalid_operator(self):
        value = {'operator': 'in', 'operand': 'no'}  # "in" is invalid for scalar operand
        filter_ = {
            'type': 'pre',
            'field': 'at_risk_field',
            'slug': 'at_risk_slug',
            'datatype': 'string',
            'pre_value': value['operand'],
            'pre_operator': value['operator'],
        }
        filter_value = PreFilterValue(filter_, value)
        with self.assertRaises(TypeError):
            filter_value.to_sql_filter()

    def test_pre_filter_between_operator(self):
        value = {'operator': 'between', 'operand': ['2017-03-13', '2017-04-11']}
        filter_ = {
            'type': 'pre',
            'field': 'dob_field',
            'slug': 'dob_slug',
            'datatype': 'date',
            'pre_value': value['operand'],
            'pre_operator': value['operator'],
        }
        filter_value = PreFilterValue(filter_, value)
        self.assertEqual(filter_value.to_sql_values(), {'dob_slug_0': '2017-03-13', 'dob_slug_1': '2017-04-11'})
        self.assertEqual(
            str(filter_value.to_sql_filter().build_expression()),
            'dob_field BETWEEN :dob_slug_0 AND :dob_slug_1'
        )

    def test_pre_filter_distinct_from_operator(self):
        value = {'operator': 'distinct from', 'operand': 'test'}
        filter_ = {
            'type': 'pre',
            'field': 'at_risk_field',
            'slug': 'at_risk_slug',
            'datatype': 'string',
            'pre_value': value['operand'],
            'pre_operator': value['operator'],
        }
        filter_value = PreFilterValue(filter_, value)
        self.assertEqual(filter_value.to_sql_values(), {'at_risk_slug': 'test'})

    def test_pre_filter_dyn_operator(self):
        from corehq.apps.reports.daterange import get_daterange_start_end_dates
        start_date, end_date = get_daterange_start_end_dates('lastmonth')

        value = {'operator': 'lastmonth', 'operand': [None]}
        filter_ = {
            'type': 'pre',
            'field': 'dob_field',
            'slug': 'dob_slug',
            'datatype': 'array',
            'pre_value': value['operand'],
            'pre_operator': value['operator'],
        }
        filter_value = PreFilterValue(filter_, value)
        self.assertEqual(filter_value.to_sql_values(), {
            'dob_slug_0': str(start_date),
            'dob_slug_1': str(end_date),
        })
        self.assertEqual(
            str(filter_value.to_sql_filter().build_expression()),
            'dob_field BETWEEN :dob_slug_0 AND :dob_slug_1'
        )

class ChoiceListFilterTestCase(SimpleTestCase):
    CHOICES = [
        {
            "value": "NEGATIVE",
            "display": "negative"
        },
        {
            "value": "POSITIVE",
            "display": "positive"
        }
    ]

    def test_choice_list_filter(self):
        filter = ReportFilterFactory.from_spec({
            "type": "choice_list",
            "slug": "diagnosis_slug",
            "field": "diagnosis_field",
            "display": "Diagnosis",
            "choices": self.CHOICES,
            "show_all": False,
        })
        self.assertEqual(ChoiceListFilter, type(filter))
        self.assertEqual('diagnosis_slug', filter.name)
        self.assertEqual('Diagnosis', filter.label)
        self.assertEqual(2, len(filter.choices))
        for i, choice in enumerate(self.CHOICES):
            self.assertEqual(filter.choices[i].value, choice['value'])
            self.assertEqual(filter.choices[i].display, choice['display'])

        # check values
        self.assertEqual('positive', filter.value(diagnosis_slug='POSITIVE').display)

    def test_choice_list_filter_show_all(self):
        filter = ReportFilterFactory.from_spec({
            "type": "choice_list",
            "slug": "diagnosis_slug",
            "field": "diagnosis_field",
            "display": "Diagnosis",
            "choices": self.CHOICES,
            "show_all": True,
        })
        self.assertEqual(3, len(filter.choices))

        self.assertEqual(SHOW_ALL_CHOICE, filter.choices[0].value)
        for i, choice in enumerate(self.CHOICES):
            self.assertEqual(filter.choices[i + 1].value, choice['value'])
            self.assertEqual(filter.choices[i + 1].display, choice['display'])

        # check all value
        self.assertEqual('Show all', filter.value(diagnosis_slug=SHOW_ALL_CHOICE).display)

    def test_choice_list_filter_with_integers(self):
        choices = [
            {
                "value": 0,
                "display": "negative"
            },
            {
                "value": 1,
                "display": "positive"
            }
        ]
        filter = ReportFilterFactory.from_spec({
            "type": "choice_list",
            "slug": "diagnosis_slug",
            "field": "diagnosis_field",
            "datatype": "integer",
            "display": "Diagnosis",
            "choices": choices,
            "show_all": True,
        })
        self.assertEqual(ChoiceListFilter, type(filter))
        self.assertEqual('diagnosis_slug', filter.name)
        self.assertEqual('Diagnosis', filter.label)
        self.assertEqual(3, len(filter.choices))
        non_all_choices = filter.choices[1:]
        for i, choice in enumerate(choices):
            self.assertEqual(non_all_choices[i].value, choice['value'])
            self.assertEqual(non_all_choices[i].display, choice['display'])

        # ensure integer values work
        self.assertEqual('positive', filter.value(diagnosis_slug=1).display)
        # ensure 0 integer value works
        self.assertEqual('negative', filter.value(diagnosis_slug=0).display)
        # check string to int coercion
        self.assertEqual('positive', filter.value(diagnosis_slug='1').display)
        # ensure 0 string to int works
        self.assertEqual('negative', filter.value(diagnosis_slug='0').display)

        # check missing values raise errors
        with self.assertRaises(FilterValueException):
            filter.value(diagnosis_slug='4')

        # check non-integers raise errors
        with self.assertRaises(FilterValueException):
            filter.value(diagnosis_slug='foo')

        # check that all still works
        self.assertEqual('Show all', filter.value(diagnosis_slug=SHOW_ALL_CHOICE).display)

class DynamicChoiceListFilterTestCase(SimpleTestCase):

    def setUp(self):
        self.filter_spec = {
            "type": "dynamic_choice_list",
            "slug": "dynoslug",
            "field": "dynofield",
            "display": "Dynamic choice list",
            "show_all": False,
        }

    def test_choice_list_filter(self):
        filter = ReportFilterFactory.from_spec(self.filter_spec)
        self.assertEqual(DynamicChoiceListFilter, type(filter))
        self.assertEqual('dynoslug', filter.name)
        self.assertEqual('Dynamic choice list', filter.label)

    def test_string_datatype(self):
        self.filter_spec['datatype'] = 'string'
        filter = ReportFilterFactory.from_spec(self.filter_spec)
        tests = (
            ('1', '1'),
            ('1.2', '1.2'),
            ('hello', 'hello'),
        )
        for input, expected in tests:
            choices = filter.value(dynoslug=input)
            self.assertEqual(len(choices), 1)
            self.assertEqual(expected, choices[0].value)
            self.assertEqual(input, choices[0].display)

    def test_integer_datatype(self):
        self.filter_spec['datatype'] = 'integer'
        filter = ReportFilterFactory.from_spec(self.filter_spec)
        tests = (
            ('1', 1, '1'),
            ('1.2', 1, '1'),
            ('hello', None, ''),
        )
        for input, expected_value, expected_display in tests:
            choices = filter.value(dynoslug=input)
            self.assertEqual(len(choices), 1)
            self.assertEqual(expected_value, choices[0].value)
            self.assertEqual(expected_display, choices[0].display)

    def test_multiple_selections(self):
        self.filter_spec["datatype"] = "string"
        filter = ReportFilterFactory.from_spec(self.filter_spec)
        test_cases = (
            ['apple'],
            ['apple', 'banana'],
            ['apple', 'banana', 'carrot'],
        )
        choices = [
            Choice('apple', 'apple'),
            Choice('banana', 'banana'),
            Choice('carrot', 'carrot')
        ]
        for i, s in enumerate(test_cases):
            self.assertListEqual(choices[0:i + 1], filter.value(dynoslug=s))

    def test_ancestor_expression(self):
        filter = {
            "type": "dynamic_choice_list",
            "slug": "dynoslug",
            "field": "dynofield",
            "display": "Dynamic choice list",
            "show_all": False,
            "choice_provider": {"type": "user"},
            "ancestor_expression": {
                "field": "state_id",
                "location_type": "state",
            }
        }

        with self.assertRaises(BadSpecError):
            ReportFilterFactory.from_spec(filter)
        filter['choice_provider']['type'] = 'location'
        ReportFilterFactory.from_spec(filter)

class DateFilterOffsetTest(SimpleTestCase):
    def _computed_dates(self, actual_startdate, actual_enddate):
        filter = {
            'compare_as_string': False,
            'field': 'submission_date',
            'slug': 'submitted_on',
            'type': 'date',
            'required': False
        }
        value = DateSpan(actual_startdate, actual_enddate)
        filter_value = DateFilterValue(filter, value)
        computed_values = filter_value.to_sql_values()
        startdate = computed_values['%s_startdate' % filter['slug']]
        enddate = computed_values['%s_enddate' % filter['slug']]
        return startdate, enddate

    def test_date_objects(self):
        start, end = date(2015, 1, 1), date(2015, 1, 2)
        computed_start, computed_end = self._computed_dates(start, end)
        self.assertEqual(computed_start, start)
        self.assertEqual(computed_end, datetime.combine(end, datetime.max.time()))

    def test_datetime_objects(self):
        # computed_enddate should be last minute of the enddate
        start, end = datetime(2015, 1, 1), datetime(2015, 1, 2)
        computed_start, computed_end = self._computed_dates(start, end)
        self.assertEqual(computed_start, start)
        self.assertEqual(computed_end, datetime.combine(end, datetime.max.time()))
        self.assertEqual((computed_end - end).days, 0)

class LocationDrilldownFilterTest(LocationHierarchyTestCase):
    location_type_names = ['state', 'county', 'city']
    location_structure = [
        ('Massachusetts', [
            ('Middlesex', [
                ('Cambridge', []),
                ('Somerville', []),
            ]),
            ('Suffolk', [
                ('Boston', []),
            ])
        ])
    ]

    @classmethod
    def setUpClass(cls):
        cls.user = CommCareUser.create(cls.domain, 'test1', 'test123', None, None)
        super(LocationDrilldownFilterTest, cls).setUpClass()

    def test_filter(self):
        report = ReportConfiguration(domain=self.domain)
        ui_filter = ReportFilterFactory.from_spec({
            "slug": "block_id_drill",
            "type": "location_drilldown",
            "field": "block_id",
            "display": "Drilldown by Location",
            "include_descendants": False,
        }, report)

        self.assertEqual(type(ui_filter), LocationDrilldownFilter)

        # test filter_context
        filter_context_expected = {
            'input_name': 'block_id_drill',
            'loc_id': None,
            'hierarchy': location_hierarchy_config(self.domain),
            'locations': load_locs_json(self.domain),
            'loc_url': '/a/{}/api/v0.5/location_internal/'.format(self.domain),
            'max_drilldown_levels': 99,
            'auto_drill': 'false',
        }
        self.assertDictEqual(ui_filter.filter_context(self.user), filter_context_expected)

        # test include_descendants=False
        self.assertListEqual(
            ui_filter.value(
                **{ui_filter.name: self.locations.get('Middlesex').location_id, REQUEST_USER_KEY: self.user}
            ),
            [self.locations.get('Middlesex').location_id]
        )

        # test include_descendants=True
        ui_filter = ReportFilterFactory.from_spec({
            "slug": "block_id_drill",
            "type": "location_drilldown",
            "field": "block_id",
            "display": "Drilldown by Location",
            "include_descendants": True,
        }, report)
        self.assertListEqual(
            ui_filter.value(
                **{ui_filter.name: self.locations.get('Middlesex').location_id, REQUEST_USER_KEY: self.user}
            ),
            [self.locations.get(name).location_id
             for name in ['Middlesex', 'Cambridge', 'Somerville']]
        )

    def test_filter_value(self):
        filter = {
            "type": "location_drilldown",
            "field": "block_id",
            "slug": "block_id_drill",
            "display": "Drilldown by Location",
        }
        filter_value = LocationDrilldownFilterValue(filter, ['Middlesex'])
        self.assertDictEqual(filter_value.to_sql_values(), {'block_id_drill_0': 'Middlesex'})
        self.assertEqual(
            str(filter_value.to_sql_filter().build_expression()),
            'block_id IN (:block_id_drill_0)'
        )
        self.assertEqual(
            filter_value.to_sql_values(),
            {'block_id_drill_0': 'Middlesex'}
        )

    def test_ancestor_expression_missing_location_type(self):
        with self.assertRaises(BadSpecError):
            ReportFilterFactory.from_spec({
                "type": "location_drilldown",
                "field": "block_id",
                "slug": "block_id_drill",
                "display": "Drilldown by Location",
                "ancestor_expression": {
                    'field': 'state_id',
                    # missing 'location_type': 'state',
                }
            })

    def test_prefix_ancestor_location(self):
        filter = {
            "type": "location_drilldown",
            "field": "block_id",
            "slug": "block_id_drill",
            "display": "Drilldown by Location",
            "ancestor_expression": {
                'field': 'state_id',
                'location_type': 'state',
            }
        }
        middlesex_id = self.locations['Middlesex'].location_id
        mass_id = self.locations['Massachusetts'].location_id
        # make sure ancestor gets passed if right block is passed
        filter_value = LocationDrilldownFilterValue(filter, [middlesex_id])
        self.assertEqual(
            str(filter_value.to_sql_filter().build_expression()),
            'state_id = :state_id AND block_id IN (:block_id_drill_0)'
        )
        self.assertEqual(
            filter_value.to_sql_values(),
            {'state_id': mass_id, 'block_id_drill_0': middlesex_id}
        )
        # make sure ancestor doesn't get passed if multiple locations are passed
        filter_value = LocationDrilldownFilterValue(filter, [middlesex_id, 'Suffolk'])
        self.assertEqual(
            str(filter_value.to_sql_filter().build_expression()),
            'block_id IN (:block_id_drill_0, :block_id_drill_1)'
        )
        self.assertEqual(
            filter_value.to_sql_values(),
            {'block_id_drill_0': middlesex_id, 'block_id_drill_1': 'Suffolk'}
        )
        # no ancestor is passed if passed in location is invalid
        filter_value = LocationDrilldownFilterValue(filter, ['random'])
        self.assertEqual(
            str(filter_value.to_sql_filter().build_expression()),
            'block_id IN (:block_id_drill_0)'
        )
        self.assertEqual(
            filter_value.to_sql_values(),
            {'block_id_drill_0': 'random'}
        )

class QueryDictUtilTest(SimpleTestCase):
    def test_raw_boolean_strings_are_not_cast(self):
        request_dict = query_dict_to_dict(QueryDict(urlencode(
            {'my_string_key': 'true', 'another_string': 'false', 'non_string': 'true',
             'non_string_2': 'false', 'string_int': '1', 'non_string_int': '2', 'apple': 'orange'})),
            "some_domain",
            ['my_string_key', 'another_string', 'string_int']
        )
        self.assertDictEqual(
            request_dict,
            {
                # keys marked as string should not be casted to bool
                'apple': 'orange',
                'my_string_key': 'true',
                'another_string': 'false',
                'string_int': '1',
                # keys not marked as string are casted to bool
                'non_string': True,
                'non_string_2': False,
                'domain': 'some_domain',
                'non_string_int': 2,
            }
        )


import numpy as np
import matplotlib.pyplot as plt
from math import log
from math import pow
from matplotlib.ticker import FuncFormatter
import matplotlib

def to_percent(y, position):
    # Ignore the passed in position. This has the effect of scaling the default
    # tick locations.
    s = str(100 * y)

    # The percent symbol needs escaping in latex
    if matplotlib.rcParams['text.usetex'] == True:
        return s + r'$\%$'
    else:
        return s + '%'

def entropy(kill1, kill2, die1, die2):
	e = []
	for i in range(len(kill1)):
		e += [eval_entropy(kill1[i], kill2[i], die1[i], die2[i])]
	return e

def eval_entropy(kill_1, kill_2, die_1, die_2):
	kill1 = kill_1
	kill2 = kill_2
	total = kill1 + kill2

	e1 = kill1/total*log(kill1/total, 2) if kill1 != 0 else 0
	e2 = kill2/total*log(kill2/total,2) if kill2 != 0 else 0

	e = -(e1 + e2)

	#e += total/40
	#e += pow(0.9, suicides)

	return e

def main():

	statistics_file = open("statistics.txt", "r")

	content = statistics_file.readlines()

	i = 0

	statistics = {}
	data = [[] for _ in range(8)]

	for string in content:
		if "[" in string:
			split_spaces = string.split(" ")
			for splitted in split_spaces :
				splitted = splitted.replace("[", "")
				splitted = splitted.replace("]", "")
				splitted = splitted.replace(",", "")
				splitted = splitted.replace("\n", "")
				try:
					val = int(splitted)
				except :
					val = float(splitted)
				data[i] += [val]

			i += 1
			if i == 8 :
				i = 0

	statistics.update({0 : data[:4]})
	statistics.update({1 : data[4:]})

	plt.figure(figsize=(16, 9))

	#plt.subplot(221)
	#plt.title("time kill")
	#plt.boxplot([val[0] for key, val in statistics.items()], labels=[str(i + 1) + "° weapon" for i in range(2)])
	plt.subplot(221)
	plt.title("distance")
	plt.ylabel("Unreal Unit")
	plt.boxplot([val[1] for key, val in statistics.items()], labels=[str(i + 1) + "° weapon" for i in range(2)])
	plt.subplot(222)
	plt.title("kill streak")
	plt.ylabel("Kill")
	plt.boxplot([val[2] for key, val in statistics.items()], labels=[str(i + 1) + "° weapon" for i in range(2)])
	plt.subplot(223)
	plt.title("precision")
	formatter = FuncFormatter(to_percent)
	plt.boxplot([val[3] for key, val in statistics.items()], labels=[str(i + 1) + "° weapon" for i in range(2)])
	plt.gca().yaxis.set_major_formatter(formatter)

	plt.savefig("statistics.png", bbox_inches='tight', dpi = 200)
	plt.close()

main()


# test code for trimming stuff

from pydub import AudioSegment

def detect_leading_silence(sound, silence_threshold=-50.0, chunk_size=10):
    '''
    sound is a pydub.AudioSegment
    silence_threshold in dB
    chunk_size in ms

    iterate over chunks until you find the first one with sound
    '''
    trim_ms = 0 # ms

    assert chunk_size > 0 # to avoid infinite loop
    print(sound[trim_ms:trim_ms+chunk_size].dBFS)
    while sound[trim_ms:trim_ms+chunk_size].dBFS < silence_threshold and trim_ms < len(sound):
        trim_ms += chunk_size
        print(sound[trim_ms:trim_ms+chunk_size].dBFS)

    return trim_ms

def print_db_values(sound, silence_threshold=-50.0, chunk_size=10):
    '''
    sound is a pydub.AudioSegment
    silence_threshold in dB
    chunk_size in ms

    iterate over chunks until you find the first one with sound
    '''
    trim_ms = 0 # ms

    assert chunk_size > 0 # to avoid infinite loop
    while trim_ms < len(sound):
        trim_ms += chunk_size
        print(sound[trim_ms:trim_ms+chunk_size].dBFS)

sound = AudioSegment.from_file("test1.wav", format="wav")

print_db_values(sound)

print("leading")
start_trim = detect_leading_silence(sound)
print("reverse")
end_trim = detect_leading_silence(sound.reverse())

duration = len(sound)
trimmed_sound = sound[start_trim:duration-end_trim]


from flask import Blueprint, jsonify, request, session, redirect, url_for, send_file

from werkzeug.utils import secure_filename
from app import db
import os

api = Blueprint('api', __name__, url_prefix="/api")

UPLOAD_FOLDER = os.path.abspath("app/static/attachments")

@api.route("/execute", methods=["POST"])
def execute():
    try:
        code = request.json.get("code")
        result = db.engine.execute(code).all()
        if len(result) == 0:
            return jsonify({
                "status": "no_result"
            }), 200
        else:
            keys, values = result[0].keys()._keys, []
            for result_obj in result:
                temp_values = []
                for result_value in result_obj:
                    temp_values.append(result_value)
                values.append(temp_values)
            return jsonify({
                "status": "success",
                "keys": keys,
                "values": values
            }), 200
    except Exception as e:
        return jsonify({
            "status": "error",
            "message": str(e)
        }), 400

@api.route("/get-customer")
def get_customer():
    try:
        customer_id = request.args.get("id")
        query = f"select * from customers where id={customer_id}"
        customer = db.engine.execute(query).first()
        return jsonify({
            "status": "success",
            "data": {
                "first_name": customer["first_name"],
                "last_name": customer["last_name"],
                "company_name": customer["company_name"],
                "address": customer["address"],
                "city": customer["city"],
                "county": customer["county"],
                "state": customer["state"],
                "zip_code": customer["zip_code"],
                "phone_1": customer["phone_1"],
                "phone_2": customer["phone_2"],
                "email": customer["email"],
                "web": customer["web"]
            }
        }), 200
    except Exception as e:
        return jsonify({
            "status": "error",
            "message": str(e)
        }), 400


import pytest
from h_matchers import Any

from checkmatelib.url import Domain
from checkmatelib.url.domain.enums import SuffixType

class TestDomain:
    # These methods are quite often really just combinations of other things
    # so we'll be giving some a quite light touch

    @pytest.mark.parametrize(
        "domain,is_public",
        (
            ("www.example.com", True),
            ("  www.whitespace.com", True),
            ("216.58.212.206", True),
            ("192.168.34.11", False),
            ("bad.-hyphen.com", False),
            ("plausable.but-wrong.dato", False),
            ("random_hostname", False),
            ("<html>", False),
        ),
    )
    def test_is_public(self, domain, is_public):
        assert Domain(domain).is_public == is_public

    @pytest.mark.parametrize(
        "domain,is_fqdn",
        (
            ("com", False),
            ("co.uk", False),
            ("more.com", True),
            ("www.example.com", True),
            ("  www.whitespace.com", True),
            ("216.58.212.206", False),  # IPs are not fully qualified
            ("bad.-hyphen.com", False),
            ("plausable.but-wrong.dato", False),
            ("random_hostname", False),
            ("<html>", False),
        ),
    )
    def test_is_fully_qualified(self, domain, is_fqdn):
        assert Domain(domain).is_fully_qualified == is_fqdn

    @pytest.mark.parametrize(
        "domain,tld",
        (
            ("www.example.com", "com"),
            ("com", "com"),
            ("www.example.not_a_tld", None),
            ("10.0.0.1", None),
        ),
    )
    def test_tld(self, domain, tld):
        assert Domain(domain).tld == tld

    @pytest.mark.parametrize(
        "domain,public_suffix",
        (
            ("com", "com"),
            ("co.uk", "co.uk"),
            ("www.example.com", "com"),
            ("www.example.co.uk", "co.uk"),
            ("page.github.io", "github.io"),
            ("nonsense", None),
            ("10.0.0.1", None),
        ),
    )
    def test_public_suffix(self, domain, public_suffix):
        assert Domain(domain).public_suffix == public_suffix

    @pytest.mark.parametrize(
        "domain,icann_suffix",
        (
            ("com", "com"),
            ("co.uk", "co.uk"),
            ("www.example.com", "com"),
            ("www.example.co.uk", "co.uk"),
            ("page.github.io", "io"),
            ("nonsense", None),
            ("10.0.0.1", None),
        ),
    )
    def test_icann_suffix(self, domain, icann_suffix):
        assert Domain(domain).icann_suffix == icann_suffix

    @pytest.mark.parametrize(
        "domain,suffix_type",
        (
            ("com", SuffixType.ICANN),
            ("www.example.com", SuffixType.ICANN),
            ("www.example.co.uk", SuffixType.ICANN),
            ("page.github.io", SuffixType.PRIVATE),
            ("github.io", SuffixType.PRIVATE),
            ("nonsense", None),
            ("10.0.0.1", None),
        ),
    )
    def test_suffix_type(self, domain, suffix_type):
        assert Domain(domain).suffix_type == suffix_type

    @pytest.mark.parametrize(
        "domain,icann_only,sub_domains,root_domain",
        (
            ("www.example.com", False, ["www"], "example.com"),
            ("a.page.github.io", False, ["a"], "page.github.io"),
            ("github.io", False, [], "github.io"),
            ("a.page.github.io", True, ["a", "page"], "github.io"),
            # Lets say IPs are their own root domain
            ("10.0.0.1", False, [], "10.0.0.1"),
            # Is there any sensible way to deal with things without public
            # suffixes? We don't know where to start or stop here
            ("my_home_pc", False, [], "my_home_pc"),
            ("a.b.c.d.e.my_home_pc.local", False, [], "a.b.c.d.e.my_home_pc.local"),
        ),
    )
    def test_split_domain(self, domain, icann_only, sub_domains, root_domain):
        values = Domain(domain).split_domain(icann_only)

        assert values == (sub_domains, root_domain)

    @pytest.mark.parametrize(
        "domain,root_domain",
        (
            ("www.example.com", "example.com"),
            ("www2.example.com", "example.com"),
            ("a.b.example.com", "example.com"),
            ("a.b.c.page.github.io", "page.github.io"),
            # Lets say IPs are their own root domain
            ("10.0.0.1", "10.0.0.1"),
            # Is there any sensible way to deal with things without public
            # suffixes? We don't know where to start or stop here
            ("my_home_pc", "my_home_pc"),
            ("a.b.c.d.e.my_home_pc.local", "a.b.c.d.e.my_home_pc.local"),
        ),
    )
    def test_root_domain(self, domain, root_domain):
        assert Domain(domain).root_domain == root_domain

    def test_as_dict(self):
        # Not really going to go to town on this just yet, the exact contents
        # aren't used by anyone. It's just a good way to dump them right now.
        assert Domain("www.example.com").as_dict() == Any.dict()


from django.urls import path
from base.views import product_views as views

urlpatterns = [
    path("getproducts/", views.getProducts, name="get-products"),
    path("register/", views.register, name="register"),
    path("getproduct/<str:pk>/", views.getProduct, name="get-product"),
    path("update/<str:pk>/", views.update, name="update-product"),
    path("delete/<str:pk>/", views.delete, name="delete-product"),
    path("search/<str:querie>/", views.search, name="search-product"),
]


import json
from difflib import get_close_matches

data = json.load(open("data.json"))

def translate(w):
    w = w.lower()
    if w in data:
        return data[w]
    elif len(get_close_matches(w, data.keys())) > 0:
        valid = input(f"Did you mean %s instead of {w}. Please write Y for yes and N for no." %get_close_matches(w, data.keys())[0])
        if valid == "Y":
            return get_close_matches(w, data.keys())[0]
        elif valid == "N":
            return "We can't understand you."
        else:
            return "Try a valid word"
    else:
        return "You inseted an invalid word.."

user_word = input("Write a word: ")
output = translate(user_word)

if type(output) == list:
    for item in output:
        print(item)
else:
    print(output)


from gpiozero import DistanceSensor
from time import sleep

sensor1 = DistanceSensor(echo=22, trigger=11)
sensor = DistanceSensor(echo=24, trigger=25)
#18 and 23
#17and 4
#22 and 11
#24 and 25
while True:
    x = sensor.distance
    y = sensor1.distance

    print("Right")
    print (x)
    print("lLeft")
    print (y)
    print("\n")

    sleep(1)


import matplotlib
matplotlib.use('Agg')
from matplotlib.pylab import *
from skimage.feature import greycomatrix, greycoprops
from sklearn.metrics.cluster import entropy
import numpy as np
import cv2
import csv
import math
import scipy.spatial.distance as dist
from PIL import Image
import skimage.io

root_path = '/static/content/'
UPLOAD_FOLDER = '/static/uploads/'

def colorQuantization(colorChannelImage, bins, max_color=255):
    # ubah varian warna menjadi varian bins
    quant = np.array(colorChannelImage) * (bins / max_color)
    quant = np.floor(quant)
    quant[quant >= bins] = bins - 1

    return quant

def combineColorQuantization(image, B_bins, G_bins, R_bins):
    # extrak matrix dari color channel image
    B = image[:, :, 0]
    G = image[:, :, 1]
    R = image[:, :, 2]

    # kuantisasikan tiap color channel
    B_quant = colorQuantization(B, B_bins)  # bisa coba diganti dengan K-Means
    G_quant = colorQuantization(G, G_bins)
    R_quant = colorQuantization(R, R_bins)

    # menggabungkan kuantisasi warna
    combine_quant = (B_bins * G_bins * R_quant) + (B_bins * G_quant) + B_quant

    return combine_quant

def edgeQuantization(image, binsTheta):
    # extrak matrix dari color channel image
    B = image[:, :, 0]
    G = image[:, :, 1]
    R = image[:, :, 2]

    # simplementasi sobel
    Bx = cv2.Sobel(B, cv2.CV_64F, 1, 0, ksize=3)
    By = cv2.Sobel(B, cv2.CV_64F, 0, 1, ksize=3)
    Gx = cv2.Sobel(G, cv2.CV_64F, 1, 0, ksize=3)
    Gy = cv2.Sobel(G, cv2.CV_64F, 0, 1, ksize=3)
    Rx = cv2.Sobel(R, cv2.CV_64F, 1, 0, ksize=3)
    Ry = cv2.Sobel(R, cv2.CV_64F, 0, 1, ksize=3)

    # get |a| and |b|
    a = sqrt(Bx ** 2 + Gx ** 2 + Rx ** 2)
    b = sqrt(By ** 2 + Gy ** 2 + Ry ** 2)

    # get ab
    ab = (Bx * By) + (Gx * Gy) + (Rx * Ry)

    # image orientation
    (h, w) = a.shape
    # binsTheta = 18
    theta = np.zeros((h, w))

    # edge quantization
    for i in range(0, h):
        for j in range(0, w):
            if (a[i, j] == 0 or b[i, j] == 0):
                cosab1 = 0
            else:
                cosab1 = ab[i, j] / (a[i, j] * b[i, j])
            theta1 = math.degrees(np.arccos(cosab1))
            if (math.isnan(theta1)):
                theta1 = 0
            theta[i, j] = math.floor(theta1 * (binsTheta / 180))
            if (theta[i, j] >= binsTheta - 1):
                theta[i, j] = binsTheta - 1

    return np.array(theta)

def textonSearch(colorQuant, cBins, edgeQuant, eBins):
    # tentukan bentuk dari citra
    (h, w) = colorQuant.shape

    # untuk menangani image yang dimensinya ganjil
    if (h % 2 == 1):
        a = np.zeros((h + 1, w))
        colorQuant = colorQuant[:-1, :]
        edgeQuant = edgeQuant[:-1, :]

    if (w % 2 == 1):
        a = np.zeros((h, w + 1))
        colorQuant = colorQuant[:, :-1]
        edgeQuant = edgeQuant[:, :-1]

    (h, w) = colorQuant.shape
    color_img = np.zeros((h, w))
    edge_img = np.zeros((h, w))

    # sliding window check for all color channel
    for i in range(0, h, 2):
        for j in range(0, w, 2):

            # texton search for color
            cTemp = colorQuant[i:i + 2, j:j + 2]
            if (cTemp[0, 0] == cTemp[0, 1]):  # texton type 1
                color_img[i, j] = colorQuant[i, j]
                color_img[i, j + 1] = colorQuant[i, j + 1]
            if (cTemp[0, 0] == cTemp[1, 0]):  # texton type 2
                color_img[i, j] = colorQuant[i, j]
                color_img[i + 1, j] = colorQuant[i + 1, j]
            if (cTemp[0, 0] == cTemp[1, 1]):  # texton type 3
                color_img[i, j] = colorQuant[i, j]
                color_img[i + 1, j + 1] = colorQuant[i + 1, j + 1]
            if (cTemp[1, 0] == cTemp[1, 1]):  # texton type 4
                color_img[i + 1, j] = colorQuant[i + 1, j]
                color_img[i + 1, j + 1] = colorQuant[i + 1, j + 1]
            if (cTemp[0, 1] == cTemp[1, 1]):  # texton type 5
                color_img[i, j + 1] = colorQuant[i, j + 1]
                color_img[i + 1, j + 1] = colorQuant[i + 1, j + 1]
            if (cTemp[0, 1] == cTemp[1, 0]):  # texton type 6
                color_img[i, j + 1] = colorQuant[i, j + 1]
                color_img[i + 1, j] = colorQuant[i + 1, j]

            # pencarian garis tepi menggunakan texton
            eTemp = edgeQuant[i:i + 2, j:j + 2]
            if (eTemp[0, 0] == eTemp[0, 1]):  # texton type 1
                edge_img[i, j] = edgeQuant[i, j]
                edge_img[i, j + 1] = edgeQuant[i, j + 1]
            if (eTemp[0, 0] == eTemp[1, 0]):  # texton type 2
                edge_img[i, j] = edgeQuant[i, j]
                edge_img[i + 1, j] = edgeQuant[i + 1, j]
            if (eTemp[0, 0] == eTemp[1, 1]):  # texton type 3
                edge_img[i, j] = edgeQuant[i, j]
                edge_img[i + 1, j + 1] = edgeQuant[i + 1, j + 1]
            if (eTemp[1, 0] == eTemp[1, 1]):  # texton type 4
                edge_img[i + 1, j] = edgeQuant[i + 1, j]
                edge_img[i + 1, j + 1] = edgeQuant[i + 1, j + 1]
            if (eTemp[0, 1] == eTemp[1, 1]):  # texton type 5
                edge_img[i, j + 1] = edgeQuant[i, j + 1]
                edge_img[i + 1, j + 1] = edgeQuant[i + 1, j + 1]
            if (eTemp[0, 1] == eTemp[1, 0]):  # texton type 6
                edge_img[i, j + 1] = edgeQuant[i, j + 1]
                edge_img[i + 1, j] = edgeQuant[i + 1, j]

    # make color histogram
    cF = np.histogram(color_img.ravel(), cBins, [0, 64])
    colorFeatures = (np.array(cF[0]) / 6)  # perlu dibagi dg 6 meyesuaikan dg jumlah type texton yg digunakan

    # make edge histogram
    eF = np.histogram(edge_img.ravel(), eBins, [0, 18])
    edgeFeatures = (np.array(eF[0]) / 6)

    # combine color and edge features
    features = []
    features.extend(colorFeatures)
    features.extend(edgeFeatures)

    return features

def GLCM(image):
    # convert iamge to greyscale
    grey_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # make co-occurance matrix
    gm = greycomatrix(grey_img, [1], [0, np.pi / 4, np.pi / 2, 3 * np.pi / 4], levels=256, normed=True)
    (h, w) = gm[:, :, 0, 0].shape

    glcm_features = []

    # calculate energy, contrast, correlation, entropy
    # using scikit library

    energy = greycoprops(gm, 'energy')
    contrast = greycoprops(gm, 'contrast')
    correlation = greycoprops(gm, 'correlation')
    glcm_features.extend(energy.tolist())
    glcm_features.extend(contrast.tolist())
    glcm_features.extend(correlation.tolist())

    entropy = []
    for i in range(0, 4):
        e = np.abs(gm[:, :, 0, i] * np.log2(gm[:, :, 0, i]))
        e[isnan(e)] = 0
        entropy.append(sum(e))

    return glcm_features, entropy

class Searcher:
    def __init__(self, indexPath):
        # store the index path
        self.indexPath = indexPath

    def search(self, queryFeatures, limit=12):
        # initialize our dictionary of results
        results = {}

        # open the index file for reading
        with open(self.indexPath) as f:
            # initialize the csv reader
            reader = csv.reader(f)

            # loop over the rows in the index
            for row in reader:
                # parse out the image ID and features, then compute the chi-squared
                # distance between the features in our index and our query features
                features = [float(x) for x in row[1:]]
                d = self.canberra_distance(features, queryFeatures)

                # now that we have the distance between the two feature vectors,
                # we can update the result dictionary -- the key is the current
                # image ID in the index and the value is the distance we just
                # computed, representing how 'similar' the image in the index is to our query
                results[row[0]] = d

            # close the reader
            f.close()

        # sort our results, so that the smaller distance (i.e. the more relevant images
        # are at the front of the list)
        results = sorted([(v, k) for (k, v) in results.items()])

        # return our (limited) results
        return results[:limit]

    def canberra_distance(self, histA, histB):
        # d = dist.canberra(histA, histB)

        # modified canberra
        M = len(histA)
        mA = mean(histA)
        mB = mean(histB)
        d = 0
        for i in range(0, M):
            d = d + (abs(histA[i] - histB[i]) /
                     ((abs(histA[i] + mA) + abs(histB[i] + mB))))

        return d

def process_file(path):

    # Define path of testing data and indexing file
    queryPath = path
    index_file = 'static/data/mtcd_full.csv'

    # define the bins for quantization
    colorBins = 64
    R_Bins = 4
    G_Bins = 4
    B_Bins = 4
    edgeBins = 18
    query = cv2.imread(queryPath)

    # Color Quantization
    colorQuant = combineColorQuantization(query, B_Bins, G_Bins, R_Bins)

    # Edge Quantization
    edgeQuant = edgeQuantization(query, edgeBins)

    # Texton Search
    features = textonSearch(colorQuant, colorBins, edgeQuant, edgeBins)

    # GLCM
    glcm, en = GLCM(query)
    features.extend(glcm[0])
    features.extend(glcm[1])
    features.extend(glcm[2])
    features.extend(en)

    # perform the search
    searcher = Searcher(index_file)
    results = searcher.search(features)

    # display the query
    fig = figure(figsize=(5, 5))
    title('Query Image')
    imshow(array(Image.open(queryPath)))
    axis('off')

    # loop over the results
    fig = figure(num=None, figsize=(20, 5))
    title('Result Image')
    i = 1
    result = []
    trowReslut = 'static/result/'

    for (score, resultID) in results:
        # load the result image and display it
        a = fig.add_subplot(2, 6, i)
        image = skimage.io.imread("static/"+resultID)
        imshow(image)
        result.append(cv2.imwrite(trowReslut + 'res' + str(i) + '.jpg', cv2.cvtColor(image, cv2.COLOR_BGR2RGB)))
        i += 1
        axis('off')
    return result


import pandas as pd
CD_data=pd.read_csv('E:\python\CD_DLC.csv')
#pd.set_option("display.max.columns", None)
CD_data.head()
frames_CD=CD_data["coords"]
nosebrx=CD_data["nb_x"]
nosebry=CD_data["nb_y"]
midlinex=CD_data["ad_x"]
midliney=CD_data["ad_y"]
distx=midlinex.subtract(nosebrx)
disty=midliney.subtract(nosebry)
import numpy as np
nosebrxr=np.where(nosebrx<0,0,nosebrx)
area_nbx=print('areanosebridgeright=', np.trapz(nosebrxr))
nosebrxl=np.where(nosebrx>0,0,nosebrx)
area_nbx=print('areanosebridgeleft=', np.trapz(nosebrxl))
move_nbx=print('movement_nosebridge_horizontal=', np.std(nosebrx))
import matplotlib.pyplot as plt
plt.plot((frames_CD/30), distx)
plt.plot((frames_CD/30), disty)
plt.plot((frames_CD/30), nosebry)
plt.plot((frames_CD/30), nosebrx)
plt.ylim(-50,250)
plt.axhline(0,linestyle='dotted')
plt.show()