from flask import Flask, render_template,redirect
from flask_pymongo import PyMongo
import scrape_mars

#Create an instance of Flask
app=Flask(__name__)

#Setup connection to mongodb
app.config["MONGO_URI"]="mongodb://localhost:27017/mars_app"
mongo = PyMongo(app)

#Create routes and render html templates
@app.route("/")
def index():

    mars_dict=mongo.db.mars_dict.find_one()

    return render_template("index.html",mars=mars_dict)

@app.route("/scrape")
def scrape():

    mars_dict = mongo.db.mars_dict
    mars_data=scrape_mars.scrape()

    mars_dict.update({},mars_data,upsert=True)
    return redirect("/",code=302)

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


import copy
import os
from typing import Any, Dict
from unittest import mock

import tensorflow as tf
from tfx.extensions.google_cloud_ai_platform import constants
from tfx.extensions.google_cloud_ai_platform.trainer import executor as ai_platform_trainer_executor
from tfx.extensions.google_cloud_ai_platform.tuner import executor as ai_platform_tuner_executor
from tfx.proto import tuner_pb2
from tfx.types import standard_component_specs
from tfx.utils import json_utils
from tfx.utils import name_utils
from tfx.utils import proto_utils

class ExecutorTest(tf.test.TestCase):

  def setUp(self):
    super().setUp()

    self._output_data_dir = os.path.join(
        os.environ.get('TEST_UNDECLARED_OUTPUTS_DIR', self.get_temp_dir()),
        self._testMethodName)
    self._job_dir = os.path.join(self._output_data_dir, 'jobDir')
    self._project_id = '12345'
    self._job_id = 'fake_job_id'
    self._inputs = {}
    self._outputs = {}
    # Dict format of exec_properties. custom_config needs to be serialized
    # before being passed into Do function.
    self._exec_properties = {
        'custom_config': {
            ai_platform_trainer_executor.JOB_ID_KEY: self._job_id,
            ai_platform_tuner_executor.TUNING_ARGS_KEY: {
                'project': self._project_id,
                'jobDir': self._job_dir,
            },
        },
    }
    self._executor_class_path = name_utils.get_full_name(
        ai_platform_tuner_executor._WorkerExecutor)

    self.addCleanup(mock.patch.stopall)
    self.mock_runner = mock.patch(
        'tfx.extensions.google_cloud_ai_platform.tuner.executor.runner').start(
        )

  def _serialize_custom_config_under_test(self) -> Dict[str, Any]:
    """Converts self._exec_properties['custom_config'] to string."""
    result = copy.deepcopy(self._exec_properties)
    result['custom_config'] = json_utils.dumps(result['custom_config'])
    return result

  def testDo(self):
    executor = ai_platform_tuner_executor.Executor()
    executor.Do(self._inputs, self._outputs,
                self._serialize_custom_config_under_test())

  def testDoWithTuneArgs(self):
    executor = ai_platform_tuner_executor.Executor()
    self._exec_properties['tune_args'] = proto_utils.proto_to_json(
        tuner_pb2.TuneArgs(num_parallel_trials=3))

    executor.Do(self._inputs, self._outputs,
                self._serialize_custom_config_under_test())

    self.mock_runner.start_cloud_training.assert_called_with(
        self._inputs, self._outputs, self._serialize_custom_config_under_test(),
        self._executor_class_path, {
            'project': self._project_id,
            'jobDir': self._job_dir,
            'scaleTier': 'CUSTOM',
            'masterType': 'standard',
            'workerType': 'standard',
            'workerCount': 2,
        }, self._job_id, None, False, None)

  def testDoWithTuneArgsAndTrainingInputOverride(self):
    executor = ai_platform_tuner_executor.Executor()
    self._exec_properties['tune_args'] = proto_utils.proto_to_json(
        tuner_pb2.TuneArgs(num_parallel_trials=6))

    self._exec_properties['custom_config'][
        ai_platform_tuner_executor.TUNING_ARGS_KEY].update({
            'scaleTier': 'CUSTOM',
            'masterType': 'n1-highmem-16',
            'workerType': 'n1-highmem-16',
            'workerCount': 2,
        })

    executor.Do(self._inputs, self._outputs,
                self._serialize_custom_config_under_test())

    self.mock_runner.start_cloud_training.assert_called_with(
        self._inputs,
        self._outputs,
        self._serialize_custom_config_under_test(),
        self._executor_class_path,
        {
            'project': self._project_id,
            'jobDir': self._job_dir,
            # Confirm scale tier and machine types are not overritten.
            'scaleTier': 'CUSTOM',
            'masterType': 'n1-highmem-16',
            'workerType': 'n1-highmem-16',
            # Confirm workerCount has been adjusted to num_parallel_trials.
            'workerCount': 5,
        },
        self._job_id,
        None,
        False,
        None)

  def testDoWithoutCustomCaipTuneArgs(self):
    executor = ai_platform_tuner_executor.Executor()
    self._exec_properties = {'custom_config': {}}
    with self.assertRaises(ValueError):
      executor.Do(self._inputs, self._outputs,
                  self._serialize_custom_config_under_test())

  def testDoWithEnableVertexOverride(self):
    executor = ai_platform_tuner_executor.Executor()
    enable_vertex = True
    vertex_region = 'us-central2'
    self._exec_properties[standard_component_specs.CUSTOM_CONFIG_KEY][
        constants.ENABLE_VERTEX_KEY] = enable_vertex
    self._exec_properties[standard_component_specs.CUSTOM_CONFIG_KEY][
        constants.VERTEX_REGION_KEY] = vertex_region
    executor.Do(self._inputs, self._outputs,
                self._serialize_custom_config_under_test())
    self.mock_runner.start_cloud_training.assert_called_with(
        self._inputs, self._outputs, self._serialize_custom_config_under_test(),
        self._executor_class_path, {
            'project': self._project_id,
            'jobDir': self._job_dir,
        }, self._job_id, None, enable_vertex, vertex_region)

if __name__ == '__main__':
  tf.test.main()


from itertools import accumulate

N = int(input())
A = list(map(int, input().split()))

cumsum = list(accumulate(A))
ans = 0
maximum = 0
for i in range(N):
    maximum = max(maximum, A[i])
    ans += cumsum[i]
    print(ans + maximum * (i + 1))


def fact(number):
    n = 1
    for i in range(1, number + 1):
        n *= i
        yield n

number = int(input("Факториал какого числа?"))
for _ in fact(number):
    if _ > 15:
        break
    print(_)


from django.shortcuts import render
from django.http import HttpResponse
from django.core import serializers
from mywatchlist.models import MyWatchList

def show_mywatchlist_html(request):
    mywatchlist = MyWatchList.objects.all()
    movies_counter = len(MyWatchList.objects.all())
    movies_counter_watched = len(MyWatchList.objects.filter(watched = True))
    if(movies_counter_watched >= movies_counter/2):
        movies_watched = True
    else:
        movies_watched = False

    context = {
        "nama": "Alvaro Austin",
        "student_id": 2106752180,
        "mywatchlist": mywatchlist,
        "movies_watched": movies_watched
    }

    return render(request, 'mywatchlist.html', context)

def show_mywatchlist_xml(request):
    mywatchlist = MyWatchList.objects.all()
    return HttpResponse(serializers.serialize("xml", mywatchlist), content_type="application/xml")

def show_mywatchlist_json(request):
    mywatchlist = MyWatchList.objects.all()
    return HttpResponse(serializers.serialize("json", mywatchlist), content_type="application/json")


import os
from typing import List

NEWLINE = os.linesep

TEXT_SPLIT_OPTIONS = [
    ["\n", "\r"],
    ["."],
    ["?", "!"],
    [";"],
    [":"],
    [","],
    [")", "]", "}"],
    [" "],
    ["-"],
    None,
]

MD_SPLIT_OPTIONS = [
    ["."],
    ["?", "!"],
    [";"],
    [":"],
    [","],
    [")", "]", "}"],
    [" "],
    ["-"],
    ["\n", "\r"],
    None,
]

def split_plaintext_lines(text: str, max_token_per_line: int) -> List[str]:
    """
    Split plain text into lines.
    it will split on new lines first, and then on punctuation.
    """
    return _split_text_lines(text, max_token_per_line, True)

def split_markdown_lines(text: str, max_token_per_line: int) -> List[str]:
    """
    Split markdown into lines.
    It will split on punctuation first, and then on space and new lines.
    """
    return _split_markdown_lines(text, max_token_per_line, True)

def split_plaintext_paragraph(text: List[str], max_tokens: int) -> List[str]:
    """
    Split plain text into paragraphs.
    """

    split_lines = []
    for line in text:
        split_lines.extend(_split_text_lines(line, max_tokens, True))

    return _split_text_paragraph(split_lines, max_tokens)

def split_markdown_paragraph(text: List[str], max_tokens: int) -> List[str]:
    """
    Split markdown into paragraphs.
    """
    split_lines = []
    for line in text:
        split_lines.extend(_split_markdown_lines(line, max_tokens, False))

    return _split_text_paragraph(split_lines, max_tokens)

def _split_text_paragraph(text: List[str], max_tokens: int) -> List[str]:
    """
    Split text into paragraphs.
    """
    if not text:
        return []

    paragraphs = []
    current_paragraph = []

    for line in text:
        num_tokens_line = _token_count(line)
        num_tokens_paragraph = _token_count("".join(current_paragraph))

        if (
            num_tokens_paragraph + num_tokens_line + 1 >= max_tokens
            and len(current_paragraph) > 0
        ):
            paragraphs.append("".join(current_paragraph).strip())
            current_paragraph = []

        current_paragraph.append(f"{line}{NEWLINE}")

    if len(current_paragraph) > 0:
        paragraphs.append("".join(current_paragraph).strip())
        current_paragraph = []

    # Distribute text more evenly in the last paragraphs
    # when the last paragraph is too short.

    if len(paragraphs) > 1:
        last_para = paragraphs[-1]
        sec_last_para = paragraphs[-2]

        if _token_count(last_para) < max_tokens / 4:
            last_para_tokens = last_para.split(" ")
            sec_last_para_tokens = sec_last_para.split(" ")
            last_para_token_count = len(last_para_tokens)
            sec_last_para_token_count = len(sec_last_para_tokens)

            if last_para_token_count + sec_last_para_token_count <= max_tokens:
                sec_last_para = " ".join(sec_last_para_tokens) + NEWLINE
                last_para = " ".join(last_para_tokens)
                new_sec_last_para = sec_last_para + last_para
                paragraphs[-2] = new_sec_last_para.strip()
                paragraphs.pop()

    return paragraphs

def _split_markdown_lines(text: str, max_token_per_line: int, trim: bool) -> List[str]:
    """
    Split markdown into lines.
    """

    lines = _split_str_lines(text, max_token_per_line, MD_SPLIT_OPTIONS, trim)
    return lines

def _split_text_lines(text: str, max_token_per_line: int, trim: bool) -> List[str]:
    """
    Split text into lines.
    """

    lines = _split_str_lines(text, max_token_per_line, TEXT_SPLIT_OPTIONS, trim)

    return lines

def _split_str_lines(
    text: str, max_tokens: int, separators: List[List[str]], trim: bool
) -> List[str]:
    if not text:
        return []

    text = text.replace("\r\n", "\n")
    lines = []
    was_split = False
    for split_option in separators:
        if not lines:
            lines, was_split = _split_str(text, max_tokens, split_option, trim)
        else:
            lines, was_split = _split_list(lines, max_tokens, split_option, trim)
        if not was_split:
            break

    return lines

def _split_str(
    text: str, max_tokens: int, separators: List[str], trim: bool
) -> List[str]:
    """
    Split text into lines.
    """
    if not text:
        return []

    input_was_split = False
    text = text.strip() if trim else text

    text_as_is = [text]

    if _token_count(text) <= max_tokens:
        return text_as_is, input_was_split

    input_was_split = True

    half = int(len(text) / 2)

    cutpoint = -1

    if not separators:
        cutpoint = half

    elif set(separators) & set(text) and len(text) > 2:
        for index, text_char in enumerate(text):
            if text_char not in separators:
                continue

            if abs(half - index) < abs(half - cutpoint):
                cutpoint = index + 1

    else:
        return text_as_is, input_was_split

    if 0 < cutpoint < len(text):
        lines = []
        first_split, has_split1 = _split_str(
            text[:cutpoint], max_tokens, separators, trim
        )
        second_split, has_split2 = _split_str(
            text[cutpoint:], max_tokens, separators, trim
        )

        lines.extend(first_split)
        lines.extend(second_split)

        input_was_split = has_split1 or has_split2
    else:
        return text_as_is, input_was_split

    return lines, input_was_split

def _split_list(
    text: List[str], max_tokens: int, separators: List[str], trim: bool
) -> List[str]:
    """
    Split list of string into lines.
    """
    if not text:
        return []

    lines = []
    input_was_split = False
    for line in text:
        split_str, was_split = _split_str(line, max_tokens, separators, trim)
        lines.extend(split_str)
        input_was_split = input_was_split or was_split

    return lines, input_was_split

def _token_count(text: str) -> int:
    """
    Count the number of tokens in a string.

    TODO: chunking methods should be configurable to allow for different
          tokenization strategies depending on the model to be called.
          For now, we use an extremely rough estimate.
    """
    return int(len(text) / 4)


#!/usr/bin/env python3

import inkex
import copy

class bluePrintMakerData():
	def __init__(self,effect):
		self.effect=effect
		self.stroke_units=effect.options.stroke_units
		self.unit_factor=1.0
		self.set_units()
		self.stroke_width=effect.options.stroke_width*self.unit_factor
		self.palette=effect.options.palette
		self.background_color=None
		self.stroke_color=None
		self.set_colors()
		self.selected_nodes=[]
		if len(effect.options.ids)==0:
			self.selected_nodes=[effect.svg.getElementById(x) for x in effect.svg.get_ids()]
			self.selected_nodes=[node for node in self.selected_nodes if effect.is_geometry(node)]
		else:
			self.selected_nodes=[y for x,y in effect.svg.selected.items()]
			self.selected_nodes=[node for node in self.selected_nodes if effect.is_geometry(node,shapes=['path','g','rect','ellipse','perspective'])]
		self.allowed_ids=[]
		self.allowed_nodes=[]
		self.set_objects()

	def set_units(self):
		if self.stroke_units=='millimeters':
			self.unit_factor=3.543
		if self.stroke_units=='centimeters':
			self.unit_factor=35.433
		if self.stroke_units=='points':
			self.unit_factor=1.25
		if self.stroke_units=='pixels':
			self.unit_factor=1.0

	def set_colors(self):
		if self.palette=='blueprint':
			self.background_color='#006fde'
			self.stroke_color='#ffffff'
		if self.palette=='black':
			self.background_color='#000000'
			self.stroke_color='#ffffff'
		if self.palette=='white':
			self.background_color='#ffffff'
			self.stroke_color='#000000'
		if self.palette=='laser':
			self.background_color='#ffffff'
			self.stroke_color='#ff0000'

	def set_objects(self):
		for current_id in self.effect.svg.get_ids():
			node=self.effect.svg.getElementById(current_id)
			if self.effect.is_geometry(node):
				self.allowed_ids.append(current_id)
				self.allowed_nodes.append(node)

class BluePrintMaker(inkex.EffectExtension):

	def __init__(self):
		inkex.Effect.__init__(self)
		self.arg_parser.add_argument('-p', '--palette', help='Choose the colors...')
		self.arg_parser.add_argument('-s', '--stroke_width', type=float, help='Stroke size...')
		self.arg_parser.add_argument('-u', '--stroke_units', help='Choose the units...')
		self.data=None

	def is_a_group(self, node):
		data=False
		if node.tag==inkex.addNS('g','svg'):
			data=True
		return data

	def is_geometry(self, node, shapes=['path','rect','ellipse','perspective']):
		data=False
		for s in shapes:
			if node.tag==inkex.addNS(s,'svg'):
				data=True
		return data

	def change_page_settings(self):
		namedview=self.svg.namedview
		namedview.set('pagecolor',self.data.background_color)
		namedview.set(inkex.addNS('pageopacity', 'inkscape'),'1')
		namedview.set(inkex.addNS('pageshadow', 'inkscape'),'0')
		namedview.set('bordercolor',self.data.stroke_color)
		namedview.set('borderopacity','1')
		return None

	def change_this_object(self,node):
		styles=dict(inkex.Style.parse_str(node.get('style')))
		styles_copy=copy.deepcopy(styles)
		styles_copy['stroke']=self.data.stroke_color
		styles_copy['stroke_width']=self.data.stroke_width
		styles_copy['stroke-opacity']='1'
		styles_copy['fill']='none'
		styles_copy['fill-opacity']='1'
		styles_copy['opacity']='1'
		node.set('style',str(inkex.Style(styles_copy)))
		return None

	def iterate_on_objects(self,node=None):
		if self.is_geometry(node):
			self.change_this_object(node)
		if self.is_a_group(node):
			for current_node in list(node):
				self.iterate_on_objects(current_node)

	def effect(self):
		self.data=bluePrintMakerData(self)
		self.change_page_settings()
		for node in self.data.selected_nodes:
			self.iterate_on_objects(node)
		return None

if __name__ == '__main__':
	BluePrintMaker().run()


"""
imshows.py: wrappers around matplotlib.pyplot.imshow with saner
defaults for 3D scientific images.
"""
import numpy as np
from matplotlib import pyplot as plt, cm, colors
from skimage import color

def cshow(im):
    """Show an image (or cross-section) with the cubehelix colormap.

    Parameters
    ----------
    im : array
        An array of intensity values (ie not multichannel).

    Returns
    -------
    ax : matplotlib AxesImage object
        The figure axes.

    Notes
    -----
    For nD images with n > 2, ``cshow`` repeatedly takes the middle
    cross- section of leading axes until a 2D image remains. For
    example, given an array `im` of shape ``(7, 512, 512)``, ``cshow``
    will display `im[3]`. For shape ``(4, 50, 50, 50)``, ``cshow`` will
    display `im[2, 25]`.
    """
    if im.ndim > 2:
        mid = im.shape[0] // 2
        ax = cshow(im[mid])
    else:
        ax = plt.imshow(im, cmap=cm.cubehelix, interpolation='nearest')
    return ax

def _factors(n):
    """Return integer factors of `n`, not including 1 or `n`.

    Parameters
    ----------
    n : int
        Integer for which we want a factorization.

    Returns
    -------
    fs : list of int
        The list of factors of `n` (empty if `n` is prime).

    Examples
    --------
    >>> _factors(10)
    [2, 5]
    >>> _factors(20)
    [2, 4, 5, 10]
    """
    fs = filter(lambda i: (n % i == 0), range(2, 1 + n/2))
    return fs

def rshow(values):
    """Show a 1D vector of values in a rectangular grid.

    Parameters
    ----------
    values : 1D array
        The values to be plotted.

    Returns
    -------
    ax : matplotlib AxesImage object
        The figure axes.

    Notes
    -----
    If the number of values is prime, rshow will revert to a line plot.
    """
    n = len(values)
    fs = _factors(n)
    k = len(fs)
    if k == 0:
        return plt.plot(values)
    else:
        new_shape = (-1, fs[k // 2])
        values_im = values.reshape(new_shape)
        return cshow(values_im)

def nshow(im):
    """Show an image after normalising each channel to [0, 255] uint8.

    Parameters
    ----------
    im : array
        The input image.

    Returns
    -------
    ax : matplotlib AxesImage object
        The figure axes.
    """
    channel_mins = im.min(axis=0).min(axis=0)[np.newaxis, np.newaxis, :]
    channel_maxs = im.max(axis=0).max(axis=0)[np.newaxis, np.newaxis, :]
    im_out = (im.astype(float) - channel_mins) / (channel_maxs - channel_mins)
    ax = plt.imshow(im_out)
    return ax

def sshow(im, labrandom=True):
    """Show a segmentation (or cross-section) using a random colormap.

    Parameters
    ----------
    im : np.ndarray of int
        The segmentation to be displayed.
    labrandom : bool, optional
        Use random points in the Lab colorspace instead of RGB.

    Returns
    -------
    ax : matplotlib AxesImage object
        The figure axes.
    """
    if im.ndim > 2:
        mid = im.shape[0] // 2
        ax = sshow(im[mid], labrandom)
    else:
        rand_colors = np.random.rand(np.ceil(im.max()), 3)
        if labrandom:
            rand_colors[:, 0] = rand_colors[:, 0] * 60 + 20
            rand_colors[:, 1] = rand_colors[:, 1] * 185 - 85
            rand_colors[:, 2] = rand_colors[:, 2] * 198 - 106
            rand_colors = color.lab2rgb(rand_colors[np.newaxis, ...])[0]
            rand_colors[rand_colors < 0] = 0
            rand_colors[rand_colors > 1] = 1
        rcmap = colors.ListedColormap(np.concatenate((np.zeros((1, 3)),
                                                      rand_colors)))
        ax = plt.imshow(im, cmap=rcmap, interpolation='nearest')
    return ax


from ctypes import *
import math
import os
import random
import cv2
import numpy as np
import datetime
import rtsp

classes=['AnQuanMao','Ren','FanGuangYi','PuTongYi']
color=[(255,0,0),(0,255,0),(0,0,255)]
def sample(probs):
    s = sum(probs)
    probs = [a/s for a in probs]
    r = random.uniform(0, 1)
    for i in range(len(probs)):
        r = r - probs[i]
        if r <= 0:
            return i
    return len(probs)-1

def c_array(ctype, values):
    arr = (ctype*len(values))()
    arr[:] = values
    return arr

class BOX(Structure):
    _fields_ = [("x", c_float),
                ("y", c_float),
                ("w", c_float),
                ("h", c_float)]

class DETECTION(Structure):
    _fields_ = [("bbox", BOX),
                ("classes", c_int),
                ("prob", POINTER(c_float)),
                ("mask", POINTER(c_float)),
                ("objectness", c_float),
                ("sort_class", c_int)]

class IMAGE(Structure):
    _fields_ = [("w", c_int),
                ("h", c_int),
                ("c", c_int),
                ("data", POINTER(c_float))]

class METADATA(Structure):
    _fields_ = [("classes", c_int),
                ("names", POINTER(c_char_p))]

#lib = CDLL("/home/pjreddie/documents/darknet/libdarknet.so", RTLD_GLOBAL)
lib = CDLL("/home/workspace/install/darknet/libdarknet.so", RTLD_GLOBAL)
lib.network_width.argtypes = [c_void_p]
lib.network_width.restype = c_int
lib.network_height.argtypes = [c_void_p]
lib.network_height.restype = c_int

predict = lib.network_predict
predict.argtypes = [c_void_p, POINTER(c_float)]
predict.restype = POINTER(c_float)

set_gpu = lib.cuda_set_device
set_gpu.argtypes = [c_int]

make_image = lib.make_image
make_image.argtypes = [c_int, c_int, c_int]
make_image.restype = IMAGE

get_network_boxes = lib.get_network_boxes
get_network_boxes.argtypes = [c_void_p, c_int, c_int, c_float, c_float, POINTER(c_int), c_int, POINTER(c_int)]
get_network_boxes.restype = POINTER(DETECTION)

make_network_boxes = lib.make_network_boxes
make_network_boxes.argtypes = [c_void_p]
make_network_boxes.restype = POINTER(DETECTION)

free_detections = lib.free_detections
free_detections.argtypes = [POINTER(DETECTION), c_int]

free_ptrs = lib.free_ptrs
free_ptrs.argtypes = [POINTER(c_void_p), c_int]

network_predict = lib.network_predict
network_predict.argtypes = [c_void_p, POINTER(c_float)]

reset_rnn = lib.reset_rnn
reset_rnn.argtypes = [c_void_p]

load_net = lib.load_network
load_net.argtypes = [c_char_p, c_char_p, c_int]
load_net.restype = c_void_p

do_nms_obj = lib.do_nms_obj
do_nms_obj.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]

do_nms_sort = lib.do_nms_sort
do_nms_sort.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]

free_image = lib.free_image
free_image.argtypes = [IMAGE]

letterbox_image = lib.letterbox_image
letterbox_image.argtypes = [IMAGE, c_int, c_int]
letterbox_image.restype = IMAGE

load_meta = lib.get_metadata
lib.get_metadata.argtypes = [c_char_p]
lib.get_metadata.restype = METADATA

load_image = lib.load_image_color
load_image.argtypes = [c_char_p, c_int, c_int]
load_image.restype = IMAGE

rgbgr_image = lib.rgbgr_image
rgbgr_image.argtypes = [IMAGE]

predict_image = lib.network_predict_image
predict_image.argtypes = [c_void_p, IMAGE]
predict_image.restype = POINTER(c_float)

"""
Process video data
"""
ndarray_image = lib.ndarray_to_image
ndarray_image.argtypes = [POINTER(c_ubyte), POINTER(c_long), POINTER(c_long)]
ndarray_image.restype = IMAGE

def nparray_to_image(img):
    data = img.ctypes.data_as(POINTER(c_ubyte))
    image = ndarray_image(data, img.ctypes.shape, img.ctypes.strides)
    return image

def classify(net, meta, im):
    out = predict_image(net, im)
    res = []
    for i in range(meta.classes):
        res.append((meta.names[i], out[i]))
    res = sorted(res, key=lambda x: -x[1])
    return res

def detect(net, meta, image, thresh=.3, hier_thresh=.5, nms=.45):
    im = load_image(image, 0, 0)
    num = c_int(0)
    pnum = pointer(num)
    predict_image(net, im)
    dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, None, 0, pnum)
    num = pnum[0]
    if (nms): do_nms_obj(dets, num, meta.classes, nms);

    res = []
    for j in range(num):
        for i in range(meta.classes):
            if dets[j].prob[i] > 0:
                b = dets[j].bbox
                res.append((meta.names[i], dets[j].prob[i], (b.x, b.y, b.w, b.h)))
    res = sorted(res, key=lambda x: -x[1])
    free_image(im)
    free_detections(dets, num)
    return res

def Iou(box1, box2, wh=False):
    if wh == False:
	    xmin1, ymin1, xmax1, ymax1 = box1
	    xmin2, ymin2, xmax2, ymax2 = box2
    else:
        xmin1, ymin1 = int(box1[0]-box1[2]/2.0), int(box1[1]-box1[3]/2.0)
        xmax1, ymax1 = int(box1[0]+box1[2]/2.0), int(box1[1]+box1[3]/2.0)
        xmin2, ymin2 = int(box2[0]-box2[2]/2.0), int(box2[1]-box2[3]/2.0)
        xmax2, ymax2 = int(box2[0]+box2[2]/2.0), int(box2[1]+box2[3]/2.0)
    # 获取矩形框交集对应的左上角和右下角的坐标（intersection）
    tlx = np.max([xmin1, xmin2])
    tly = np.max([ymin1, ymin2])
    brx = np.min([xmax1, xmax2])
    bry = np.min([ymax1, ymax2])
    # 计算两个矩形框面积
    area1 = (xmax1-xmin1) * (ymax1-ymin1)
    area2 = (xmax2-xmin2) * (ymax2-ymin2)
    inter_area=(np.max([0,brx-tlx]))*(np.max(bry-tly)) #计算交集面积

    iou=inter_area/(area1+area2-inter_area+1e-6)#计算交并比

    return iou

def drawbbox(res,image_path):
    """

    :param res: inflence result
    :param image_path: iamge path
    :return:
    """
    if len(res)==0:
        print("Not bbox found!")
        return

    if not os.path.exists(image_path):
        print("% not found!" %image_path )
        return
    image=cv2.imread(image_path)

    for bbox in res:

        claeese=bbox[0].decode()
        conf=bbox[1]
        xmin=int(bbox[2][0]-bbox[2][2]/2)
        ymin=int(bbox[2][1]-bbox[2][3]/2)
        xmax=int(bbox[2][2]/2 + bbox[2][0])
        ymax=int(bbox[2][3]/2 + bbox[2][1])
        # cv2.rectangle(image,(xmin,ymin),(xmax,ymax),color=(0,255,0))
        # cv2.putText(image, str(claeese), (xmin, ymin-20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 1)
        # cv2.putText(image, str(conf), (xmin, ymin -10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0),1)

        cls_cof = "{}:{:.2f}".format(claeese, conf)

        color = tuple(map(int, np.uint8(np.random.uniform(0, 255, 3))))

        cv2.rectangle(image, tuple(xmin, ymin), tuple(xmax, ymax), color, 1)
        t_size = cv2.getTextSize(cls_cof, cv2.FONT_HERSHEY_PLAIN, 1, 1)[0]
        pt2 = xmin + t_size[0] + 3, ymin + t_size[1] + 4
        cv2.rectangle(image, tuple(xmin, ymin), tuple(pt2), color, -1)
        cv2.putText(image, cls_cof, (xmin, t_size[1] + 4 + ymin), cv2.FONT_HERSHEY_PLAIN,
                    cv2.FONT_HERSHEY_PLAIN, 1, 1, 2)

        save_path='/mnt/share/test/Test_'+os.path.basename(image_path)
    # cv2.imshow("screen_title", image)

        cv2.imwrite(save_path,image)

counter=0

def drawbbox_usb(res,image):
    """

    :param res: inflence result
    :param image_path: iamge path
    :return:
    """
    global counter
    counter+=1
    if len(res)==0:
        print("Not bbox found!")
        return

    person_f=False
    draw_img=image.copy()
    for bbox in res:
        cls = bbox[0].decode()
        if cls=="person":
            person_f=True

        conf = bbox[1]
        xmin = int(bbox[2][0] - bbox[2][2] / 2)
        ymin = int(bbox[2][1] - bbox[2][3] / 2)
        xmax = int(bbox[2][2] / 2 + bbox[2][0])
        ymax = int(bbox[2][3] / 2 + bbox[2][1])

        cls_cof="{}:{:.2f}".format(cls, conf)

        color = tuple(map(int, np.uint8(np.random.uniform(0, 255, 3))))

        cv2.rectangle(image, tuple((xmin,ymin)), tuple((xmax,ymax)), color, 1)
        t_size = cv2.getTextSize(cls_cof, cv2.FONT_HERSHEY_PLAIN, 1 , 1)[0]
        pt2 = xmin + t_size[0] + 3, ymin + t_size[1] + 4
        cv2.rectangle(image, tuple((xmin,ymin)), tuple(pt2), color, -1)
        cv2.putText(image, cls_cof, (xmin, t_size[1] + 4 + ymin), cv2.FONT_HERSHEY_PLAIN,
                    cv2.FONT_HERSHEY_PLAIN, 1, 1, 2)

        # cv2.rectangle(image, (xmin, ymin), (xmax, ymax), color=color[1])
        # cv2.putText(image, str(cls), (xmin, ymin - 30), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color[1], 1)
        # cv2.putText(image, str(conf), (xmin, ymin - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.4, color[1],1)

    # if person_f  and counter %15==0:
    #     nowTime = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
    #     save_path='/mnt/share/20200722-ch/ch3/image/'+str(nowTime)+"_8_7_shiyanshi.jpg"
    #     cv2.imwrite(save_path,draw_img)

def detectVideo(net, meta, im, thresh=.55, hier_thresh=.3, nms=.45):
    """
    detect video data
    :param net:
    :param meta:
    :param im:
    :param thresh:
    :param hier_thresh:
    :param nms:
    :return:
    """

    num = c_int(0)
    pnum = pointer(num)

    predict_image(net, im)
    dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, None, 0, pnum)
    num = pnum[0]
    if (nms): do_nms_obj(dets, num, meta.classes, nms);

    res = []
    for j in range(num):
        for i in range(meta.classes):
            if dets[j].prob[i] > 0:
                b = dets[j].bbox
                res.append((meta.names[i], dets[j].prob[i], (b.x, b.y, b.w, b.h)))
    res = sorted(res, key=lambda x: -x[1])
    free_image(im)
    free_detections(dets, num)
    return res

def Video(base_name):

    cap = cv2.VideoCapture("/mnt/furg-fire-dataset/ele_fire/2020-7-22/VID_20200722_162307.mp4")  # 打开指定路径上的视频文件
    # cap=cv2.VideoCapture(0) #打开设备索引号对于设备的摄像头，一般电脑的默认索引号为0
    net = load_net((base_name + "yolov3.cfg").encode('utf-8'), \
                   (base_name + "backup/yolov3-voc_20000.weights").encode('utf-8'), 0)
    meta = load_meta((base_name + "train.data").encode('utf-8'))

    fps = 16
    size = (640, 480)
    fourcc = cv2.VideoWriter_fourcc('M','J','P','G')
    videoWriter = cv2.VideoWriter('./a.avi', fourcc, fps, size)

    while (True):
        ret, frame = cap.read()

        if ret == True:

            im = nparray_to_image(frame)

            res = detectVideo(net, meta, im)
            drawbbox_usb(res, frame)
            print(res)
            cv2.imshow("screen_title", frame)
            # videoWriter.write(frame)
            if cv2.waitKey(25) & 0xFF == ord('q'):
                break
        else:
            break

    cap.release()
    cv2.destroyAllWindows()

def VideoList(base_name):
    """
    read video in dir
    :return:
    """
    videos=glob.glob(os.path.join("/mnt/share/20200722-ch/ch3/","*.mp4"))
    for video in videos:
        cap = cv2.VideoCapture(video)  # 打开指定路径上的视频文件
        # cap=cv2.VideoCapture(0) #打开设备索引号对于设备的摄像头，一般电脑的默认索引号为0
        print("Load configure from %s"  %(base_name + "yolov3.cfg") )
        # net = load_net((base_name + "yolov3.cfg").encode('utf-8'), \
        #                (base_name + "yolov3.weights").encode('utf-8'), 0)
        # meta = load_meta(("/home/workspace/install/darknet/cfg/coco.data").encode('utf-8'))  #/home/workspace/nnie/package/yolov3/model

        net = load_net((base_name + "cfg/yolov3-voc.cfg").encode('utf-8'), \
                       (base_name + "cfg/backup/yolov3-voc_final.weights").encode('utf-8'), 0)
        meta = load_meta((base_name + "cfg/voc.data").encode('utf-8'))

        fps = 16
        size = (640, 480)
        fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')

        while (True):
            ret, frame = cap.read()

            if ret == True:
                h, w = frame.shape[:2]
                cenx, ceny = (w - 1) // 2, (h - 1) // 2

                roi_tl_x=cenx-400
                roi_tl_y=ceny-450
                roi_matrix=frame.copy()
                # roi_matrix=frame[roi_tl_y:roi_tl_y+800,roi_tl_x:roi_tl_x+900,:]
                im = nparray_to_image(roi_matrix)

                # roi_matrix=im.copy()

                # im = nparray_to_image(roi_matrix)

                res = detectVideo(net, meta, im)
                drawbbox_usb(res, roi_matrix)
                print(res)
                cv2.imshow("screen_title", roi_matrix)
                # videoWriter.write(frame)
                if cv2.waitKey(25) & 0xFF == ord('q'):
                    break
            else:
                break

                # for stepSizeH in range(2):
                #     for stepSizeV in range(2):
                #
                #         roi_matrix = frame[stepSizeH * cenx:stepSizeH * cenx + cenx, stepSizeV * ceny:stepSizeV * ceny + ceny, :]
                #
                #         im = nparray_to_image(roi_matrix)
                #
                #         res = detectVideo(net, meta, im)
                #         drawbbox_usb(res, roi_matrix)
                #         print(res)
                #         cv2.imshow("screen_title", roi_matrix)
                #         # videoWriter.write(frame)
                #         if cv2.waitKey(25) & 0xFF == ord('q'):
                #             break
                #     else:
                #         break

    cap.release()
    cv2.destroyAllWindows()

def USBCamera(base_name):
    capture = cv2.VideoCapture(0)
    # /mnt/furg-fire-dataset/barbecue.mp4
    # capture = cv2.VideoCapture("/mnt/furg-fire-dataset/ele_fire/2020-7-22/VID_20200722_162307.mp4")
    net = load_net((base_name+"cfg/yolov3-voc.cfg").encode('utf-8'), \
                   (base_name+"cfg/backup/yolov3-voc.backup").encode('utf-8'), 0)
    meta = load_meta((base_name+"cfg/train.data").encode('utf-8'))
    # 打开自带的摄像头
    if capture.isOpened():
        # 以下两步设置显示屏的宽高
        capture.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
        capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
        # 持续读取摄像头数据
        while True:
            read_code, frame = capture.read()
            if not read_code:
                break

            im = nparray_to_image(frame)

            res = detectVideo(net, meta,im)
            drawbbox_usb(res, frame)
            print(res)

            cv2.imshow("screen_title", frame)
            # 输入 q 键，保存当前画面为图片
            if cv2.waitKey(30) == ord('q'):
                break
    capture.release()
    cv2.destroyAllWindows()

"""*****************************************************************************************************"""
def Use_Rtsp(rtscap,base_name):
    net = load_net((base_name + "cfg/yolov3-voc.cfg").encode('utf-8'), \
                   (base_name + "cfg/backup/yolov3-voc_final.weights").encode('utf-8'), 0)
    meta = load_meta((base_name + "cfg/voc.data").encode('utf-8'))

    while rtscap.isStarted():
        ok, img = rtscap.read_latest_frame()  # read_latest_frame() 替代 read()

        if img is None:
            continue
        orig_img = img.copy()

        # frame = cv2.resize(orig_img, (416, 416))
        frame=orig_img
        im = nparray_to_image(frame)

        res = detectVideo(net, meta, im)
        drawbbox_usb(res, frame)
        print(res)

        cv2.imshow("screen_title", frame)
        # 输入 q 键，保存当前画面为图片
        if cv2.waitKey(30) == ord('q'):
            break

cam=0
video=0
use_rtsp=1

import glob
if __name__ == "__main__":
    if cam:
        # USBCamera("/mnt/workspcae/caffe/test_model/2020-8-3/") #/mnt/workspcae/darknet/train/train_person/cfg
        USBCamera("/mnt/workspcae/darknet/train/train_person/")
    elif video:
        VideoList("/mnt/workspcae/caffe/test_model/2020-8-3/")
        # VideoList("/home/workspace/nnie/package/yolov3/model/")
        # Video('/mnt/furg-fire-dataset/ele_fire/bangzi/Fire/cfg/')
    elif use_rtsp:
        rtscap = rtsp.RTSCapture.create('rtsp://admin:Aa123456@192.168.1.11:554/Streaming/Channels/301')
        rtscap.start_read()  # 启动子线程并改变 read_latest_frame 的指向
        # Use_Rtsp(rtscap,"/mnt/workspcae/darknet/train/train_person/")  #/mnt/workspcae/caffe/test_model/2020-8-3
        Use_Rtsp(rtscap, "/mnt/workspcae/caffe/test_model/2020-8-10/")

        rtscap.stop_read()
        rtscap.release()
        cv2.destroyAllWindows()
    else:
        # Image list test

        # net = load_net("/mnt/workspcae/caffe/test_model/2020-8-3/cfg/yolov3-voc.cfg".encode('utf-8'), \
        #                "/mnt/workspcae/caffe/test_model/2020-8-3/cfg/backup/yolov3-voc_final.weights".encode('utf-8'), 0)
        # meta = load_meta("/mnt/workspcae/caffe/test_model/2020-8-3/cfg/voc.data".encode('utf-8'))

        net = load_net("/mnt/workspcae/darknet/train/train_tumble/cfg/yolov3-voc.cfg".encode('utf-8'), \
                       "/mnt/workspcae/darknet/train/train_tumble/cfg/backup/yolov3-voc.backup".encode('utf-8'),
                       0)
        meta = load_meta("/mnt/workspcae/darknet/train/train_tumble/cfg/train.data".encode('utf-8'))

        total_counter = 0
        target_counter = 0

        img_list = glob.glob(os.path.join('/media/libin/办公/Workspace/Dataset/tumble/tumble/tumb/', "*.jpg"))
        for img in img_list:
            r = detect(net, meta, img.encode('utf-8'))
            drawbbox(r, img)
            print(r)
            total_counter += 1
            if len(r):
                target_counter += 1

        print("Test image %d pic, found target %d pic" % (total_counter, target_counter))


#!/usr/bin/env python3

import math, itertools, functools, heapq
from collections import defaultdict, Counter
from typing import List, Set, Dict, Tuple
try:
    from _tree import *
    from _list import *
    from _util import *
except ImportError:
    pass

class Solution:
    def AC_sortByBits(self, arr: List[int]) -> List[int]:
        bucket = []
        for _ in range(16):
            bucket.append([])

        for num in arr:
            idx = self.bits_num(num)
            bucket[idx].append(num)

        res = []
        for seg in bucket:
            res.extend(sorted(seg))

        return res

    def bits_num(self, num: int) -> int:
        res = 0
        while num > 0:
            res += num % 2
            num = num // 2

        return res

    def sortByBits(self, arr: List[int]) -> List[int]:
        """
        refer to
        https://leetcode.com/problems/sort-integers-by-the-number-of-1-bits/discuss/516999/Python-1-line
        """
        return sorted(arr, key=lambda num: (sum((num >> i) & 1 for i in range(32)), num))

if __name__ == '__main__':
    print(Solution().sortByBits([0,1,2,3,4,5,6,7,8]))


from basic_gui import *
from PyQt5.QtWidgets import (
    QRadioButton,
    QGroupBox,
    QCheckBox,
    QHBoxLayout,
    QTreeWidgetItemIterator,
)
from PyQt5.QtGui import QIcon
import wordsearch_generater

class Communication(Communication):
    super(Communication)
    # signal for puzzle settings
    puzzle_setting = pyqtSignal(list)
    # emits if entered words are korean
    korean = pyqtSignal(bool)
    # siganl to notify that making wordsearch puzzle is complete and to proceed the following
    puzzle_complete = pyqtSignal()
    recursionerrormsg = pyqtSignal()
    valueerrormsg = pyqtSignal()

class Settings(QWidget):
    def __init__(self, c):
        super().__init__()
        self.c = c
        self.puzzle_width = 15
        self.puzzle_height = 15
        self.shape = 0
        self.direction = 1
        self.diff_val = 1
        self.option = "겹치지 않도록"
        self.option_val = 0
        self.init_UI()

    def init_UI(self):
        title_label = QLabel("1. 퍼즐 옵션을 선택하세요.")

        # Group for size
        grp_size = QGroupBox("크기 조정")
        self.label_puzzle_width = QLabel("가로 길이: ")
        self.width_spin = QSpinBox()
        self.width_spin.setMinimum(5)
        self.width_spin.setToolTip("마우스 스크롤 가능합니다.")
        self.width_spin.setValue(15)

        self.label_puzzle_height = QLabel("세로 길이: ")
        self.height_spin = QSpinBox()
        self.height_spin.setMinimum(5)
        self.height_spin.setToolTip("마우스 스크롤 가능합니다.")
        self.height_spin.setValue(15)
        self.height_spin.valueChanged.connect(self.puzzle_height_change)

        # layout width
        hbox_width = QHBoxLayout()
        hbox_width_label = QHBoxLayout()
        hbox_width_label.setAlignment(Qt.AlignRight)
        hbox_width_label.addWidget(self.label_puzzle_width)
        hbox_width.addLayout(hbox_width_label)
        hbox_width_spin = QHBoxLayout()
        hbox_width_spin.setAlignment(Qt.AlignLeft)
        hbox_width_spin.addWidget(self.width_spin)
        hbox_width.addLayout(hbox_width_spin)
        self.width_spin.valueChanged.connect(self.puzzle_width_change)

        # layout height
        hbox_height = QHBoxLayout()
        hbox_height_label = QHBoxLayout()
        hbox_height_label.setAlignment(Qt.AlignRight)
        hbox_height_label.addWidget(self.label_puzzle_height)
        hbox_height_spin = QHBoxLayout()
        hbox_height_spin.setAlignment(Qt.AlignLeft)
        hbox_height_spin.addWidget(self.height_spin)
        hbox_height.addLayout(hbox_height_label)
        hbox_height.addLayout(hbox_height_spin)

        # layout for width, height
        vbox_size = QVBoxLayout()
        vbox_size.addLayout(hbox_width)
        vbox_size.addLayout(hbox_height)

        grp_size.setLayout(vbox_size)

        # Group for word shape
        grp_shape = QGroupBox("단어 모양")
        shape_1 = QRadioButton("가로세로")
        shape_1.setToolTip(
            "
단어를 가로세로로 설정합니다."
        )
        shape_1.setChecked(True)
        shape_2 = QRadioButton("가로세로 + 대각선")
        shape_2.setToolTip(
            "
단어를 가로세로, 대각선으로 설정합니다."
        )

        shape_1.clicked.connect(lambda: self.diff_checked(shape_1))
        shape_2.clicked.connect(lambda: self.diff_checked(shape_2))

        # layout shape
        grp_shape_layout = QVBoxLayout()
        grp_shape_layout.addWidget(shape_1)
        grp_shape_layout.addWidget(shape_2)

        grp_shape.setLayout(grp_shape_layout)

        # Group for word direction
        grp_direction = QGroupBox("단어 방향")
        direction_1 = QRadioButton("정방향")
        direction_1.setChecked(True)
        direction_1.setToolTip(
            "
글자 방향은 정방향으로 설정합니다."
        )
        direction_2 = QRadioButton("정방향 + 역방향")
        direction_2.setToolTip(
            "
글자 방향은 역방향으로 설정합니다."
        )
        direction_1.clicked.connect(lambda: self.diff_checked(direction_1))
        direction_2.clicked.connect(lambda: self.diff_checked(direction_2))

        # layout direction
        grp_direction_layout = QVBoxLayout()
        grp_direction_layout.addWidget(direction_1)
        grp_direction_layout.addWidget(direction_2)

        grp_direction.setLayout(grp_direction_layout)

        grp_option = QGroupBox("옵션")
        option_1 = QRadioButton("글자 겹치지 않게")
        option_1.setToolTip(
            "퍼즐이 쉬워집니다.
채워지는 글자는 되도록 겹치지 않도록 설정합니다."
        )
        option_1.setChecked(True)
        option_2 = QRadioButton("글자 무작위로")
        option_2.setToolTip(
            "퍼즐 난이도는 보통입니다.
채워지는 글자는 되도록 무작위로 설정합니다."
        )
        option_3 = QRadioButton("글자 겹치게")
        option_3.setToolTip(
            "
퍼즐이 어려워집니다.
채워지는 글자는 되도록 겹치도록 설정합니다."
        )
        option_1.clicked.connect(lambda: self.option_checked(option_1))
        option_2.clicked.connect(lambda: self.option_checked(option_2))
        option_3.clicked.connect(lambda: self.option_checked(option_3))
        # layout option
        grp_option_layout = QVBoxLayout()
        grp_option_layout.addWidget(option_1)
        grp_option_layout.addWidget(option_2)
        grp_option_layout.addWidget(option_3)

        grp_option.setLayout(grp_option_layout)

        # layout for diplay
        vbox_display = QVBoxLayout()

        hbox_setting = QHBoxLayout()
        hbox_setting.addWidget(grp_size)
        hbox_setting.addWidget(grp_shape)
        hbox_setting.addWidget(grp_direction)
        hbox_setting.addWidget(grp_option)

        vbox_display.addWidget(title_label)
        vbox_display.addLayout(hbox_setting)

        self.setLayout(vbox_display)
        self.show()

    @pyqtSlot(int)
    def puzzle_width_change(self, value):
        self.puzzle_width = value
        self.c.puzzle_setting.emit(
            [self.puzzle_width, self.puzzle_height, self.diff_val, self.option_val]
        )

    @pyqtSlot(int)
    def puzzle_height_change(self, value):
        self.puzzle_height = value
        self.c.puzzle_setting.emit(
            [self.puzzle_width, self.puzzle_height, self.diff_val, self.option_val]
        )

    @pyqtSlot(QRadioButton)
    def diff_checked(self, diff):
        text = diff.text()
        if text == "가로세로":
            self.shape = 0
        elif text == "가로세로 + 대각선":
            self.shape = 2
        elif text == "정방향":
            self.direction = 1
        elif text == "정방향 + 역방향":
            self.direction = 2

        self.diff_val = self.shape + self.direction
        self.c.puzzle_setting.emit(
            [self.puzzle_width, self.puzzle_height, self.diff_val, self.option_val]
        )

    @pyqtSlot(QRadioButton)
    def option_checked(self, option):
        text = option.text()
        if text == "글자 겹치지 않게":
            self.option_val = 0
        elif text == "글자 무작위로":
            self.option_val = 1
        elif text == "글자 겹치게":
            self.option_val = 2

        self.c.puzzle_setting.emit(
            [self.puzzle_width, self.puzzle_height, self.diff_val, self.option_val]
        )

class EnterWords(EnterWords):
    def init_UI(self):
        # Title for widget
        title = QLabel("2, 단어를 입력세요.")
        self.grid.addWidget(title, 0, 0)
        super(EnterWords, self).init_UI()

    def set_words(self):
        search_target = self.input_words.toPlainText()
        regex = r"[a-zA-Z]+_?[a-zA-Z]+"
        self.words = list({word.lower() for word in re.findall(regex, search_target)})
        if not self.words:
            regex = r"[가-힣]+_?[가-힣]+"
            self.words = list(
                {word.lower() for word in re.findall(regex, search_target)}
            )
            self.c.korean.emit(True)
        else:
            self.c.korean.emit(False)
        return self.words

class DownloadImage(DownloadImage):
    def __init__(self, c):
        super(DownloadImage, self).__init__(c)
        # initial puzzle settings
        self.width, self.height, self.diff, self.option = 15, 15, 1, 0
        # initialize download numbers
        self.picture_on = False
        # initialize language mode
        self.korean = False
        # initialize chosung or scramble mode
        self.chosung_scramable = False
        # initialize uppercase mode
        self.uppercase = False

    def init_UI(self):
        # Title for widget
        title = QLabel("3. 이미지를 선택하세요.")
        self.grid.addWidget(title, 0, 0)

        super(DownloadImage, self).init_UI()
        # get data of puzzle settings
        self.c.puzzle_setting.connect(self.puzzle_setting)
        # see if its korean or english/ default is english
        self.c.korean.connect(self.korean_on)

        self.uppercase_checkbox = QCheckBox("대문자", self)
        self.uppercase_checkbox.stateChanged.connect(self.uppercase_checkbox_on)

        self.chosung_scramable_checkBox = QCheckBox("scramble word", self)
        self.chosung_scramable_checkBox.setToolTip("단어의 철자가 뒤섞여서 제시됩니다.")
        self.chosung_scramable_checkBox.stateChanged.connect(self.chosung_scramable_on)

        self.make_puzzle_bt = QPushButton("Word Search\n퍼즐 만들기")
        self.make_puzzle_bt.clicked.connect(self.make_puzzle)
        self.make_puzzle_bt.setToolTip("단축키 : Ctrl + D")
        self.make_puzzle_bt.setShortcut("Ctrl+D")
        self.vbox.addWidget(self.uppercase_checkbox)

        self.vbox.addWidget(self.chosung_scramable_checkBox)
        self.vbox.addWidget(self.make_puzzle_bt)

    # define puzzle settings
    @pyqtSlot(list)
    def puzzle_setting(self, puzzle_setting):
        self.width, self.height, self.diff, self.option = (
            puzzle_setting[0],
            puzzle_setting[1],
            puzzle_setting[2],
            puzzle_setting[3],
        )

    @pyqtSlot(bool)
    def korean_on(self, bool):
        self.korean = bool
        if bool is True:
            self.chosung_scramable_checkBox.setText("초성")
            self.chosung_scramable_checkBox.setToolTip("단어의 초성으로 제시됩니다.")
            self.make_puzzle_bt.setText("낱말 퍼즐\n 만들기")
            self.uppercase_checkbox.close()
        else:
            self.chosung_scramable_checkBox.setText("scramble word")
            self.chosung_scramable_checkBox.setToolTip("단어의 철자가 뒤섞여서 제시됩니다.")
            self.make_puzzle_bt.setText("Word Search\n퍼즐 만들기")
            self.uppercase_checkbox.show()
        self.make_puzzle_bt.setToolTip("단축키 : Ctrl + D")
        self.make_puzzle_bt.setShortcut("Ctrl+D")

    @pyqtSlot()
    def uppercase_checkbox_on(self):
        if self.uppercase_checkbox.isChecked() is True:
            self.uppercase = True
        else:
            self.uppercase = False

    @pyqtSlot()
    def chosung_scramable_on(self):
        if self.chosung_scramable_checkBox.isChecked() is True:
            self.chosung_scramable = True
        else:
            self.chosung_scramable = False

    def enable_buttons(self):
        self.download_bt.setEnabled(True)
        self.make_puzzle_bt.setEnabled(True)
        self.c.enable_set_keyword_bt.emit()

    def disable_buttons(self):
        self.download_bt.setEnabled(False)
        self.make_puzzle_bt.setEnabled(False)
        self.c.disable_set_keyword_bt.emit()

    @pyqtSlot()
    def make_puzzle(self):
        word_image = []
        if self.tree.topLevelItemCount() == 0:
            self.start_download()
            return

        self.disable_buttons()

        if self.picture_on:
            iterator = QTreeWidgetItemIterator(
                self.tree, QTreeWidgetItemIterator.HasChildren
            )
        else:
            iterator = QTreeWidgetItemIterator(self.tree, QTreeWidgetItemIterator.All)
            if iterator.value() is None:
                self.c.press_set_keyword_bt.emit()
                q = QMessageBox(self)
                q.information(
                    self,
                    "information",
                    "검색어 키워드가 존재하지 않아요. 그래서 검색어 키워드 버튼을 대신 눌렀습니다~.",
                    QMessageBox.Ok,
                )
                self.enable_buttons()
                return
        while iterator.value():
            item = iterator.value()
            word = item.data(0, 0)
            pic = ""
            if self.picture_on:
                pic = item.path
                if not os.path.exists(pic):
                    self.c.press_set_keyword_bt.emit()
                    self.enable_buttons()
                    q = QMessageBox(self)
                    q.information(
                        self,
                        "information",
                        "선택하신 이미지가 존재하지 않습니다. 다시 다운로드 눌러주세요.",
                        QMessageBox.Ok,
                    )
                    return
            if word.strip().find(" ") != -1:
                if self.korean:
                    word = "가".join(word.split())
                else:
                    word = "a".join(word.split())
            word_image.append([word, pic])
            iterator += 1

        self.path = self.get_save_hwp_dir()
        if self.path:
            puzzle_worker = PuzzleWorker(
                wordsearch_generater.MakeWordSearch,
                word_image,
                self.width,
                self.height,
                self.diff,
                self.option,
                self.picture_on,
                self.korean,
                self.chosung_scramable,
                self.uppercase,
                self.path,
            )
            puzzle_worker.signal.puzzle_complete.connect(self.puzzle_finish)
            puzzle_worker.signal.recursionerrormsg.connect(self.recurerrormsg)
            puzzle_worker.signal.valueerrormsg.connect(self.valerrormsg)
            self.threadpool.start(puzzle_worker)
        else:
            self.enable_buttons()

    def get_save_hwp_dir(self):
        file_path = os.path.join(os.getcwd(), "dir_path.json")
        is_dir_path = os.path.exists(file_path)
        if is_dir_path:
            with open(file_path) as f:
                data = json.load(f)
            if "hwp_dir" in data.keys():
                dir_path = data["hwp_dir"]
                return dir_path
            else:
                q = QMessageBox(self)
                q.information(self, "information", "퍼즐을 저장할 폴더를 선택하세요.", QMessageBox.Ok)
                fname = str(QFileDialog.getExistingDirectory(self, "퍼즐을 저장할 폴더"))
                if fname:
                    data["hwp_dir"] = fname
                    with open(file_path, "w") as f:
                        json.dump(data, f)
                    dir_path = fname
                    return dir_path
                else:
                    return
        else:
            q = QMessageBox(self)
            q.information(self, "information", "퍼즐을 저장할 폴더를 선택하세요.", QMessageBox.Ok)
            fname = str(QFileDialog.getExistingDirectory(self, "퍼즐을 저장할 폴더"))
            if fname:
                with open(file_path, "w") as f:
                    json.dump({"hwp_dir": fname}, f)
                dir_path = fname
                return dir_path
            else:
                return

    @pyqtSlot()
    def puzzle_finish(self):
        q = QMessageBox(self)
        q.information(
            self, "information", "{}에 퍼즐 파일이 저장되었습니다.".format(self.path), QMessageBox.Ok
        )
        self.enable_buttons()

    @pyqtSlot()
    def recurerrormsg(self):
        q = QMessageBox(self)
        q.warning(self, "Warning", "단어의 개수에 비해서 퍼즐의 크기가 너무 작습니다.", QMessageBox.Ok)
        self.enable_buttons()

    @pyqtSlot()
    def valerrormsg(self):
        q = QMessageBox(self)
        q.warning(self, "Warning", "퍼즐의 크기에 비해 단어가 너무 길어요.", QMessageBox.Ok)
        self.enable_buttons()

# thread to download pictures while not stopping the Gui
class PuzzleWorker(QRunnable):
    def __init__(self, fn, *args, **kwargs):
        super(PuzzleWorker, self).__init__()
        self.fn = fn
        self.args = args
        self.kwargs = kwargs
        self.signal = Communication()

    @pyqtSlot()
    def run(self):
        try:
            self.fn(*self.args, **self.kwargs).make_puzzle()
            self.signal.puzzle_complete.emit()
        except RecursionError:
            self.signal.recursionerrormsg.emit()
        except ValueError:
            self.signal.valueerrormsg.emit()

class MainWindow(MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

    def init_UI(self):
        super(MainWindow, self).init_UI()
        self.setWindowTitle("Word Puzzle generator")
        self.setWindowIcon(QIcon("wordsearch.ico"))
        c = Communication()
        self.vbox.addWidget(Settings(c))
        self.enterwords_widget = EnterWords(c)
        self.vbox.addWidget(self.enterwords_widget)
        self.vbox.addWidget(DownloadImage(c))
        self.vbox.setStretch(0, 1)
        self.vbox.setStretch(1, 1)
        self.vbox.setStretch(2, 7)
        self.addsettingmenu()
        self.addhelpmenu()

    def addsettingmenu(self):
        self.settings_menu = self.mainMenu.addMenu("설정")
        self.set_grad_class_Button = QAction("학년 반 설정하기", self)
        self.set_grad_class_Button.triggered.connect(self.grade_class_dialog)
        self.settings_menu.addAction(self.set_grad_class_Button)

        self.reset_grade_class_Button = QAction("학년 반 초기화하기", self)
        self.reset_grade_class_Button.triggered.connect(self.reset_grade_class)
        self.settings_menu.addAction(self.reset_grade_class_Button)

    def addhelpmenu(self):
        self.help_menu = self.mainMenu.addMenu("도움말")

        self.puzzle_option_menu = self.help_menu.addMenu("퍼즐 옵션")
        self.shape_help = QAction("단어 모양은 무슨 뜻인가요?")
        # self.shape_help.triggered.connect(self.)
        self.puzzle_option_menu.addAction(self.shape_help)

        self.direction_help = QAction("단어 방향은 무슨 뜻인가요?")
        # self.direction_help.triggered.connect(self.)
        self.puzzle_option_menu.addAction(self.direction_help)

        self.option_help = QAction("옵션에서 글자를 겹치게 한다는 것은 무슨 뜻인가요?")
        # self.option_help.triggered.connect(self.)
        self.puzzle_option_menu.addAction(self.option_help)

        self.enter_words_menu = self.help_menu.addMenu("단어 입력")
        self.enterword_help = QAction("단어는 어떻게 입력하나요?")
        # self.enterword_help.triggered.connect(self.)
        self.enter_words_menu.addAction(self.enterword_help)

        self.prefix_help = QAction("실제 사진이 아니라 케릭터 사진을 원하면 어떻게 하나요?")
        # self.prefix_help.triggered.connect(self.)
        self.enter_words_menu.addAction(self.prefix_help)

        self.download_images_menu = self.help_menu.addMenu("이미지")
        self.keyword_help = QAction("원하는 이미지가 안 나올 때는 어떻게 하나요?")
        # self.keyword_help.triggered.connect(self.grade_class_dialog)
        self.download_images_menu.addAction(self.keyword_help)

        self.searchnum_help = QAction("이미지 검색 개수를 어떻게 바꾸나요?")
        # self.searchnum_help.triggered.connect(self.grade_class_dialog)
        self.download_images_menu.addAction(self.searchnum_help)

        self.changepic_help = QAction("원하는 이미지로 어떻게 변경하나요?")
        # self.changepic_help.triggered.connect(self.)
        self.download_images_menu.addAction(self.changepic_help)

        self.scramble_help = QAction("scramble word를 체크하면 어떻게 되나요?")
        # self.scramble_help.triggered.connect(self.)
        self.help_menu.addAction(self.scramble_help)

    def grade_class_dialog(self):
        self.grade_class_input = QWidget()
        hbox_grade = QHBoxLayout()
        grade_label = QLabel("학년")
        self.grade_spin = QSpinBox()
        self.grade_spin.setMinimum(1)
        self.grade_spin.setMaximum(6)
        hbox_grade.addWidget(grade_label)
        hbox_grade.addWidget(self.grade_spin)
        hbox_class = QHBoxLayout()
        class_label = QLabel("반")
        self.class_spin = QSpinBox()
        self.class_spin.setMinimum(1)
        hbox_class.addWidget(class_label)
        hbox_class.addWidget(self.class_spin)

        if os.path.exists("hwp_settings.json"):
            with open("hwp_settings.json") as f:
                data = json.load(f)
                self.grade_spin.setValue(data["grade"])
                self.class_spin.setValue(data["class"])

        ok_button = QPushButton("확인")
        ok_button.clicked.connect(self.set_grade_class)

        vbox_display = QVBoxLayout()
        vbox_display.addLayout(hbox_grade)
        vbox_display.addLayout(hbox_class)
        vbox_display.addWidget(ok_button)

        self.grade_class_input.setLayout(vbox_display)
        self.grade_class_input.show()

    def set_grade_class(self):
        self.grade = self.grade_spin.value()
        self.class_ = self.class_spin.value()
        data = dict()
        data["grade"] = self.grade
        data["class"] = self.class_
        with open("hwp_settings.json", "w") as f:
            json.dump(data, f)
        self.grade_class_input.close()

    def reset_grade_class(self):
        if os.path.exists("hwp_settings.json"):
            os.unlink("hwp_settings.json")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = MainWindow()
    app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
    sys.exit(app.exec_())


import sys
from collections import deque

n, k = map(int, sys.stdin.readline().rstrip().split())

dic = dict()
dic[n] = [0, 1]

q = deque()
q.append((n, 0, 1))

def bfs():
    while q:
        x, time, cnt = q.popleft()

        dx = [-1, 1, x]

        for i in range(3):
            if 0 <= x + dx[i] <= 200000:
                if not dic.get(x + dx[i]):
                    dic[x + dx[i]] = [time + 1, cnt]
                    q.append((x + dx[i], time + 1, cnt))
                else:
                    if dic[x + dx[i]][0] == time + 1:
                        dic[x + dx[i]][1] += 1
                        q.append((x + dx[i], time + 1, cnt))

bfs()

print(dic[k][0])
print(dic[k][1])


#!/bin/python3

import math
import os
import random
import re
import sys

# Complete the designerPdfViewer function below.
def designerPdfViewer(h, word):
    maxm = -1
    for alpha in word:
        index = ord(alpha) - 97
        value = h[index]
        if(maxm < value):
            maxm = value
    return (len(word) * maxm)

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')

    h = list(map(int, input().rstrip().split()))

    word = input()

    result = designerPdfViewer(h, word)

    fptr.write(str(result) + '\n')

    fptr.close()


# -*- coding: utf-8 -*-
"""
Spyder Editor

This is a temporary script file.
"""

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import mpl_finance as mpf
from datetime import datetime
import pandas as pd

plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
font = FontProperties(fname='/System/Library/Fonts/STHeiti Light.ttc')

df_stockload = ts.pro_bar(ts_code='600580.SH',start_date='20191025', end_date='20191122', freq="5min",ma=[5, 10, 24,48,120,240])
df_stockload = df_stockload.sort_index(ascending=False)

fig = plt.figure(figsize=(8,6),dpi=100,facecolor='white')
fig.subplots_adjust(left=0.09,bottom=0.20, right=0.94,top=0.90, wspace=0.2, hspace=0)
graph_KAV = fig.add_subplot(1,1,1)
mpf.candlestick2_ochl(graph_KAV, df_stockload.open,df_stockload.close,df_stockload.high,df_stockload.low, width=0.5, colorup='r', colordown='g')
graph_KAV.set_title("600580 卧龙电驱-5M线")
graph_KAV.set_xlabel("日期")
graph_KAV.set_ylabel("价格")
graph_KAV.set_xlim(0,len(df_stockload.index)) #设置一下x轴的范围
graph_KAV.set_xticks(range(0,len(df_stockload.index),45))#X轴刻度设定，每15天标一个日期

graph_KAV.set_xticklabels([df_stockload.index.strftime('%Y-%m-%d')[index] for index in graph_KAV.get_xticks()])#标签设置为日期

#X轴每个ticker标签都向右倾斜45度
for label in graph_KAV.xaxis.get_ticklabels():
    label.set_rotation(45)
    label.set_fontsize(10)#设置标签字号

plt.show()


#!/usr/bin/env python3

#main module to communicate with ROS
import rospy

#import the customized message type for Robot X (has two values: pos_x, pos_y (Float32))
from robot_x.msg import RobotPosition

#Create a global variable with the custom message
POSITION = RobotPosition()
#Getting initial values from rosparam server and assigning (Initial position)
POSITION.pos_x = rospy.get_param('initial_post_x')
POSITION.pos_y = rospy.get_param('initial_post_y')

#callback function for the subscriber of '/change_position' topic
def update_position(data):
	#accessing the global variable
	global POSITION
	#updating the global variable value
	POSITION = data

#publisher function
def pub_position_val():
	#accessing the global variable
	global POSITION

	#creating a publisher class object to publish position values
	#'position' -> topic name; RobotPosition -> msg type; 'queue_size' -> outgoing message queue used for asynchronous publishing
	position_pub = rospy.Publisher('position', RobotPosition, queue_size=10)

	#creating a Rate class object, at 10Hz, 10 times per second
	rate = rospy.Rate(10)

	#checking the ros master is alive
	while not rospy.is_shutdown():
		#publishing the global variable; msg type -> RobotPosition
		position_pub.publish(POSITION)
		#sleeping 0.1 seconds since Rate is 5 Hz
		rate.sleep()

if __name__ == "__main__":
	try:
		#initializing a new node
		rospy.init_node('position_pub_node')

		#creating a subscriber for the topic "change_position"
		#received data type -> RobotPosition; callback func -> update_position
		rospy.Subscriber("change_position", RobotPosition, update_position)

		#main function for publisher
		pub_position_val()

		#to keep alive the node, continuous spinning
		rospy.spin()

	#only ROS related exceptions will be captured
	except rospy.ROSInterruptException as e:
		print(e)


# built in high order functions

# lista = [[1,2], [2,3], [3,4], [4,5], [5,6]]
# print(max(lista, key=sum))  # Same for min()

"""with open(r'file.txt') as f:
     for line in iter(f.readline, ''):
        print(line)"""

# print(sorted(['ab', 'bc', 'ad'], key=lambda x: x[1], reverse=True))

#print(list(filter(lambda x: x%2 == 0, [1,2,3,4,5])))

from functools import partial

def tail(iterable, n, key=None):
    if key:
        return key(iterable[-n:])
    else:
        return iterable[-n:]

print(list(tail([1,2,3,4,5], 3, key=partial(map, lambda x: x**2))))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jul  1 14:51:33 2019

@author: michaelcornish
"""

import numpy as np
import os
from math import pi
import matplotlib.pyplot as plt
import pickle

# math functions
def sin(x):
    from math import sin
    output = np.array([sin(i) for i in x])
    return output

def cos(x):
    from math import cos
    output = np.array([cos(i) for i in x])
    return output

def ddx(y,k,N):
    # differentiates in fourier space
    output = np.real( np.fft.ifft( N*1j*k*np.fft.fft(y) ) )
    return output

def d2dx2(y,k,N):
    # differentiates in fourier space
    output = np.real( np.fft.ifft( -(N*k)**2*np.fft.fft(y) ) )
    return output

def f1(s, w, k,N):
    # The inputs s & w are in fourier space
    # output is the RHS of S evolution equation in fourier space

    K = N*k;

    Sx = np.real(np.fft.ifft(1j*K*s));
    Wx = np.real(np.fft.ifft(1j*K*w));

    #Runge-Kutta Step
    temp = np.fft.fft(-Sx*np.real(np.fft.ifft(w)) -0.5*Wx*(1 + np.real(np.fft.ifft(s))));

    # Preserve Symmetries
    temp  = np.real(temp);
    # Remove Machine Error
    temp[np.abs(temp) <1e-1] = 0;

    return temp

def f2(s, w,k,B_0, epsilon,N):
    # The inputs s & w are in fourier space
    # output is the RHS of W evolution equation in fourier space

    K = N*k;

    # Runge-Kutta Step
    first = 0.5*np.fft.ifft(w)**2  - (0.5*B_0/((1+np.fft.ifft(s))**2));
    second = (1/(1+np.fft.ifft(s)) - (epsilon*np.fft.ifft(-K**2*s))/(1 + (epsilon*(1+np.fft.ifft(1j*K*s))**2) ) )/np.sqrt(1 + (epsilon*(1+np.fft.ifft(1j*K*s))**2));
    third = -1j*K*np.fft.fft(first + second);
    fourth = np.fft.fft( np.fft.ifft(1j*K*np.fft.fft( (1+np.fft.ifft(s))**2*np.fft.ifft(1j*K*w)))*3/(1+np.fft.ifft(s))**2);
    temp = third + fourth;

    # Preserve Symmetries
    temp = 1j*np.imag(temp);
    # Remove Machine error
    temp[np.abs(temp) <1e-1] = 0;

    return temp

def single_fluid_plots(S,W,B_0,k,x,dt,save_prefix):

    factor = dt;
    p = min(S.shape[0], W.shape[0]);
    M = 10; # Number of curves

    plt.figure()
    for j in np.linspace(p//M, p,M).astype(int)[0:-1]:
        if j==p//M:
            plt.plot(x,1+S[0,:], label = 'Initial State');
        elif j == M-1:
            plt.plot(x,1+S[j,:],label = 't = {}'.format(factor*p))
        else:
            plt.plot(x,1+S[j,:]);

    plt.xlabel('z',fontsize = 18)
    plt.ylabel('S',fontsize = 18)
    plt.savefig(os.path.join(save_prefix, 'S.eps'))
    plt.close()

    plt.figure()
    for j in np.linspace(p//M, p,M).astype(int)[0:-1]:
        if j==p//M:
            plt.plot(x,1+W[0,:], label = 'Initial State');
        elif j == M-1:
            plt.plot(x,1+W[j,:],label = 't = {}'.format(factor*p))
        else:
            plt.plot(x,1+W[j,:]);

    plt.xlabel('z',fontsize = 18)
    plt.ylabel('W',fontsize = 18)
    plt.savefig(os.path.join(save_prefix, 'W.eps'))
    plt.close()

def Diss_Full_Curv_main(epsilon, B_0):
    file_path =  'Dissipation\B_0__{}\epsilon__{}'.format(B_0,epsilon)
    try:
        os.mkdir(file_path)
    except:
        pass

    # Initialization

    N = 2**10;                                     # fft works fastest with 2^n points.
    x = (2*pi/N)*np.array([i for i in range(N)]);  # spatial domain
    k = np.fft.fftfreq(x.shape[-1])                # frequency domain
    dt = 1e-4;                                     # Time step

    Q = 1;                            # Number of solution recordings
    S = np.zeros([Q,N]);                    # Solution matrix in real space
    W = np.zeros([Q,N]);                    # Solution matrix in real space

    S[0,:] = 0.1*cos(x);                 # Initial real space wave profile
    W[0,:] = -0.1*sin(x);              # Initial real space velocity profile
    Sf_old = np.fft.fft(S[0,:]);              # Initial Fourier space wave profile
    Wf_old = np.fft.fft(W[0,:]);              # Initial Fourier space velocity profile

    Sf_old = np.real(Sf_old)
    Wf_old = 1j*np.imag(Wf_old)
    Sf_old[Sf_old <1] = 0;
    Wf_old[abs(Wf_old) < 1] = 0;

    ## Main Loop

    #Diagnostics
    t = 1; p = 0;
    S_min = min(1+S[0,:]);
    S_threshold = 0.01;
    real_time = 0;
    nontrivial = True;
    non_converged = True;

    ##
    while S_min > S_threshold and real_time < 200 and nontrivial and non_converged:

        # Runge-Kutta Method
        k0 = f1(Sf_old, Wf_old,k,N);
        l0 = f2(Sf_old, Wf_old,k,B_0, epsilon,N);
        k1 = f1(Sf_old + 0.5*dt*k0,Wf_old + 0.5*dt*l0,k,N);
        l1 = f2(Sf_old + 0.5*dt*k0,Wf_old + 0.5*dt*l0,k,B_0, epsilon,N);

        Sf_new = Sf_old + dt*k1;
        Wf_new = Wf_old + dt*l1;

        # Diagnostics
        S_min = min(1+np.real(np.fft.ifft(Sf_new)));
        if S_min < S_threshold or np.isnan(S_min):
            print('Minimum S triggered stop')

        S_temp = np.real(np.fft.ifft(Sf_new))
        Sx  = np.max(np.abs( ddx(   S_temp,k,N)));
        Wx  = np.max(np.abs( ddx(   np.real(np.fft.ifft(Wf_new)),k,N)));
        Sxx = np.max(np.abs( d2dx2( S_temp,k,N)));

        if Sx >100 or Wx >100 or Sxx > 100:
            print('Slope Singlurity')
            break;

        # convergence test
        S_old = np.real(np.fft.ifft(Sf_old))
        S_new = np.real(np.fft.ifft(Sf_new))
        L2 = np.dot(S_old-S_new, S_old - S_new)
        if L2 < 1e-10 and t > 100:
            print('Convergence!')
            non_converged = False;

        # Update Solution and Scheme
        t = t+1;
        real_time =  dt*t;
        Sf_old = Sf_new; Wf_old = Wf_new;
        if real_time > 0.1*(p+1):
            S = np.vstack([S, np.real(np.fft.ifft(Sf_new))]);
            W = np.vstack([W, np.real(np.fft.ifft(Wf_new))]);
            p = p+1;

            if np.min(S[p,:]) > np.min(S[p-1,:]):
                nontrivial = False;
                print('')
                print('Trivial Solution Expected, Computations Stopped')
                print('')

    single_fluid_plots(S,W,B_0,k,x,dt,file_path)

    # Saving the objects:
    with open(os.path.join(file_path,'objs.pkl')) as f:  # Python 3: open(..., 'wb')
        pickle.dump([S,W], f)

    return S, W

'''
Main File
'''

B_0 = 0.5;                         # Magnetic Bond Number
linear_epsilon = 0.5;
'''
epsilon_list = np.linspace(linear_epsilon - 0.7*linear_epsilon, linear_epsilon + 0.3*linear_epsilon, 7);
epsilon_list = epsilon_list[-1:-1:0];
conservation_error_list = [];

ep_list = cat(2,epsilon_list2, epsilon_list3);
conservation_error_list2 = [];
'''
conservation_error_list = [];
N = 2**10;                                     # fft works fastest with 2^n points.
x = (2*pi/N)*np.array([i for i in range(N)]);  # spatial domain
k = np.fft.fftfreq(x.shape[-1])                # frequency domain
dt = 1e-4;                                     # Time step

dz = x[1]-x[0];

for epsilon in [0.1]:
    print('Working on epsilon = {}'.format(epsilon))
    S,W = Diss_Full_Curv_main(epsilon, B_0);
    conservation_error_list.append(np.trapz((1+S[0,:])**2,dx = dz) - np.trapz((1+S[-1,:])**2,dx = dz))


#POORLY OPTIMIZED NEEDS WORK

#import evdev
from evdev import InputDevice, categorize, ecodes
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup([14,15,18,23], GPIO.OUT)

b1 = 14 #servo control
b2 = 15
b3 = 18 #drive control
b4 = 23

#creates object 'gamepad' to store the data
#you can call it whatever you like
gamepad = InputDevice('/dev/input/event1')

#button code variables (change to suit your device)
aBtn = 305
bBtn = 304
xBtn = 307
yBtn = 306

upDown = 17
rightLeft = 16

plus = 313
minus = 312

home = 316
screenshot = 317

lTrig = 310
lBum = 308
rTrig = 311
rBum = 309

#prints out device info at start
print(gamepad)

#loop and filter by event code and print the mapped label
for event in gamepad.read_loop():
    if event.type == ecodes.EV_KEY:
        if event.value == 1:
            if event.code == bBtn:
                GPIO.output(b4, 0)
                GPIO.output(b3, 0)
                print("Motors Off")
            elif event.code == aBtn:
                GPIO.output(b4, 1)
                GPIO.output(b3, 1)
                print("Motors On")
            elif event.code == xBtn:
                GPIO.output([b1,b2,b3,b4], 0)
                print("STOP")

            elif event.code == lTrig:
                GPIO.output(b2, 1)
                GPIO.output(b1, 0)
                print("Left Turn")
            elif event.code == rTrig:
                GPIO.output(b2, 0)
                GPIO.output(b1, 1)
                print("Right Turn")
            elif event.code == plus:
                GPIO.output(b4, 1)
                GPIO.output(b3, 0)
                print("Speed +")
                sleep(0.01)
                GPIO.output(b4, 1)
                GPIO.output(b3, 1)
            elif event.code == minus:
                GPIO.output(b4, 0)
                GPIO.output(b3, 1)
                print("Speed -")
                sleep(0.01)
                GPIO.output(b4, 1)
                GPIO.output(b3, 1)
        elif event.value == 2:
            if event.code == lTrig:
                GPIO.output(b2, 1)
                GPIO.output(b1, 0)
            elif event.code == rTrig:
                GPIO.output(b2, 0)
                GPIO.output(b1, 1)
        elif event.value == 0:
            if event.code == lTrig:
                GPIO.output([b2,b1], 0)
            elif event.code == rTrig:
                GPIO.output([b2,b1], 0)


from collections import defaultdict
from Code.IRenderObject import IRenderObject

class Canvas:
    def __init__(self, size_x, size_y, fill=' '):
        self.sizeX = size_x
        self.sizeY = size_y
        self.fill_char = fill
        self.chars = defaultdict(lambda: fill)

    def resize(self, size_x, size_y):
        self.sizeX = size_x
        self.sizeY = size_y

    def set_fillchar(self, fillchar):
        self.fill_char = fillchar
        self.chars.default_factory = lambda: fillchar

    def add_char(self, x, y, char):
        self.chars[x, y] = char

    def add_line(self, x1, y1, x2, y2, char):
        dx = x2 - x1
        dy = y2 - y1

        dmax = abs(max(dx, dy))
        dx /= dmax
        dy /= dmax

        x = x1
        y = y1
        gx = round(x)
        gy = round(y)

        while x1 <= gx <= x2 and y1 <= gy <= y2:
            self.chars[gx, gy] = char
            x += dx
            y += dy
            gx = round(x)
            gy = round(y)

    def add_rect(self, x0, y0, size_x, size_y, char):
        self.add_line(x0, y0, x0 + size_x, y0, char)
        self.add_line(x0, y0, x0, y0 + size_y, char)
        self.add_line(x0 + size_x, y0, x0 + size_x, y0 + size_y, char)
        self.add_line(x0, y0 + size_y, x0 + size_x, y0 + size_y, char)

    def add_object(self, obj: IRenderObject):
        obj.darw(self)

    def fill_rect(self, x1, y1, sizeX, sizeY, char):
        for x in range(x1, x1 + sizeX + 1):
            for y in range(y1, y1 + sizeY + 1):
                self.chars[x, y] = char

    def add_text(self, x1, y1, sizeX, sizeY, text):
        x = x1
        y = y1
        for char in text:
            self.chars[x, y] = char
            x += 1
            if x >= x1 + sizeX:
                y += 1
                x = x1

            if y >= y1 + sizeY:
                return

    def clear(self):
        self.chars = defaultdict(lambda: self.fill_char)

    def draw(self):
        for y in range(self.sizeY):
            for x in range(self.sizeX):
                print(self.chars[x, y], end='')
            print()


import sqlite3
import json
import urllib.request as request
from flask import Flask
from flask_restx import Resource, Api
from flask_restx import fields
from flask_restx import reqparse
from flask_restx import Model
from flask import Response
from flask import send_file
from datetime import datetime
import pandas as pd
from matplotlib import pyplot as plt
import time

app = Flask(__name__)
api = Api(app, version='1.0', title='TV-MAZE API',
    description='A REST API build on TVMAZE API ',
)

port_number = 8000
host = 'localhost'

tv_model = api.model('TV',{'name':fields.Integer,
  'name':fields.String,
  'type':fields.String,
  'language':fields.String,
  'genres':fields.List(fields.String),
  'status':fields.String,
  'runtime':fields.Integer,
  'premiered':fields.String,
  'officialSite':fields.String,
  'schedule':fields.Raw,
  'rating':fields.Raw,
  'weight':fields.Integer,
  'network':fields.Raw,
  'summary':fields.String
})

parser = reqparse.RequestParser()
parser.add_argument('name', type=str, location='args' )
parser.add_argument('order_by',type=str, location='args' )
parser.add_argument('page', type=int , location='args')
parser.add_argument('page_size', type=int , location='args')
parser.add_argument('filter', type=str, location='args' )
parser.add_argument('format', type=str, location='args' )
parser.add_argument('by', type=str, location='args' )

##########################################  Q1 ########################################
@api.route('/tv-shows/import')
@api.doc(params={'name': 'title for the tv show'})
class ImportShow(Resource):
    @api.response(201, "Created")
    @api.response(404, "TV-show not found")
    def post(self):
        args = parser.parse_args()
        name = args.get('name')
        fname = name.replace(' ','%20')
        found = False
        updating = False
        dataSource = request.Request(f"http://api.tvmaze.com/search/shows?q={fname}")
        data=json.loads(request.urlopen(dataSource).read())
        for i in range(len(data)):
            if data[i]["show"]["name"].lower() == ' '.join(name.split()).lower():
                found = True
                res={"request":data[i]["show"]["name"],"name":name}
                updating, ID = Getkey(data[i]["show"]["id"])
                if not updating:
                    ID = ID+1
                result = InsertTuple(data[i]["show"],ID,updating)
        if not found:
          return {
                    "errors": {
                      "name": "The value '{}' is not a valid choice for 'name'.".format(name)
                    },
                    "message": "Input parameters validation failed"
                  },404
        else:
            return result,201

##########################################  Q2 ########################################

@api.route('/tv-shows/<id>')
@api.doc(params={'id': 'An ID'})
class RetrieveShow(Resource):
    @api.response(200, "OK")
    @api.response(404, "TV-show not found")
    def get(self,id):
        result = GetRecord(id)
        if result:
            return result,200
        else:
            return {"messge":"TVshow id: {} does not exist".format(id)},404

##########################################  Q3 ########################################
    @api.response(200, "OK")
    @api.response(404, "TV-show not found")
    def delete(self,id):
        con = sqlite3.connect('z5234102.db')
        c=con.cursor()
        show_exist = c.execute("SELECT Id from TVSHOWS where Id=?;",(id,)).fetchall()
        if len(show_exist):
            DeleteRecord(id)
            return {
                "message" :"The tv show with id {} was removed from the database!".format(id),
                "id": id
            },200
        else:
          return {
                    "errors": {
                      "id": "The value '{}' is not a valid choice for 'id'.".format(id)
                    },
                    "message": "Input parameters validation failed"
                  },404

##########################################  Q4 ########################################
    @api.response(201, "Created")
    @api.response(404, "TV-show not found")
    @api.expect(tv_model,validate=True)
    @api.doc(body=tv_model)
    def patch(self,id):
        payload = api.payload
        con = sqlite3.connect('z5234102.db')
        c=con.cursor()
        unix = int(time.time())
        update_time = str(datetime.fromtimestamp(unix).strftime('%Y-%m-%d-%H:%M:%S'))
        show_exist = c.execute("SELECT Id from TVSHOWS where Id=?;",(id,)).fetchall()
        if len(show_exist):
          c.execute("UPDATE TVSHOWS set last_update = ? where Id=?;",( update_time, id))
          i = 0
          for key, value in payload.items():
              if key == 'genres':
                  value = ','.join(value)
              if key == 'schedule' or key == 'rating' or key == 'network':
                  value = json.dumps(value)
              c.execute("UPDATE TVSHOWS set "+key+" = ? where Id=?;",(value,id,))
              time.sleep(0.01)
          con.commit()
          con.close()
          return {
              "id" : id,
              "last-update": update_time,
              "_links": {
                  "self": {
                    "href": "http://{}:{}/tv-shows/{}".format(host,port_number,id)
                  }
              }
          },201
        else:
            return {
                    "errors": {
                      "id": "The value '{}' is not a valid choice for 'id'.".format(id)
                    },
                    "message": "Input parameters validation failed"
                  },404

##########################################  Q5 ########################################
@api.route('/tv-shows')
@api.doc(params={'order_by': 'comma separated string value to sort the list based on the given criteria\n(+ ascending,-descending)'})
@api.doc(params={'page': 'page number will be shown'})
@api.doc(params={'page_size': 'the number of TV shows per page'})
@api.doc(params={'filter': 'attributes will be shown'})
class OrderShow(Resource):
    @api.response(200, "OK")
    @api.response(400, "Bad Request")
    def get(self):
        order_by = parser.parse_args().get('order_by')
        filter = parser.parse_args().get('filter')
        page = parser.parse_args().get('page')
        page_size = parser.parse_args().get('page_size')
        order_range = ['id','name','runtime','premiered','rating-average']
        filter_range = ['tvmaze_id','id' ,'last-update' ,'name','type ','language' ,'genres' ,'status' ,'runtime' ,'premiered ','officialSite' ,'schedule' ,'rating ','weight' ,'network' ,'summary']
        filter_list = []
        order_list = []
        # order_dic = {}
        if filter:
          for filter_item in filter.split(','):
              if filter_item not in filter_range:
                return {
                    "errors": {
                      "filter": "The value '{}' is not a valid choice for 'filter'.".format(filter_item)
                    },
                    "message": "Input payload validation failed"
                  },400
              else:
                filter_list.append(filter_item)
        else :
            filter_list = ['id','name']
        if order_by:
          for order_item in order_by.split(','):
              if order_item[0] == "+":
                  order_list.append(order_item[1:]+' ASC')
              elif order_item[0] == "-":
                  order_list.append(order_item[1:]+' DESC')
              else:
                  return {
                      "errors": {
                        "order_by": "The value should start with '+' or '-'."
                      },
                      "message": "Input payload validation failed"
                  },400
              if order_item[1:] not in order_range:
                  return {
                  "errors": {
                    "order_by": "The value '{}' is not a valid choice for 'order_by'.".format(order_item)
                  },
                  "message": "Input payload validation failed"
                },400
        else:
          order_list = ['id']
        con = sqlite3.connect('z5234102.db')
        c=con.cursor()
        ordered = c.execute("SELECT " + ','.join(filter_list)+" from TVSHOWS ORDER BY " + ','.join(order_list)+";").fetchall()
        con.commit()
        con.close()
        show_dic = {}
        result_list = []
        left_tuple = len(ordered)
        p = 1
        while left_tuple > page_size:
            show_list = []
            for i in range(page_size*(p-1),page_size+page_size*(p-1)):
              for j in range(len(filter_list)):
                  show_dic[filter_list[j]] = ordered[i][j]
              show_list.append(show_dic)
              show_dic = {}
            result = {
                "page": p,
                "page-size": page_size,
                "tv-shows": show_list,
            }
            result_list.append(result)
            left_tuple = left_tuple - page_size
            p +=1
        if left_tuple > 0:
            show_list = []
            for i in range(page_size*(p-1),len(ordered)):
              for j in range(len(filter_list)):
                  show_dic[filter_list[j]] = ordered[i][j]
              show_list.append(show_dic)
              show_dic = {}
            result = {
                "page": p,
                "page-size": page_size,
                "tv-shows": show_list,
            }
            result_list.append(result)
        else:
            p -= 1
        if page > 0 and page <= p:
            final_result = result_list[page-1]
        else:
            return {
                    "errors": {
                      "page": "The value '{}' is not a valid choice for 'page'.".format(page)
                    },
                    "message": "Input parameters validation failed"
                  },400
        if page > 1  and page < p:
            final_result["_links"] = {
                "self": {
                  "href": "http://{}:{}/tv-shows?order_by={}&page={}&page_size={}&filter={}".format(host,port_number,order_by,page,page_size,filter)
                },
                "previous": {
                  "href": "http://{}:{}/tv-shows?order_by={}&page={}&page_size={}&filter={},name".format(host,port_number,order_by,page-1,page_size,filter)
                },
                "next": {
                  "href": "http://{}:{}/tv-shows?order_by={}&page={}&page_size={}&filter={},name".format(host,port_number,order_by,page+1,page_size,filter)
                }
              }
            return final_result,200
        if page == 1 and p>1:
            final_result["_links"] = {
                "self": {
                  "href": "http://{}:{}/tv-shows?order_by={}&page={}&page_size={}&filter={}".format(host,port_number,order_by,page,page_size,filter)
                },
                "next": {
                  "href": "http://{}:{}/tv-shows?order_by={}&page={}&page_size={}&filter={}".format(host,port_number,order_by,page+1,page_size,filter)
                }
              }
            return final_result,200
        if page >1 and page == p:
            final_result["_links"] = {
                "self": {
                  "href": "http://{}:{}/tv-shows?order_by={}&page={}&page_size={}&filter={}".format(host,port_number,order_by,page,page_size,filter)
                },
                "previous": {
                  "href": "http://{}:{}/tv-shows?order_by={}&page={}&page_size={}&filter={},name".format(host,port_number,order_by,page-1,page_size,filter)
                }
              }
            return final_result,200
        if page ==1 and p ==1:
            final_result["_links"] = {
                "self": {
                  "href": "http://{}:{}/tv-shows?order_by={}&page={}&page_size={}&filter={}".format(host,port_number,order_by,page,page_size,filter)
                },
              }
            return final_result,200

##########################################  Q6 ########################################
@api.route('/tv-shows/statistics')
@api.doc(params={'format': 'json or image'})
@api.doc(params={'by': 'attributes of TVshow(language,genres,status,type)'})
class ShowStatistics(Resource):
    @api.response(200, "OK")
    @api.response(400, "Bad Request")
    def get(self):
        format = parser.parse_args().get('format')
        by = parser.parse_args().get('by')
        valid_by = ['language','genres','status','type']
        if by not in valid_by:
          return {
                  "errors": {
                    "by": "The value '{}' is not a valid choice for 'by'.".format(by)
                  }
                  },400
        con = sqlite3.connect('z5234102.db')
        c = con.cursor()
        lists = []
        update_time= []
        res = c.execute("SELECT "+by+", last_update from TVSHOWS;").fetchall()
        for i in range(len(res)):
            update_time.append(res[i][1])
            for j in range(len(res[i][0].split(','))):
                lists.append(res[i][0].split(',')[j])
        types =list(set(lists))
        t = time.time()
        count = 0
        for str_time in update_time:
            time_stamp = time.mktime(time.strptime(str_time,'%Y-%m-%d-%H:%M:%S'))
            if t - time_stamp < 172800:
              count += 1
        json_dic = {}
        pie_dic = {}
        for i in range(len(types)):
          json_dic[types[i]] = '%.1f%%' % (round(lists.count(types[i])/len(lists),3)*100)
          pie_dic[types[i]] = round(lists.count(types[i])/len(lists),3*100)
        if format == "json":
            result = {
                "total": len(lists),
                "total-updated": count,
                "values" : json_dic
              }
            con.commit()
            con.close()
            return result,200
        elif format == "image":
            plt.figure(figsize=(9,12))
            labels = list(pie_dic.keys())
            sizes = list(pie_dic.values())
            colors = ['tomato','navajowhite', 'lightskyblue', 'pink','violet', 'yellowgreen','lightgrey','sandybrown']
            colors = colors[:len(labels)]
            explode = (0.03,)*len(labels)
            patches,l_text,p_text = plt.pie(sizes,explode=explode,labels=labels,colors=colors,
                                            labeldistance = 1.05,autopct = '%3.1f%%',shadow = False,
                                            startangle = 90,pctdistance = 0.6)
            plt.axis('equal')
            plt.title(by+' of TVshows')
            plt.legend(loc='best')
            plt.savefig('Ass2.jpg')
            filename = './Ass2.jpg'
            with open(filename,'rb') as f:
                image = f.read()
            result = Response(image, mimetype="image/jpg")
            return result
        else:
          return{
                  "errors": {
                    "format": "The value '{}' is not a valid choice for 'format'.".format(format)
                  }
                  },400
###########################################################
#            self defined functions
# InsertTuple(record,ID,updating): insert imported TV shows into database
# Getkey(TVmazeId): get the apropriate ID for the insert record
# GetRecord(ID): get all info for an specific ID
# GetPreID(ID): find previous ID
# GetPreID(ID): find next ID
# DeleteRecord(ID): delete record where Id = ID
###########################################################
def InsertTuple(record,ID,updating):
    con = sqlite3.connect('z5234102.db')
    c=con.cursor()
    name = record["name"]
    unix = int(time.time())
    update_time = str(datetime.fromtimestamp(unix).strftime('%Y-%m-%d-%H:%M:%S'))
    tvmaze_Id  = record["id"]
    tuple_type = record["type"]
    language = record["language"]
    genres = ','.join(record["genres"])
    status = record["status"]
    runtime = record["runtime"]
    premiered = record["premiered"]
    officialSite =record["officialSite"]
    schedule = json.dumps(record["schedule"])
    rating = json.dumps(record["rating"])
    weight = record["weight"]
    network = json.dumps(record["network"])
    summary = record["summary"]
    _links = json.dumps(record["_links"])
    rating_average = record["rating"]["average"]
    if updating:
      c.execute("UPDATE TVSHOWS SET tvmaze_Id =?, last_update=? ,name=?,type=?,language=?,genres=?,status=?,runtime=?,premiered=?,officialSite=?,schedule=?,rating=?,weight=?,network=?,summary=?,_links=?,rating_average=? WHERE Id=? ", \
        (tvmaze_Id, update_time, name,tuple_type,language,genres,status,runtime,premiered,officialSite,schedule,rating,weight,network,summary,_links,ID,rating_average))
    else:
      c.execute("INSERT INTO TVSHOWS (Id,tvmaze_Id ,last_update,name,type,language,genres,status,runtime,premiered,officialSite,schedule,rating,weight,network,summary,_links,rating_average) \
      VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? )",(ID,tvmaze_Id ,update_time,name,tuple_type,language,genres,status,runtime,premiered,officialSite,schedule,rating,weight,network,summary,_links,rating_average))
    con.commit()
    con.close()
    result = {
              "id" : ID,
              "last-update": update_time,
              "tvmaze-id" : tvmaze_Id,
              "_links": {
                  "self": {
                    "href": "http://{}:{}/tv-shows/{}".format(host,port_number,ID)
                  }
              }
            }
    return result

def Getkey(TVmazeId):
    con = sqlite3.connect('z5234102.db')
    c = con.cursor()
    TVmazeId = str(TVmazeId)
    cursor = c.execute("SELECT Id, tvmaze_Id from TVSHOWS ;")
    all_records = cursor.fetchall()
    if len(all_records):
      cursor = c.execute("SELECT Id from TVSHOWS where tvmaze_Id=?;",(TVmazeId,))
      show_exist = cursor.fetchall()
      if len(show_exist): # show already exist in database, return Id of the show
          con.commit()
          con.close()
          return True,show_exist[0][0]
      else:# show not exist in database, return the max key in database
        cursor = c.execute("SELECT max( Id ) FROM TVSHOWS;")
        ID = cursor.fetchone()[0]
        con.commit()
        con.close()
        return False,ID
    else:
        con.commit()
        con.close()
        return False, 0

def GetRecord(ID):
    con = sqlite3.connect('z5234102.db')
    c = con.cursor()
    show_exist = c.execute("SELECT * from TVSHOWS where Id=?;",(ID,)).fetchall()
    con.commit()
    con.close()
    if len(show_exist):
        preId = GetPreID(ID)
        nextId = GetNextID(ID)
        result = {
            "tvmaze-id" :show_exist[0][1],
            "id": show_exist[0][0],
            "last-update": show_exist[0][2],
            "name": show_exist[0][3],
            "type": show_exist[0][4],
            "language":show_exist[0][5],
            "genres": show_exist[0][6].split(','),
            "status": show_exist[0][7],
            "runtime": show_exist[0][8],
            "premiered": show_exist[0][9],
            "officialSite": show_exist[0][10],
            "schedule":  json.loads(show_exist[0][11]),
            "rating": json.loads(show_exist[0][12]),
            "weight":  show_exist[0][13],
            "network": json.loads( show_exist[0][14]),
            "summary": show_exist[0][15]
        }
        if preId and nextId:
            previous = "http://{}:{}/tv-shows/{}".format(host,port_number,preId)
            nxt = "http://{}:{}/tv-shows/{}".format(host,port_number,nextId)
            result["_links"] = {
                  "self": {
                    "href": "http://{}:{}/tv-shows/{}".format(host,port_number,ID)
                  },
                  "previous": {
                    "href": previous
                  },
                  "next": {
                    "href": nxt
                  }
                }
        elif preId:
            previous = "http://{}:{}/tv-shows/{}".format(host,port_number,preId)
            result["_links"] = {
                  "self": {
                    "href": "http://{}:{}/tv-shows/{}".format(host,port_number,ID)
                  },
                  "previous": {
                    "href": previous
                  },
                }
        elif nextId:
            nxt = "http://{}:{}/tv-shows/{}".format(host,port_number,nextId)
            result["_links"] = {
                  "self": {
                    "href": "http://{}:{}/tv-shows/{}".format(host,port_number,ID)
                  },
                  "next": {
                    "href": nxt
                  }
                }
        else:
            result["_links"] = {
                  "self": {
                    "href": "http://{}:{}/tv-shows/{}".format(host,port_number,ID)
                  }
                }
        return result
    else:
      return {}

def GetPreID(ID):
  ID = int(ID)
  pre = ID-1
  con = sqlite3.connect('z5234102.db')
  c=con.cursor()
  while True:
      cursor = c.execute("SELECT Id from TVSHOWS where Id=?;",(pre,))
      show_exist = cursor.fetchall()
      if len(show_exist):
          con.commit()
          con.close()
          return pre
      else:
          pre = pre-1
          if pre == 0:
              con.commit()
              con.close()
              return 0

def GetNextID(ID):
  ID = int(ID)
  nxt = ID+1
  con = sqlite3.connect('z5234102.db')
  c=con.cursor()
  maxId = c.execute("SELECT max( Id ) FROM TVSHOWS;").fetchone()[0]
  while True:
      show_exist = c.execute("SELECT Id from TVSHOWS where Id=?;",(nxt,)).fetchall()
      if len(show_exist):
          con.commit()
          con.close()
          return nxt
      else:
          nxt = nxt+1
          if nxt > maxId:
              con.commit()
              con.close()
              return 0

def DeleteRecord(ID):
    con = sqlite3.connect('z5234102.db')
    c = con.cursor()
    c.execute("DELETE from TVSHOWS where ID=?;",(ID,))
    con.commit()
    con.close()

if __name__ == '__main__':
    con = sqlite3.connect('z5234102.db')
    c=con.cursor()
    c.execute('''CREATE TABLE  IF NOT EXISTS TVSHOWS
        (Id INT PRIMARY KEY     NOT NULL,
        tvmaze_Id      INT,
        last_update    TEXT,
        name          TEXT,
        type          TEXT,
        language      TEXT,
        genres        TEXT,
        status        TEXT,
        runtime       INT,
        premiered     TEXT,
        officialSite  TEXT,
        schedule      JSON,
        rating        JSON,
        weight        INT,
        network       TEXT,
        summary       TEXT,
        _links        TEXT,
      rating_average REAL);''')
    con.commit()
    con.close()
    app.run(host = host,
        port = port_number,
        debug = True)