# -*- coding: utf-8 -*-

import speech_recognition as sr
import urllib3
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
import webbrowser
import os
import pandas as pd
from bs4 import BeautifulSoup
import requests

def hava():
    url = requests.get("https://www.ntvhava.com/konum/eskisehir/3-gunluk-hava-tahmini")
    content = url.content
    soup = BeautifulSoup(content, "html.parser")

    günler = soup.find_all("div", class_="date")
    sıcaklıklar = soup.find_all("span", class_="range2 font25")
    sıcak = []
    for sıcaklık in sıcaklıklar:
        sıcak.append(sıcaklık.getText())
    del sıcak[1]
    del sıcak[2]
    del sıcak[3]

    tablo = {"-----Gün-----": [],
             "Sıcaklık": []}

    for gün, sıc in zip(günler, sıcak):
        tablo["-----Gün-----"].append(gün.getText())
        tablo["Sıcaklık"].append(sıc)

    data = pd.DataFrame(tablo)
    print(data)

urls = ["https://www.reddit.com/","https://www.youtube.com/","https://www.google.com/"]
print("***************SARVIS V1.0***************")
while True:
    r = sr.Recognizer()
    with sr.Microphone() as source:
        print("Dinliyorum... >> ")
        r.adjust_for_ambient_noise(source, duration=1)
        audio = r.listen(source, phrase_time_limit=5)

    try:
        command = r.recognize_google(audio,key=None, language="tr-TR")

        if "kapat" in command:
            print(command)
            print("durduruldu")
            sys.exit()
        elif command == "sayfalar":
            print(command)
            for sayfa in urls:
                webbrowser.open_new_tab(sayfa)
                print(sayfa+" açılıyor...")
        elif "hava durumu" in command:
            hava()
        elif command == "kaydet":
            try:
                    r = sr.Recognizer()
                    with sr.Microphone() as source:
                        print("Yazmak için dinliyorum... ")
                        r.adjust_for_ambient_noise(source, duration=1)
                        audio = r.listen(source, phrase_time_limit=10)
                    command_yaz = r.recognize_google(audio, key=None, language="tr-TR")
                    os.chdir("C:\\Users\\dogu2\\Desktop\\")
                    with open("yazıcı.txt", "w", encoding="utf-8") as yazdır:
                        yazdır.write(command_yaz)
                        yazdır.close()
            except sr.UnknownValueError:
                print("Anlaşılmadı..")
        elif command == "oku":
            metin = open("yazıcı.txt", "r", encoding="utf-8")
            okut = metin.read()
            print(okut)
        if "arama" in command:
            driver = webdriver.Chrome()
            driver.get("https://www.google.com/")
            ara = driver.find_element_by_class_name("gsfi")
            try:
                r = sr.Recognizer()
                with sr.Microphone() as source:
                    print("Aranacak şeyi söyle ")
                    r.adjust_for_ambient_noise(source, duration=1)
                    audio = r.listen(source, phrase_time_limit=5)

                    command_ara = r.recognize_google(audio, key=None, language="tr-TR")
                    ara.send_keys(command_ara)
                    ara.send_keys(Keys.ENTER)

            except sr.UnknownValueError:
                print("Tekrar söyle")

    except sr.UnknownValueError:
        print("Anlaşılmadı.Tekrar dene")


#!/usr/bin/python
# Golf
# Code Angel

import sys
import os
import pygame
from pygame.locals import *
import random

# Define the colours
WHITE = (255, 255, 255)
GREY = (62, 87, 113)

# Define constants
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480

SCOREBOARD_MARGIN = 4
SCOREBOARD_HEIGHT = 48
SCOREBOARD_LINE = 20
SCOREBOARD_COLUMNS = 10

HOLE_MESSAGE_Y = 60

METER_X = 25
METER_Y = SCOREBOARD_HEIGHT + 20

SLIDER_BORDER = 5
SLIDER_X = 35
SLIDER_TOP_PADDDING = 8

SLIDER_SPEED = 5
SLOW_SLIDER_SPEED = 20
SLOW_PUTT_RANGE = 3

MAX_POWER = 30
MIN_POWER = 1

START_BALL_X = 20
BALL_Y = 436
BALL_STEP = 3
BALL_DESCENT = 5

FLAG_Y = 244
RANDOM_FLAG_MIN = 10
RANDOM_FLAG_MAX = 30
FLAG_STEP = 18
HOLE_CENTRE = 8

# Setup
os.environ['SDL_VIDEO_CENTERED'] = '1'
pygame.mixer.pre_init(44100, -16, 2, 512)
pygame.mixer.init()
pygame.init()
game_screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Golf')
clock = pygame.time.Clock()
font = pygame.font.SysFont('Helvetica', 16)

# Load images
background_image = pygame.image.load('golf_background.png').convert()
power_meter_image = pygame.image.load('power_meter.png').convert()
slider_image = pygame.image.load('slider.png').convert_alpha()
ball_image = pygame.image.load('ball.png').convert_alpha()

flag_1_image = pygame.image.load('flag_1.png').convert_alpha()
flag_2_image = pygame.image.load('flag_2.png').convert_alpha()
flag_3_image = pygame.image.load('flag_3.png').convert_alpha()

# Load sounds
putt_sound = pygame.mixer.Sound('putt.ogg')
clap_sound = pygame.mixer.Sound('clap.ogg')

def main():

    # Initialise variables
    slider_direction = 'up'
    slider_timer = SLOW_SLIDER_SPEED
    shot_power = 1
    meter_height = power_meter_image.get_rect().height - 2 * SLIDER_BORDER

    ball_x = START_BALL_X
    ball_distance = 0
    ball_direction = 'right'
    final_ball_location = 0
    moves_per_flag = FLAG_STEP / BALL_STEP

    flag_distance = random.randint(RANDOM_FLAG_MIN, RANDOM_FLAG_MAX)
    flag_x = flag_distance * FLAG_STEP + HOLE_CENTRE

    hole = 1

    hole_strokes = [0, 0, 0]
    round_strokes = 0
    best_round_strokes = 0

    in_the_hole = False

    # Main game loop
    while True:

        for event in pygame.event.get():
            key_pressed = pygame.key.get_pressed()

            # SPACE key pressed - hit shot
            if key_pressed[pygame.K_SPACE] and ball_distance == 0 and in_the_hole is False:
                slider_direction = 'none'
                ball_distance = shot_power * moves_per_flag

                hole_strokes[hole - 1] += 1

                if ball_direction == 'right':
                    final_ball_location += shot_power
                else:
                    final_ball_location -= shot_power

                putt_sound.play()

            # RETURN pressed when ball is in the hole - start new hole
            elif key_pressed[pygame.K_RETURN] and in_the_hole is True:

                if hole == 3:

                    if round_strokes < best_round_strokes or best_round_strokes == 0:
                        best_round_strokes = round_strokes

                    hole = 1
                    hole_strokes = [0, 0, 0]
                    round_strokes = 0

                else:
                    hole += 1

                in_the_hole = False
                shot_power = 1
                slider_direction = 'up'

                ball_x = START_BALL_X
                ball_direction = 'right'
                final_ball_location = 0

                flag_distance = random.randint(RANDOM_FLAG_MIN, RANDOM_FLAG_MAX)
                flag_x = flag_distance * FLAG_STEP + HOLE_CENTRE

                slider_timer = SLOW_SLIDER_SPEED

            if event.type == QUIT:
                pygame.quit()
                sys.exit()

        # Update slider
        slider_timer -= 1

        if slider_timer == 0:

            # Slider moving up, increase shot power
            if slider_direction == 'up':
                shot_power += 1
                if shot_power == MAX_POWER:
                    slider_direction = 'down'

            # Slider moving down, decrease shot power
            elif slider_direction == 'down':
                shot_power -= 1
                if shot_power == MIN_POWER:
                    slider_direction = 'up'

            # New timer pause
            if shot_power <= SLOW_PUTT_RANGE:
                slider_timer = SLOW_SLIDER_SPEED
            else:
                slider_timer = SLIDER_SPEED

        # Update ball location
        if ball_distance > 0:

            if ball_direction == 'right':
                ball_x += BALL_STEP
            else:
                ball_x -= BALL_STEP

            # Ball gone off left or right hand edge of screen
            if ball_x > SCREEN_WIDTH or ball_x < 0:

                # Reset ball location at left of screen
                ball_x = START_BALL_X
                ball_distance = 0
                ball_direction = 'right'
                shot_power = 1

                # Reset slider at bottom of meter
                slider_direction = 'up'
                final_ball_location = 0
                slider_timer = SLOW_SLIDER_SPEED

            # Ball is still on screen so move ball closer to final_ball_position
            else:
                ball_distance -= 1

                # Ball has stopped rolling
                if ball_distance == 0:

                    # Ball in hole
                    if final_ball_location == flag_distance:
                        in_the_hole = True
                        round_strokes += hole_strokes[hole - 1]

                        clap_sound.play()

                    # Ball missed hole
                    else:
                        if final_ball_location < flag_distance:
                            ball_direction = 'right'
                        else:
                            ball_direction = 'left'

                        # Reset slider at bottom of meter
                        shot_power = 1
                        slider_direction = 'up'
                        slider_timer = SLOW_SLIDER_SPEED

        # Draw background
        game_screen.blit(background_image, [0, 0])

        # Draw meter and slider
        if ball_distance == 0 and in_the_hole is False:
            game_screen.blit(power_meter_image, [METER_X, METER_Y])

            slider_step = (MAX_POWER - shot_power) * meter_height / MAX_POWER
            slider_y = METER_Y + SLIDER_BORDER + slider_step - SLIDER_TOP_PADDDING
            game_screen.blit(slider_image, [SLIDER_X, slider_y])

        # Draw flag
        if hole == 1:
            game_screen.blit(flag_1_image, [flag_x, FLAG_Y])
        elif hole == 2:
            game_screen.blit(flag_2_image, [flag_x, FLAG_Y])
        elif hole == 3:
            game_screen.blit(flag_3_image, [flag_x, FLAG_Y])

        # Draw ball
        if in_the_hole is False:
            game_screen.blit(ball_image, [ball_x, BALL_Y])
        else:
            game_screen.blit(ball_image, [ball_x, BALL_Y + BALL_DESCENT])

        # Display scoreboard
        display_scoreboard(hole_strokes, round_strokes, best_round_strokes)

        # In the hole messages
        if in_the_hole is True:
            in_hole_message(hole, hole_strokes[hole - 1], round_strokes)

        pygame.display.update()
        clock.tick(30)

# Display the scoreboard
def display_scoreboard(hole_strokes, round_strokes, best):

    scoreboard_background_rect = (0, 0, SCREEN_WIDTH, SCOREBOARD_HEIGHT)
    pygame.draw.rect(game_screen, GREY, scoreboard_background_rect)

    # Display holes 1-3
    display_scoreboard_data('Hole:', 0, 0)

    for hole_number in range(1, 4):
        display_scoreboard_data(str(hole_number), hole_number, 0)

    # Display strokes on each of the 3 holes
    display_scoreboard_data('Strokes:', 0, 1)

    for hole_number in range(0, 3):
        if hole_strokes[hole_number] > 0:
            display_scoreboard_data(str(hole_strokes[hole_number]), hole_number + 1, 1)
        else:
            display_scoreboard_data(str('-'), hole_number + 1, 1)

    # Display total for round
    display_scoreboard_data('Total', 6, 0)

    if round_strokes > 0:
        display_scoreboard_data(str(round_strokes), 6, 1)
    else:
        display_scoreboard_data(str('-'), 6, 1)

    # Display best overall round
    display_scoreboard_data('Best', 7, 0)

    if best > 0:
        display_scoreboard_data(str(best), 7, 1)
    else:
        display_scoreboard_data(str('-'), 7, 1)

# Display scoreboard text items
def display_scoreboard_data(scoreboard_text, column, line):

    display_text = font.render(scoreboard_text, True, WHITE)

    text_x = SCREEN_WIDTH / SCOREBOARD_COLUMNS * column + SCOREBOARD_MARGIN
    text_y = SCOREBOARD_MARGIN + line * SCOREBOARD_LINE

    game_screen.blit(display_text, [text_x, text_y])

# Display message at the end of each hole
def in_hole_message(hole_number, hole_strokes, round_strokes):

    if hole_number == 3:
        message = 'Round completed in ' + str(round_strokes) + '. Press RETURN to play another round.'
        text = font.render(message, True, WHITE)
    else:
        message = 'In the hole in ' + str(hole_strokes) + '. Press RETURN to play next hole.'
        text = font.render(message, True, WHITE)

    background_x = SCOREBOARD_MARGIN * 4
    background_width = SCREEN_WIDTH - SCOREBOARD_MARGIN * 8
    background_height = 2 * SCOREBOARD_LINE
    message_background_rect = (background_x, HOLE_MESSAGE_Y, background_width, background_height)
    pygame.draw.rect(game_screen, GREY, message_background_rect)

    text_rect = text.get_rect()
    messsage_x = (SCREEN_WIDTH - text_rect.width) / 2
    message_y = HOLE_MESSAGE_Y + SCOREBOARD_LINE / 2
    game_screen.blit(text, [messsage_x, message_y])

if __name__ == '__main__':
    main()


"""
450. Delete Node in a BST
Medium

Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST.

Basically, the deletion can be divided into two stages:

Search for a node to remove.
If the node is found, delete the node.
Follow up: Can you solve it with time complexity O(height of tree)?

Example 1:

Input: root = [5,3,6,2,4,null,7], key = 3
Output: [5,4,6,2,null,null,7]
Explanation: Given key to delete is 3. So we find the node with value 3 and delete it.
One valid answer is [5,4,6,2,null,null,7], shown in the above BST.
Please notice that another valid answer is [5,2,6,null,4,null,7] and it's also accepted.

Example 2:

Input: root = [5,3,6,2,4,null,7], key = 0
Output: [5,3,6,2,4,null,7]
Explanation: The tree does not contain a node with value = 0.
Example 3:

Input: root = [], key = 0
Output: []

Constraints:

The number of nodes in the tree is in the range [0, 104].
-105 <= Node.val <= 105
Each node has a unique value.
root is a valid binary search tree.
-10^5 <= key <= 10^5
"""

"""
BST
recursively delete and merge

time O(log(N))
space O(log(N))
"""

class Solution:
    def removeKdigits(self, nums: str, k: int) -> str:
        n = len(nums)
        if n <= k:
            return "0"

        stack = []
        pop_count = 0

        for i, num in enumerate(nums):
            while stack and num < stack[-1] and pop_count < k:
                stack.pop()
                pop_count += 1
            stack.append(num)
            # print(stack)
        # if there's more digits left in stack than needed
        while stack and pop_count < k:
            stack.pop()
            pop_count += 1

        # print(stack)
        res = ''.join(stack).lstrip('0')
        return res if res else "0"

        def inorder(root):
            return inorder(root.left) + [root.val] + inorder(root.right) if root else []

        def successor(root):
            root = root.right
            while root.left:
                root = root.left
            return root

        def predecessor(root):
            root = root.left
            while root.right:
                root = root.right
            return root

def main():
    sol = Solution()
    assert sol.removeKdigits("1432219", 3) == "1219", 'fails'

    assert sol.removeKdigits("10200", 1) == "200", 'fails'

    assert sol.removeKdigits("10", 2) == "0", 'fails'

    assert sol.removeKdigits("112", 1) == "11", 'fails'

if __name__ == '__main__':
   main()


from django.urls import path
from .views import *

urlpatterns = [
    path('', index, name='index'),
    path('about/', about, name='about'),
    path('services/', services, name='services'),
    path('faq/', faq, name='faq'),
    path('404/', error, name='404'),
    path('pricing/', pricing, name='pricing'),
    path('portfolio-3-col/', portfolio_3, name='portfolio-3-col'),
    path('portfolio-4-col/', portfolio_4, name='portfolio-4-col'),
    path('portfolio-item/', portfolio_item, name='portfolio-item'),
    path('blog/', blog, name='blog'),
    path('blog-post/', blog_post, name='blog-post'),
    path('contact/', contact, name='contact'),
    path('create_service/', create_service, name='create_service'),
    path('login/', login_user, name='login'),
    path('registration', registration, name='registration'),

]


import itertools
import struct
import math
import wave

class WavOutput:
    """Outputs a list of vectors to a wav file."""

    def __init__(self, filename, fps, rate=192000):
        self.wavrange = 32766
        self.chunk_size = 1024 * 1024 # 1 MB
        self.wavbuffer = []
        self.samples_per_frame = rate / fps
        self.samplerate = rate
        self.raw = filename.endswith(".raw")
        if self.raw:
            self.audio_out = open(filename, "wb")
        else:
            self.audio_out = wave.open(filename, "w")
            self.audio_out.setparams((2, 2, rate, 0, 'NONE', 'not compressed'))

    def setfps(self, value):
        self.samples_per_frame = self.samplerate / value

    def distance(self, p0, p1):
        """Get distance between two 2D points."""
        return math.sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2)

    def valid_vecs(self, vecs, size):
        """Returns only non-duplicate vectors, shrunken to within wavrange"""
        results = set()
        shrunken = set()
        for vec in vecs:
            if (vec not in results) and (vec[::-1] not in results):
                results.add(vec)
                if abs(vec[0][0]) > size or abs(vec[0][1]) > size or abs(vec[1][0]) > size or abs(vec[1][1]) > size:
                    continue
                shrunken.add(((((vec[0][0] / size) * self.wavrange * 2) - self.wavrange, ((vec[0][1] / size) * self.wavrange * 2) - self.wavrange), (((vec[1][0] / size) * self.wavrange * 2) - self.wavrange, ((vec[1][1] / size) * self.wavrange * 2) - self.wavrange)))
        return shrunken

    def buffer_wav(self, chunk):
        if chunk is None:
            if self.raw:
                self.audio_out.write("".join(self.wavbuffer))
            else:
                self.audio_out.writeframes("".join(self.wavbuffer))
            self.audio_out.close()
            del self.wavbuffer[:]
            return
        self.wavbuffer.append(chunk)
        if len(self.wavbuffer) > self.chunk_size:
            if self.raw:
                self.audio_out.write("".join(self.wavbuffer))
            else:
                self.audio_out.writeframes("".join(self.wavbuffer))
            del self.wavbuffer[:]  # insta-clear with GC

    def add_sample(self, vec):
        try:
            left = struct.pack('h', int(round(vec[0])))
            right = struct.pack('h', int(round(vec[1])))
            self.buffer_wav(left)
            self.buffer_wav(right)
        except:
            pass

    def wavify(self, unsorted_vecs, size):
        vecs = self.valid_vecs(unsorted_vecs, size)
        distances = {}
        for vec in vecs:
            distances[vec] = self.distance(vec[0], vec[1])
        drawspeed = sum(distances.itervalues()) / self.samples_per_frame
        offset = -0.1
        step = 0.01
        samples = {}
        while True:
            samples_left = int(self.samples_per_frame)
            for vec in vecs:
                start = vec[0]
                end = vec[1]
                vec_samples = int(round((distances[vec] / drawspeed) - offset))
                samples[vec] = vec_samples
                samples_left -= vec_samples
            if samples_left >= 0:
                break
            samples = {}
            offset += step
        keys = samples.keys()
        keys.sort(key=lambda pt: ((pt[0][0] + pt[1][0]) / 2, (pt[0][1] + pt[1][1]) / 2))
        for vec, vec_samples in itertools.izip(keys, itertools.imap(samples.get, keys)):
            pos = list(vec[0])
            dist = distances[vec]
            normal = ((vec[1][0] - vec[0][0]) / (vec_samples - 1), (vec[1][1] - vec[0][1]) / (vec_samples - 1))
            for i in xrange(vec_samples - 1):
                pos[0] += normal[0]
                pos[1] += normal[1]
                self.add_sample(pos)
        for _ in range(samples_left):
            self.add_sample((0,0))


# -*- coding: UTF-8 -*-
## Copyright 2013 Luc Saffre
## This file is part of the Lino project.
## Lino is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
## Lino is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## You should have received a copy of the GNU General Public License
## along with Lino; if not, see <http://www.gnu.org/licenses/>.

"""
This package contains the `Site` class, :xfile:`settings.py`
and :xfile:`models.py` module for the :ref:`belref` project.
"""

from __future__ import unicode_literals

from os.path import join, abspath, dirname

from lino.projects.std.settings import *

from django.utils.translation import ugettext_lazy as _

class Site(Site):

    #~ title = __name__
    verbose_name = "Lino Belref"
    description = _("Belgian Reference System.")
    version = "0.1"
    url = "http://www.lino-framework.org/api/lino.projects.belref.html"
    author = 'Luc Saffre'
    author_email = 'luc.saffre@gmail.com'

    demo_fixtures = 'demo all_countries be few_cities inscodes'
    #~ demo_fixtures = 'demo'

    use_extjs = False
    #~ admin_prefix = 'admin'
    plain_prefix = ''

    #~ anonymous_user_profile =

    languages = 'fr nl de'

    #~ project_model = 'tickets.Project'
    #~ user_model = 'users.User'

    #~ sidebar_width  = 3

    #~ def get_main_action(self,user):
        #~ return self.modules.lino.Home.default_action

    def get_installed_apps(self):
        for a in super(Site,self).get_installed_apps():
            yield a
        #~ yield 'django.contrib.contenttypes'
        #~ yield 'lino.modlib.users'
        yield 'lino.modlib.system'
        yield 'lino.modlib.statbel'
        yield 'lino.modlib.countries'
        #~ yield 'lino.modlib.contacts'
        #~ yield 'lino.modlib.outbox'
        #~ yield 'lino.modlib.blogs'
        #~ yield 'lino.modlib.tickets'
        #~ yield 'lino.modlib.pages'
        yield 'lino.modlib.concepts'
        yield 'lino.projects.belref'

    def setup_menu(self,ui,profile,main):
        """
        We create a new menu from scratch because the default menu structure
        wouldn't fit.
        """
        from django.utils.translation import ugettext_lazy as _
        from lino import dd
        concepts = dd.resolve_app('concepts')
        m = main.add_menu("concepts",concepts.MODULE_LABEL)
        m.add_action(self.modules.concepts.Concepts)
        m.add_action(self.modules.countries.Countries)
        m.add_action(self.modules.countries.Cities)

    def get_main_action(self,user):
        return self.modules.belref.Main.default_action


import pandas as pd
df = pd.DataFrame(pd.read_excel(r'C:\Users\Scott\Documents\Tencent Files\1172720089\FileRecv\2023_MCM-ICM_Problems\2023_MCM-ICM_Problems\Problem_C_Data_Wordle.xlsx'))
alist = [f'{i}tries' for i in range(1,8)]
#每一行的数据都画成表格
data = []
for i in df.iterrows():
    i = list(i)
    data.append(i[1][5:])
newdata = [dict(i) for i in data]
print(newdata)

# 获取字母和计数的列表
trys = list(newdata.keys())
counts = list(newdata.values())

# 创建一个条形图
fig, ax = plt.subplots()
ax.bar(trys, counts)

# 设置图表标题和坐标轴标签
ax.set_title('字母出现频率')
ax.set_xlabel('Letter')
ax.set_ylabel('Frequency')

# 自适应调整X轴标签的显示
plt.xticks(rotation=0, ha='center')

# 显示图表
plt.show()


import torch
import torch.nn as nn
import torch.nn.functional as F

from torch.nn.modules.utils import _pair

class WeightDropConv2d(nn.Conv2d):
    """
    Reimplementing baal version of WeightDropConv2d, because it doesn't support multi-GPU training
    For details, see https://github.com/pytorch/pytorch/issues/8637
    """
    def __init__(self, weight_dropout=0.0, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.weight_dropout = weight_dropout

    def forward(self, input: torch.Tensor) -> torch.Tensor:
        dropped_weight = torch.nn.functional.dropout(self.weight, p=self.weight_dropout, training=self.training)
        if self.bias is not None:
            dropped_bias = torch.nn.functional.dropout(self.bias, p=self.weight_dropout, training=self.training)
            return self._conv_forward(input, dropped_weight, dropped_bias)
        else:
            return self._conv_forward(input, dropped_weight, self.bias)

    def _conv_forward(self, input, weight, bias):
        if self.padding_mode != 'zeros':
            return F.conv2d(F.pad(input, self._reversed_padding_repeated_twice, mode=self.padding_mode),
                            weight, bias, self.stride, _pair(0), self.dilation, self.groups)
        return F.conv2d(input, weight, bias, self.stride, self.padding, self.dilation, self.groups)

class WeightDropLinear(nn.Linear):
    """
    Reimplementing baal version of WeightDropLinear, because it doesn't support multi-GPU training
    For details, see https://github.com/pytorch/pytorch/issues/8637
    """
    def __init__(self, weight_dropout=0.0, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.weight_dropout = weight_dropout

    def forward(self, input: torch.Tensor) -> torch.Tensor:
        dropped_weight = torch.nn.functional.dropout(self.weight, p=self.weight_dropout, training=self.training)
        dropped_bias = torch.nn.functional.dropout(self.bias, p=self.weight_dropout, training=self.training)
        return F.linear(input, dropped_weight, dropped_bias)

def uniform_dropout(input, p=0.5, training=False, inplace=False):
    beta = p
    assert 0.0 < beta <= 1.0
    if training:
        out = input * (1.0 + torch.empty(input.shape, device=input.device).uniform_(-beta, beta))
        if inplace:
            raise NotImplementedError()
        return out
    else:
        return input


"""Defines URL patterns for learning_logs."""

from django.conf.urls import url

from .views import index, topics, topic, new_topic, new_entry, edit_entry, edit_topic

urlpatterns = [
    #Home page
    url(r'^$', index, name='index'),

    # Show all topics.
    url(r'^topics/$', topics, name='topics'),

    #show all topics
    url(r'^topics/(?P<topic_id>\d+)/$', topic, name='topic'),

    #page for adding a new topic
    url(r'^new_topics/$', new_topic, name='new_topic'),

    url(r'^new_entry/(?P<topic_id>\d+)/$', new_entry, name='new_entry'),

    #page for editing an entry
    url(r'^edit_entry/(?P<edit_id>\d+)/$', edit_entry, name='edit_entry'),

    #page for editing a topic
    url(r'^edit_topic/(?P<edit_id>\d+)/$', edit_topic, name='edit_topic')
]


import os
import re
import numpy as np
import pygame
import math
from .utils import *
from .env_configs import *
import scipy.spatial as sp

# ==============================================
# Car Class
# ==============================================

class Car(pygame.sprite.Sprite):
    """
        Car Pygame sprite object.

        Parameters
        ----------
        init_angle: int
        init_x: int
        init_y: int
        fps: int
    """
    def __init__(self, init_angle, init_x, init_y, car_file, fps=60):
        self.image = pygame.image.load(car_file)
        self.img = None
        self.img_mask = None
        self.img_rect = None
        self.clock = pygame.time.Clock()
        self.fps = fps

        self.x = init_x
        self.y = init_y
        self.theta = init_angle
        self.v = 0                  # center velocity
        self.w = 0                  # angular velocity
        self.dv = 0                 # acceleration
        self.dw = 0                 # angular acceleration
        self.l = 1                  # half the length of axis between the wheel
        self.M = 1                  # mass of unicycle
        self.J = 1                  # inertia moment
        self.Bv = 1                 # translational friction coefficient
        self.Bw = 25                 # rotational friction coefficient

        pygame.sprite.Sprite.__init__(self)

    def reset(self):
        """
            Reset car member variables.
        """
        self.theta = 0
        self.x = self.init_x
        self.y = self.init_y

    @property
    def xpos(self): return self.x

    @property
    def ypos(self): return SCREEN_HEIGHT - self.y

    @property
    def theta_degrees(self):
        return self.theta*(180/math.pi)

    @property
    # pose of car with bottom left origin
    def pose(self): return [self.xpos, self.y, self.theta_degrees]

    @property
    def to_screen_coords(self):
        """Convert pose of car from car from to pygame coordinates
        """
        return [self.xpos, self.ypos, self.theta_degrees]

    @property
    def center(self):
        """Compute direct center of egovehicle
        """
        return [self.xpos + self.img_rect.center[0], self.ypos + self.img_rect.center[1]]

    def set_friction(self, trans_coef, rot_coef):
        self.Bv = trans_coef
        self.Bw = rot_coef

    def step(self, action):
        """Take a step in the environment
        Parameters
        ----------
        action: numpy.array
        """
        # ================================
        # Unicycle Dynamics Model
        # ================================
        # dt = self.clock.tick_busy_loop(self.fps) / 1000.0 # in milliseconds
        dt = 0.033 # cancel the adaptive time interval settings staff

        if action is None: return
        F = action[0] + action[1]
        T = self.l * (action[1] - action[0])

        # the acceleration
        self.dw = (T - self.Bw*self.w)/self.J
        self.dv = (F - self.Bv*self.v)/self.M

        # distance
        ds = self.v*dt + 0.5*self.dv*(dt**2)
        dtheta = self.w*dt + 0.5*self.dw*(dt**2)

        # update state
        self.x = self.x + ds*math.cos(self.theta)
        self.y = self.y + ds*math.sin(self.theta)
        self.theta = wrap2pi(self.theta + dtheta)

        # update velocity
        self.w = self.w + self.dw*dt
        self.v = self.v + self.dv*dt

    def rotate(self):
        """Rotate an image while keeping its center and size
        """
        orig_rect = self.image.get_rect()
        rot_image = pygame.transform.rotate(self.image, self.theta_degrees)
        rot_rect = orig_rect.copy()
        rot_rect.center = rot_image.get_rect().center
        rot_image = rot_image.subsurface(rot_rect).copy()
        return rot_image

    def blit(self, screen, action):
        """Render car in pygame display
        """
        self.img = self.rotate()
        self.img_mask = pygame.mask.from_surface(self.img)
        self.img_rect = self.img.get_rect()
        screen.blit(self.img, self.to_screen_coords[:2])
        self.step(action)

# ==============================================
# Game Info class
# ==============================================
class Info:
    def __init__(self, font_size=24):
        self.font = pygame.font.SysFont("monospace", font_size, bold=True)

    def set_sensors(self, sensors):
        self.sensors = sensors

    def process_values(self, v):
        subtext = None

        if type(v) == list or type(v) == np.ndarray:
            subtext = " {:.3f} " * len(v)
            subtext = subtext.format(*v)
        elif type(v) == int or type(v) == float or isinstance(v, np.float64):
            subtext = " {:.3f} "
            subtext = subtext.format(v)
        elif type(v) == bool or type(v) == str:
            subtext = " {} "
            subtext = subtext.format(v)
        else:
            print(type(v))
            raise NotImplementedError

        return subtext

    def blit_info(self, name, value):
        subtext = self.process_values(value)
        sensor_text = "{}:".format(name) + subtext
        label = self.font.render(sensor_text, 1, RED)
        label_size = self.font.size(sensor_text)
        return subtext, sensor_text, label, label_size

    def blit(self, screen, info):
        width, height = screen.get_size()
        num_keys = len(info)

        for i, (k, v) in enumerate(info.items()):
            subtext = self.process_values(v)
            text = "{}:".format(k) + subtext
            label = self.font.render(text, 1, RED)
            label_size = self.font.size(text)
            screen.blit(label, (width - label_size[0], height - label_size[1] * (num_keys - i)))

        if hasattr(self, 'sensors'):
            num_sensors = len(self.sensors)
            for i, sensor in enumerate(self.sensors._sensors):
                subtext, sensor_text, label, label_size = self.blit_info(sensor.name, sensor.text)
                screen.blit(label, (width - label_size[0], label_size[1] * i))

# ==============================================
# Sensor base class
# ==============================================
from abc import ABCMeta, abstractmethod

class Sensor(object):
    def __init__(self, car, road):
        self.car = car
        self.road = road

    @abstractmethod
    def measure(self):
        pass

    @abstractmethod
    def blit(self, screen):
        pass

    @property
    def text(self): return self.measurement

# ==============================================
# Sensor for computing distance from car to center of lane
# ==============================================
class CenterLaneSensor(Sensor):
    def __init__(self, _id, car, road, oriented_curve, num_future_info=0):
        super(CenterLaneSensor, self).__init__(car, road)
        self.name = 'CenterLaneSensor' + str(_id)
        self.oriented_curve = oriented_curve
        self.win = 5
        self.num_future_info = num_future_info
        self.measure()

    def measure(self):
        car_center = np.array(self.car.center)[np.newaxis, :]
        mask = pygame.surfarray.array2d(self.road.center_lane)
        coords = np.array(mask.nonzero()).transpose()

        distances = sp.distance.cdist(car_center, coords)
        point = coords[distances.argmin()]
        dist = distances.min()
        import copy
        dist_unsign = copy.deepcopy(dist)

        screen_point = to_screen_coords(point)
        self.visual_closest_point = point

        # compute the relative pos of car wrt. lane
        # determine the car relative pos
        cross_screen_coord, indx = self.measure_car_relativepos_lane()
        if cross_screen_coord > 0: # car on the left lane
            dist *= -1

        # compute the coords of cloest point in car frame
        # compute the angle difference first wrt. car heading direction
        angle_diff_unsign, cross_car_coord = self.measure_angle_diff_unsign(indx)
        # compute the x and y pos in car frame
        if cross_car_coord > 0: # center in left of car
            ypos = dist_unsign*math.cos(angle_diff_unsign)
            xpos = -1*dist_unsign*math.sin(angle_diff_unsign)
        else: # center in the right of car
            ypos = dist_unsign*math.cos(angle_diff_unsign)
            xpos = dist_unsign*math.sin(angle_diff_unsign)
        center_pos_car_coord = [xpos, ypos]

        # closest distance
        self.closest_point = center_pos_car_coord

        # get the future lane pos information
        future_center_pos_car_coord = self.measure_future_lane_pos(indx)

        # measurement
        # self.measurement=[dist, *future_center_pos_car_coord]
        self.measurement = [dist, *center_pos_car_coord, *future_center_pos_car_coord]
        return center_pos_car_coord, dist

    def measure_future_lane_pos(self, indx):
        future_center_pos_car_coord = [] # in car frame

        # get car position and vector
        car_center = np.array(self.car.center)[np.newaxis, :]
        # car_screen_coord = to_screen_coords(car_center)
        # car vector
        car_theta_rads = self.car.theta
        car_vec = np.array([math.cos(car_theta_rads), math.sin(car_theta_rads)])
        # car vector normal direction vector
        u1 = car_vec / np.linalg.norm(car_vec)
        # Append the future lane center points information
        for i in range(self.num_future_info):
            # get the future point
            point = self.oriented_curve[wrap(self.oriented_curve, indx+i*5+1, 0)]
            # get distance
            dist_unsign = sp.distance.cdist(car_center, np.expand_dims(point, axis=0)).min()
            # get unsigned angle difference wrt. car
            angle_diff_unsign, cross_car_coord = self.measure_angle_diff_unsign(indx+i*5+1)
            # compute the x and y pos in car frame
            if cross_car_coord > 0: # center in left of car
                ypos = dist_unsign*math.cos(angle_diff_unsign)
                xpos = -1*dist_unsign*math.sin(angle_diff_unsign)
            else: # center in the right of car
                ypos = dist_unsign*math.cos(angle_diff_unsign)
                xpos = dist_unsign*math.sin(angle_diff_unsign)
            center_pos_car_coord = [xpos, ypos]
            future_center_pos_car_coord.extend(center_pos_car_coord)

        return future_center_pos_car_coord

    def measure_car_relativepos_lane(self):
        # find closest point on oriented curve
        car_center = np.array(self.car.center)[np.newaxis, :]
        distances = sp.distance.cdist(car_center, self.oriented_curve).squeeze(0)
        indx = distances.argmin()
        # get closest point coordinates
        p1 = self.oriented_curve[wrap(self.oriented_curve, indx, -self.win)]
        p2 = self.oriented_curve[wrap(self.oriented_curve, indx, self.win)]
        # to world coordinates
        pos1 = to_screen_coords(p1)
        pos2 = to_screen_coords(p2)
        # road vec and center2car vec
        center2car = to_screen_coords(car_center.squeeze()) - to_screen_coords(self.oriented_curve[wrap(self.oriented_curve, indx, 0)])
        road_vec = pos2 - pos1
        # compute cross product of road vec and center2car vec
        cross = road_vec[0]*center2car[1] - center2car[0]*road_vec[1]
        # cross > 0: car is on left, cross < 0: car is on right
        return cross, indx

    def measure_angle_diff_unsign(self, indx):
        # cloest center of lane lane direction vector
        car_center = np.array(self.car.center)[np.newaxis, :]

        # car to lane center vector
        car2center = to_screen_coords(self.oriented_curve[wrap(self.oriented_curve, indx, 0)]) - to_screen_coords(car_center.squeeze())

        # car vector
        car_theta_rads = self.car.theta
        car_vec = np.array([math.cos(car_theta_rads), math.sin(car_theta_rads)])

        # compute angle between two vectors
        u1 = car_vec / np.linalg.norm(car_vec)
        u2 = car2center / np.linalg.norm(car2center)
        angle_diff = np.arccos(np.dot(u2, u1)) # in radians

        # compute left/right of center point in car frame
        # cross < 0: center in right, corss > 0: center in left
        cross = u1[0]*u2[1] - u1[1]*u2[0]

        return angle_diff, cross

    @property
    def text(self): return f"P: {self.closest_point[0]:.2f} {self.closest_point[1]:.2f}, D: {round(self.measurement[0], 3)}"

    def blit(self, screen):
        pygame.draw.circle(screen, BLUE, tuple(self.visual_closest_point), 10)

# ==============================================
# Sensor for computing lane direction
# ==============================================
class LaneDirectionSensor(Sensor):
    def __init__(self, _id, car, road, oriented_curve, num_future_info=0):
        super().__init__(car, road)
        self.name = 'LaneDirectionSensor'
        self.oriented_curve = oriented_curve
        self.num_future_info = num_future_info
        self.win = 5
        self.relative_pos = 1 # relative position from car to road, 1 for right of lane, -1 for left
        self.measure()

    def measure(self):
        lane_dir, indx, cross = self.measure_lane_direction()

        # update the relative position between car and lane
        if cross > 0:
            self.relative_pos = -1 # car on left indicator
        else:
            self.relative_pos = 1 # car on right indicator

        angle_diff = self.measure_angle_diff()

        self.measurement = [angle_diff]

        if self.num_future_info > 0:
            self.measurement.extend(self.add_future_info(indx))

        return self.measurement

    def measure_lane_direction(self):
        car_center = np.array(self.car.center)[np.newaxis, :]
        mask = pygame.surfarray.array2d(self.road.center_lane)
        distances = sp.distance.cdist(car_center, self.oriented_curve).squeeze(0)
        indx = distances.argmin()

        p1 = self.oriented_curve[wrap(self.oriented_curve, indx, -self.win)]
        p2 = self.oriented_curve[wrap(self.oriented_curve, indx, self.win)]

        self.p1 = p1
        self.p2 = p2

        pos1 = to_screen_coords(p1)
        pos2 = to_screen_coords(p2)
        road_dir_angle = vec2angle(pos2 - pos1)

        center2car = to_screen_coords(car_center.squeeze()) - to_screen_coords(self.oriented_curve[indx])
        road_vec = pos2 - pos1
        # compute cross product of road vec and center2car vec
        cross = road_vec[0]*center2car[1] - center2car[0]*road_vec[1]

        return road_dir_angle, indx, cross

    def measure_angle_diff(self):
        car_theta_rads = self.car.theta
        car_vec = np.array([math.cos(car_theta_rads), math.sin(car_theta_rads)])
        import copy
        p1, p2 = copy.deepcopy(self.p1), copy.deepcopy(self.p2)
        p2[1] = SCREEN_HEIGHT - p2[1]
        p1[1] = SCREEN_HEIGHT - p1[1]
        road_vec = np.array(p2 - p1)

        # compute angle difference between two vectors
        u1 = car_vec / np.linalg.norm(car_vec)
        u2 = road_vec / np.linalg.norm(road_vec)
        angle_diff = np.arccos(np.dot(u1, u2)) # in radians

        # compute the signed angle difference
        cross = u1[0]*u2[1] - u1[1]*u2[0] # u1 cross u2
        if cross < 0:
            angle_diff *= -1

        return angle_diff

    def add_future_info(self, indx):
        future_dir_angle = [] # in car frame

        # car vector
        car_theta_rads = self.car.theta
        car_vec = np.array([math.cos(car_theta_rads), math.sin(car_theta_rads)])
        # car vector normal direction vector
        u1 = car_vec / np.linalg.norm(car_vec)
        # Append the future lane curvature information
        for i in range(self.num_future_info):
            p1 = self.oriented_curve[wrap(self.oriented_curve, indx+i*5+1, -self.win)]
            p2 = self.oriented_curve[wrap(self.oriented_curve, indx+i*5+1, self.win)]
            pos1 = to_screen_coords(p1)
            pos2 = to_screen_coords(p2)
            # road vector
            road_vec_tmp = np.array(pos2 - pos1)
            # compute angle difference between two vectors
            u2 = road_vec_tmp / np.linalg.norm(road_vec_tmp)
            angle_diff_tmp = np.arccos(np.dot(u1, u2)) # in radians
            # compute the signed angle difference
            cross = u1[0]*u2[1] - u1[1]*u2[0] # u1 cross u2
            if cross < 0: # negative means road dir on the right half plane (clockwise)
                angle_diff_tmp *= -1

            future_dir_angle.append(angle_diff_tmp)

        return future_dir_angle

    def blit(self, screen):
        pygame.draw.circle(screen, BLACK, tuple(self.p1), 2)
        pygame.draw.circle(screen, RED, tuple(self.p2), 2)

    @property
    def text(self):
        angle_diff = self.measurement[0]

        side = "left" if self.relative_pos < 0 else "right"
        return f"angle_diff: {angle_diff:.2f}, side: {side}"

# ==============================================
# Sensor for computing lane curvature
# ==============================================
class LaneCurvatureSensor(Sensor):
    def __init__(self, _id, car, road):
        super(LaneCurvatureSensor, self).__init__(car, road)
        self.name = 'LaneCurvatureSensor' + str(_id)
        self.measure()

    def measure(self):
        car_center = np.array(self.car.center)[np.newaxis, :]

        mask = pygame.surfarray.array2d(self.road.center_lane)
        coords = np.array(mask.nonzero()).transpose()

        import scipy.spatial as sp

        distances = sp.distance.cdist(car_center, coords).squeeze(0)

        closest_point = coords[distances.argmin()]
        x, y = closest_point

        win_size = 50

        # Take a region around the closest point
        window = mask[x-win_size:x+win_size, y-win_size:y+win_size]

        from itertools import product
        prod = np.array(list(product(range(x-win_size,x+win_size), range(y-win_size,y+win_size))))
        coords = prod[window.flatten().nonzero()]
        self.coords = coords

        # ==============================================
        # Some code to compute lane curvature
        # ==============================================

        dx_dt = np.gradient(coords[:, 0])
        dy_dt = np.gradient(coords[:, 1])
        velocity = np.stack((dx_dt, dy_dt),axis=1)

        ds_dt = np.sqrt(dx_dt**2 + dy_dt**2)
        tangent = np.array([1/ds_dt] * 2).transpose() * velocity

        tangent_x = tangent[:, 0]
        tangent_y = tangent[:, 1]

        deriv_tangent_x = np.gradient(tangent_x)
        deriv_tangent_y = np.gradient(tangent_y)

        dT_dt = np.stack((deriv_tangent_x, deriv_tangent_y),axis=1)

        length_dT_dt = np.sqrt(deriv_tangent_x ** 2 + deriv_tangent_y **2)

        normal = np.array([1/length_dT_dt] * 2).transpose() * dT_dt

        d2s_dt2 = np.gradient(ds_dt)
        d2x_dt2 = np.gradient(dx_dt)
        d2y_dt2 = np.gradient(dy_dt)

        # use formula for curvature: |x'' y' - x'y''| / (x'^2 + y'^2) ^(3/2)
        curvature = np.abs(d2x_dt2 * dy_dt - dx_dt * d2y_dt2) / (dx_dt * dx_dt + dy_dt * dy_dt)**(3/2)

        t_component = np.array([d2s_dt2] * 2).transpose()
        n_component = np.array([curvature * ds_dt * ds_dt] * 2).transpose()

        acceleration = t_component * tangent + n_component * normal

        self.measurement = curvature[int(len(curvature) / 2)]
        return self.measurement

    def blit(self, screen):
        for point in self.coords:
            pygame.draw.circle(screen, ORANGE, tuple(point), 2)

# ==============================================
# Sensor ray trace distance to edge of the road
# ==============================================
class RangeSensor(Sensor):
    def __init__(self, _id, car, road, deg):
        super(RangeSensor, self).__init__(car, road)
        self.deg = deg
        self.name = 'RangeSensor' + str(_id)
        self.measure()

    def measure(self):
        car_center = self.car.center

        length = 0
        for i in range(1500):
            self.deg_x = car_center[0] + math.cos(math.radians(self.deg + self.car.theta_degrees)) * length
            self.deg_y = car_center[1] - math.sin(math.radians(self.deg + self.car.theta_degrees)) * length

            line_surface = pygame.Surface((2, 2), pygame.SRCALPHA)
            line_rect = line_surface.get_rect()
            line_rect.topleft = self.deg_x, self.deg_y
            line_surface.fill((255,0,0))
            if self.road.field_mask.overlap(pygame.mask.from_surface(line_surface),
                                             (int(line_rect[0]), int(line_rect[1]))) is not None:
                self.measurement = length
                break
            length += 1

    def blit(self, screen):
        area_clear = 200
        if self.measurement > area_clear:
            red = 0
            green = 255
        else:
            ratio = self.measurement / area_clear
            value = 510 * ratio
            if value <= 255:
                red = 255
                green = value
            else:
                red = 255 - (value - 255)
                green = 255

        pygame.draw.line(screen, (int(red), int(green), 0), tuple(self.car.center), (self.deg_x, self.deg_y), 2)

class Sensors:
    def __init__(self, car, road, state_sources=['lane_direction', 'center_lane'], num_future_info=0):
        self.car = car
        self.road = road
        self.state_sources = state_sources
        self._sensors = []
        self.num_range_sensors = 0
        self.range_sensors = []
        range_sensor = list(filter(lambda x: bool(re.match('range_.*', x)), self.state_sources))

        oriented_curve = self.contour_tracing()

        if range_sensor:
            self.num_range_sensors = int(range_sensor[0].split('_')[-1])

            self.density = ANGLE_BETWEEN_SENSORS
            self.range_sensors = self.init_range_sensors()
            self._sensors.extend(self.range_sensors)

        if 'center_lane' in self.state_sources:
            self.center_lane_sensor = CenterLaneSensor(0, self.car, self.road, oriented_curve, num_future_info)
            self._sensors.append(self.center_lane_sensor)

        if 'lane_curvature' in self.state_sources:
            self.lane_curvature_sensor = LaneCurvatureSensor(0, self.car, self.road)
            self._sensors.append(self.lane_curvature_sensor)

        if 'lane_direction' in self.state_sources:
            self.lane_direction_sensor = LaneDirectionSensor(0, self.car, self.road, oriented_curve, num_future_info)
            self._sensors.append(self.lane_direction_sensor)

    def __len__(self):
        return len(self.range_sensors)

    def contour_tracing(self):
        b = []
        self.mask = pygame.surfarray.array2d(self.road.center_lane)
        starting_pixel = list(zip(*np.where(self.mask != 0)))
        b_x = starting_pixel[0][0]
        b_y = starting_pixel[0][1]
        b.append(starting_pixel[0])

        b_x = starting_pixel[0][0]
        b_y = starting_pixel[0][1]-1

        d_x = b_x - b_x
        d_y = b_y - b_y

        neighbors = [(0,0),(0,-1),(-1,-1),(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1)]
        count = 1
        # contour = np.zeros((*img.shape, 3))
        while count <= 2:
            tmp = 0
            for i in range(9):
                if d_x == neighbors[i][0] and d_y == neighbors[i][1]:
                    tmp = i
                    break

            while True:
                if(tmp == 8):
                    tmp = 0

                c_x = b_x + neighbors[tmp+1][0]
                c_y = b_y + neighbors[tmp+1][1]
                if (self.mask[c_x][c_y]!=0):
                    b_x = c_x
                    b_y = c_y
                    temp = (b_x,b_y)

                    if (temp in b)==True:
                        count += 1
                    b.append((b_x,b_y))
                    d_x = prev_x-b_x
                    d_y = prev_y-b_y
                    break

                prev_x = c_x
                prev_y = c_y
                tmp += 1
        return np.array(b)
        # for pixel in range(len(B)):
        #       contour[B[pixel][0]][B[pixel][1]] = [0,255,0]

    @property
    def sensors(self):
        return self._sensors

    def init_range_sensors(self):
        sensors = []
        angle_range = (self.num_range_sensors - 1) * self.density
        start_angle = -angle_range // 2

        for i, deg in enumerate(range(start_angle + angle_range, start_angle - 1, -self.density)):
            sensors.append(RangeSensor(i, self.car, self.road, deg))
        return sensors

    def blit(self, screen):
        for sensor in self.sensors:
            sensor.measure()
            sensor.blit(screen)

# ==============================================
# Road Class
# ==============================================
class Road:
    def __init__(self,
        road_file,
        center_lane_file,
        textures,
        texture_files,
        texture_frictions,
        use_textures=False
    ):
        self.img = pygame.image.load(road_file)
        self.img = pygame.transform.smoothscale(self.img, (SCREEN_WIDTH, SCREEN_HEIGHT))
        self.field_mask = pygame.mask.from_threshold(self.img, self.img.get_at((0,0)), (2, 2, 2, 255))
        self.img_rect = self.img.get_rect()

        # ==============================================
        # Load in different textures for the road
        # ==============================================
        self.texture_map = {}
        self.use_textures = use_textures

        if self.use_textures:
            for i, file in enumerate(texture_files):
                texture = pygame.image.load(file)
                texture = pygame.transform.smoothscale(texture, (SCREEN_WIDTH, SCREEN_HEIGHT))
                texture_mask = pygame.mask.from_surface(texture)

                self.texture_map[textures[i]] = dict(
                    texture=texture,
                    mask=texture_mask,
                    friction_level=texture_frictions[i]
                )

        # ==============================================
        # Load center lane
        # ==============================================
        self.center_lane = pygame.image.load(center_lane_file)
        self.center_lane_mask = pygame.mask.from_surface(self.center_lane)

    def blit(self, screen):
        screen.blit(self.center_lane, (0, 0))

        # Render track first
        screen.blit(self.img, (0, 0))

        # Render textures on top
        for texture, dic in self.texture_map.items():
            screen.blit(dic['texture'], (0, 0))


import csv

class Data:
    def __init__(self):
        self.data = {}
        with open('./data.csv', encoding="utf8") as f:
            csv_reader = csv.reader(f)
            for line_no, line in enumerate(csv_reader, 1):
                if line_no > 1:
                    self.data[line[0]] = line[1]
    def get_item(self, key):
        return self.data.get(key)


import sys
sys.dont_write_bytecode = True

import logging
logger = logging.getLogger(__name__)

import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

class Resources:
    from . import Apstra

    def __init__(self, main_class: Apstra):
        self.apstra = main_class
        self.parameters = main_class.parameters

        from apstra.resources_ipv4 import ResourcesIPv4Pool
        self.ipv4_pools = ResourcesIPv4Pool(self.apstra)
        from apstra.resources_vni import ResourcesVniPool
        self.vni_pools = ResourcesVniPool(self.apstra)
        from apstra.resources_asn import ResourcesAsnPool
        self.asn_pools = ResourcesAsnPool(self.apstra)

    def apply_resource_groups(self, bp_id: str, resource_type: str, group_name: str, pool_ids: list):
        uri = f"/api/blueprints/{bp_id}/resource_groups/{resource_type}/{group_name}"
        data = {"pool_ids": pool_ids}

        rg = self.apstra.rest.put_json_response(uri, data=data)
        return rg

class Range:
    def __init__(self, first=None, last=None):
        self.first = first
        self.last = last
        self.ranges = []

    def add_range(self, start, end):
        if start <= end:
            self.ranges.append(Range(start, end))
        else:
            raise ValueError("Invalid range")

    def get_non_overlapping_ranges(self) -> list:
        sorted_ranges = sorted(self.ranges, key=lambda r: r.first)
        non_overlapping_ranges = []
        i = 0
        while i < len(sorted_ranges):
            j = i + 1
            while j < len(sorted_ranges) and sorted_ranges[j].first <= sorted_ranges[i].last:
                if sorted_ranges[j].last > sorted_ranges[i].last:
                    sorted_ranges[i].last = sorted_ranges[j].last
                j += 1
            r = {"first": sorted_ranges[i].first, "last":sorted_ranges[i].last}
            non_overlapping_ranges.append(r)
            i = j
        return non_overlapping_ranges

    def __repr__(self):
        return str({"first": self.first, "last": self.last})

    def __str__(self):
        return str({"first": self.first, "last": self.last})


#FUNTIONAL

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0,5,11)
y = x**2

plt.plot(x,y)
plt.xlabel('X lable')
plt.ylabel('Y lable')
plt.title('Test')

#add multi plots
plt.subplot(1,2,1)
plt.plot(x,y,'r')
plt.plot(y,x,'b')

#OBJET ORIENTED
fig = plt.figure()
axes = fig.add_axes([0.1,0.1,0.8,0.8])
axes.plot(x,y,'r')
axes.set_xlabel('X Lable')
axes.set_ylabel('Y Lable')
axes.set_title('Test')

#add multitple plots
fig = plt.figure()
axes1 = fig.add_axes([0.1,0.1,0.8,0.8])
axes2 = fig.add_axes([0.2,0.5,0.4,0.3])
axes1.plot(x,y)
axes2.plot(y,x)
fig,axes = plt.subplots(nrows=1,ncols=2)
axes[0].plot(x,y)
axes[1].plot(y,x)

# Figures size and the DPI

fig,axes = plt.subplots(nrows=2,ncols=1,figsize=(8,2),dpi=200)
axes[0].plot(x,y)
axes[1].plot(y,x)

# Legend
fig2 = plt.figure()
ax = fig2.add_axes([0,0,1,1])
ax.plot(x,x**2,label='X Square')
ax.plot(x,x**3,label='X Cube')
ax.legend()
plt.tight_layout()
plt.show()

# Appearnce and colours in the plot
fig3 = plt.figure()
ax3 = fig3.add_axes([0,0,1,1])
ax3.plot(x,y,color='#ff8c00',linewidth=3,marker='o',markersize=20,
markerfacecolor='yellow',markeredgewidth=3,markeredgecolor='black')
plt.show()

# axis customization
fig4 = plt.figure()
ax4 = fig4.add_axes([0,0,1,1])
ax4 = fig4.add_subplot(111)
ax4.plot(x,y,color='purple',linewidth=2,linestyle='--')
ax4.set_xlim([0,1])
ax4.set_ylim([0,1])
plt.show()

#special plot types.


import requests
import os
from pywikiapi import wikipedia
list_of_languages = ['ady', 'an', 'ast', 'av', 'az', 'ba', 'bar', 'be', 'bg', 'br', 'bs', 'ca', 'ce', 'co', 'crh', 'cs',
                     'csb', 'cv', 'cy', 'da', 'de', 'el', 'en', 'es', 'et', 'eu', 'ext', 'fi', 'fo', 'fr', 'frp', 'fur',
                     'ga', 'gag', 'gd', 'gl', 'hr', 'hu', 'inh', 'is', 'it', 'kbd', 'kk', 'krc', 'ksh', 'kv', 'la',
                     'lad', 'lb', 'li', 'lij', 'lmo', 'lt', 'lv', 'mdf', 'mk', 'mt', 'mwl', 'myv', 'nap', 'nds', 'nl',
                     'no', 'oc', 'os', 'pcd', 'pl', 'pt', 'ro', 'ru', 'sc', 'scn', 'sco', 'se',
                     'sk', 'sl', 'sq', 'sr', 'sv', 'szl', 'tr', 'tt', 'udm', 'uk', 'vec', 'wa', 'xal', 'yi']
def scrap():
    path = "Dataset"
    try:
        for i in list_of_languages:
            os.makedirs('Dataset/' + i)
    except OSError:
        print("Creation of the directories %s failed" % path)
    else:
        print("Successfully created the directories %s" % path)

    for i in list_of_languages:
        print('Robię język ' + i)
        site = wikipedia(i)
        for j in range(100):
            for r in site.query(generator='random', grnnamespace=0, grnlimit = 1, prop=['extracts'], explaintext = 1):
                for page in r.pages:
                    title = page.title
                    title = "".join(x for x in title if x.isalnum())
                    file = open('Dataset/' + i + '/' + title + '.txt', "w", encoding="utf-8")
                    file.write(page.extract)
                break


import unittest
import ProcessResult
from collections import defaultdict

class us0809_test(unittest.TestCase):
    indi_i1 = defaultdict(str)
    indi_i1['BIRT'] = '1988-08-28'
    indi_i1['FAMC'] = 'F1'
    indi_i2 = defaultdict(str)
    indi_i2['BIRT'] = '2020-06-24'
    indi_i2['FAMC'] = 'F2'
    i2_dad = defaultdict(str)
    i2_dad['DEAT'] = '1995-02-10'

    indi_dict = defaultdict(defaultdict)
    indi_dict['I1'] = indi_i1
    indi_dict['I2'] = indi_i2
    indi_dict['I3'] = i2_dad

    fam_f1 = defaultdict(str)
    fam_f1['MARR'] = '2020-09-08'
    fam_dict = defaultdict(defaultdict)
    fam_dict['F1'] = fam_f1
    fam_f2 = defaultdict(str)
    fam_f2['HUSB'] = 'I3'
    fam_f2['WIFE'] = 'I1'
    fam_dict['F2'] = fam_f2

    def test_08_false_case(self):
        self.assertEqual(ProcessResult.birth_before_marriage_of_parents('I1', self.indi_dict, self.fam_dict),
                         'ERROR: INDIVIDUAL: US08: I1: Birth date 1988-08-28 is before marriage date of their parents 2020-09-08!')

    def test_09_false_case(self):
        self.assertEqual(ProcessResult.birth_before_death_of_parents('I2', self.indi_dict, self.fam_dict),
                         'ERROR: INDIVIDUAL: US09: I2: Birth date 2020-06-24 is after death date of his/her parents 1995-02-10!')

if __name__ == '__main__':
    unittest.main(exit=False, verbosity=2)


import requests
import datetime
from mcmodbrowser.index import *
from mcmodbrowser.util import *
from mcmodbrowser.model.curse import *

def run(args=[]):
    '''Fetch recently updated mods and put them in the index.'''

    requestLimit = int(args[args.index("--request-limit") + 1]) if "--request-limit" in args else -1

    curseToken = getCurseToken()

    index = loadJson("data/index.json")

    interruptSearch = False

    print("Fetching mods since", datetime.datetime.utcfromtimestamp(index['cursors']['curse']).isoformat(), "(", index['cursors']['curse'], ")")

    firstModModificationDate = None
    fetched = 0
    requestCount = 0
    fetchedExtra = 0

    for searchIndex in range(0, 10000, 50):
        if interruptSearch:
            break

        resp = requests.get("https://api.curseforge.com/v1/mods/search?gameId=432&sortField=3&sortOrder=desc&pageSize=50&index={}".format(searchIndex), headers = getCurseHeaders(curseToken))
        requestCount += 1

        if requestLimit != -1 and requestCount > requestLimit:
            print("Reached request limit, aborting")
            break

        if resp.status_code == 200:
            assert "data" in resp.json()

            first = True
            for mod in resp.json()["data"]:
                lastModified = getCurseModLastModifiedTimestamp(mod)

                if first:
                    print("Search index:", searchIndex, "First mod:", datetime.datetime.utcfromtimestamp(lastModified).isoformat())

                print("  updating:", mod['slug'])

                if lastModified < index['cursors']['curse']:
                    # Fetch some redundant entries to cope with unreliable API
                    if fetchedExtra == 0:
                        print("Older than cursor, fetching 30 more")
                    fetchedExtra += 1
                    if fetchedExtra > 30:
                        print("Fetched 30 extra entries, aborting")
                        interruptSearch = True
                        break

                if writeCurseModToIndex(index, mod):
                    fetched += 1

                if firstModModificationDate == None:
                    firstModModificationDate = lastModified

                first = False
        else:
            print("ERROR: got status code", resp.status_code)
            break

    if firstModModificationDate:
        index['cursors']['curse'] = firstModModificationDate

    index['lastModified'] = epochNow()

    print("Updated", fetched, "mods")

    print("Writing index...")

    writeJson(index, "data/index.json")


import os
import pickle
from abc import ABC, abstractmethod

from exceptions import exceptions

class DAO(ABC):
    __instance = None

    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            cls.__instance = super().__new__(cls)
        return cls.__instance

    @abstractmethod
    def __init__(self, datasource=''):
        self.__datasource = datasource
        self.__cache = {}
        self.__last_index = self.__load_last_index()
        try:
            self.__load()
        except FileNotFoundError:
            self.__dump()

    def __dump(self):
        with open(self.__datasource, 'wb') as file:
            pickle.dump((self.__cache, self.__last_index), file)

    def __load(self):
        with open(self.__datasource, 'rb') as file:
            self.__cache, self.__last_index = pickle.load(file)

    def __load_last_index(self):
        if os.path.exists(self.__datasource):
            with open(self.__datasource, 'rb') as file:
                try:
                    _, last_index = pickle.load(file)
                    return last_index
                except (pickle.UnpicklingError, IndexError):
                    pass
        return -1

    def add(self, key, obj):
        self.__cache[key] = obj
        self.__last_index += 1
        self.__dump()

    def update(self, key, obj):
        if key in self.__cache:
            self.__cache[key] = obj
            self.__dump()
        else:
            raise exceptions.NaoEncontradoException("Key não encontrada")

    def get(self, key):
        if key in self.__cache:
            return self.__cache[key]
        raise exceptions.NaoEncontradoException("Key não encontrada")

    def remove(self, key):
        if key not in self.__cache:
            raise exceptions.NaoEncontradoException("Key não encontrada")
        self.__cache.pop(key)
        self.__dump()

    def get_all(self):
        return list(self.__cache.values())

    def get_next_index(self):
        return self.__last_index + 1

    def clear_file(self):
        self.__cache = {}
        self.__last_index = -1
        self.__dump()


from collections import defaultdict
import itertools
import types

def parse(inp):
    if inp.strip() == '':
        return []
    return [int(i) for i in inp.strip().split(',')]

def runner(opcodes, inp=None):
    if isinstance(inp, list):
        inputs = (x for x in inp)
    elif isinstance(inp, int):
        inputs = itertools.repeat(inp)
    elif isinstance(inp, types.GeneratorType):
        inputs = inp

    opcodes = defaultdict(
        int, {i: int(v) for i, v in enumerate(opcodes)})

    def get_parameter(i, mode):
        if mode == 1:
            return opcodes[i]
        elif mode == 2:
            return opcodes[base+opcodes[i]]
        return opcodes[opcodes[i]]

    def write_parameter(i, mode, value):
        target = opcodes[i]
        if mode == 2:
            target += base
        opcodes[target] = value

    i = 0
    base = 0
    jumps = {1: 4, 2: 4, 3: 2, 4: 2, 5: 3, 6: 3, 7: 4, 8: 4, 9: 2}
    while True:
        opcode = opcodes[i] % 100
        modes = [int(p)
                 for p in reversed(str(opcodes[i] // 100).rjust(4, '0'))]
        a = get_parameter(i+1, modes[0])
        b = get_parameter(i+2, modes[1])

        if opcode == 1:
            write_parameter(i+3, modes[2], a+b)
        elif opcode == 2:
            write_parameter(i+3, modes[2], a*b)
        elif opcode == 3:
            if inp == None:
                a = yield 'inp'
            else:
                a = next(inputs)
            write_parameter(i+1, modes[0], a)
        elif opcode == 4:
            yield a
        elif opcode == 5:
            if a != 0:
                i = b
                continue
        elif opcode == 6:
            if a == 0:
                i = b
                continue
        elif opcode == 7:
            if a < b:
                write_parameter(i+3, modes[2], 1)
            else:
                write_parameter(i+3, modes[2], 0)
        elif opcode == 8:
            if a == b:
                write_parameter(i+3, modes[2], 1)
            else:
                write_parameter(i+3, modes[2], 0)
        elif opcode == 9:
            base += a
        elif opcode == 99:
            return

        i += jumps[opcode]


import json, os

data_dict = {}
data = None
filename = "data/data.json"

class Struct:
    def __init__(self, **entries):
        self.__dict__.update(entries)

def update(save=False):
    global data

    data = Struct(**data_dict)

    if save:
        with open(filename, "w") as f:
            json.dump(data_dict, f, indent=2)

def load(first_run):
    global data_dict

    if os.path.exists(filename):
        with open(filename, "r") as f:
            data_dict = json.load(f)

        update()
    else:
        os.makedirs(os.path.dirname(filename), exist_ok=True)

        data_dict = {}
        data_dict["min_problem_rating"] = 800
        data_dict["max_problem_rating"] = 3500
        data_dict["sorted_by_difficulty"] = True
        data_dict["handles"] = []

        update()

        first_run()


'''
Author: Tingjun Li
Create Time: 2017-04-10
Function: Find and show book details
'''
from django.http import JsonResponse
from django.core import serializers, exceptions
import json
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from book.models import Book, Tag, Category
from apitools.decorators import accept_methods,have_perms
from django.db.models import QuerySet

def wrap_book_list_item(book):
    try:
        resp_item={}
        resp_item['bookid']=book.bookid
        resp_item["title"]=book.title
        resp_item["author"]=book.author
        resp_item["translator"]=book.translator
        resp_item["isbn"]=book.isbn
        resp_item["pubhouse"]=book.pubhouse
        resp_item["pubtime"]=book.pubtime
        resp_item["cover"]=book.cover
        resp_item["clc"]=book.clc
        resp_item["edition"]=book.edition
        return resp_item
    except:
        return None

# List book
@csrf_exempt
@accept_methods(['post'])
def book_query_list(request):
    response_data = {}
    response_data['result'] = 'error'
    try:
        req = json.loads(request.body.decode('utf-8'))
        req = req[0]
        resp_booklist = []

        start_filter = False

        booklist = QuerySet(model=Book)

        if len(req['title'])>0:
            booklist = Book.objects.filter(title__contains=req['title'])
            start_filter = True

        if len(req['isbn'])>0:
            if start_filter:
                booklist = booklist.filter(isbn__contains=req['isbn'])
            else:
                booklist = Book.objects.filter(isbn__contains=req['isbn'])
                start_filter = True

        if len(req['clc'])>0:
            if start_filter:
                booklist = booklist.filter(clc__contains=req['clc'])
            else:
                booklist = Book.objects.filter(clc__contains=req['clc'])
                start_filter = True

        if len(req['author'])>0:
            if start_filter:
                booklist = booklist.filter(author__contains=req['author'])
            else:
                booklist = Book.objects.filter(author__contains=req['author'])
                start_filter = True

        if len(req['translator'])>0:
            if start_filter:
                booklist = booklist.filter(translator__contains=req['translator'])
            else:
                booklist = Book.objects.filter(translator__contains=req['translator'])
                start_filter = True

        if len(req['pubhouse'])>0:
            if start_filter:
                booklist = booklist.filter(pubhouse__contains=req['pubhouse'])
            else:
                booklist = Book.objects.filter(pubhouse__contains=req['pubhouse'])
                start_filter = True

        if start_filter:
            for i in booklist:
                resp_booklist.append(wrap_book_list_item(i))
            response_data['result'] = 'ok'
            response_data['data']=resp_booklist

    except:
        response_data['result'] = 'error'
        response_data['message'] = 'Cant query book'

    return JsonResponse(response_data)

# Show book details
@csrf_exempt
@accept_methods(['get'])
def book_detail(request, bid):
    response_data = {}
    response_data['result'] = 'error'
    try:
        book_item = Book.objects.get(bookid=int(bid))

        resp_book = {}
        resp_book['isbn'] = book_item.isbn
        resp_book['title'] = book_item.title
        resp_book['author'] = book_item.author
        resp_book['translator'] = book_item.translator
        resp_book['edition'] = book_item.edition
        resp_book['pubhouse'] = book_item.pubhouse
        resp_book['pubtime'] = book_item.pubtime
        resp_book['summary'] = book_item.summary
        resp_book['context'] = book_item.context
        resp_book['clc'] = book_item.clc
        resp_book['price'] = book_item.price
        resp_book['category'] = []
        resp_book['tag'] = []

        # print(len(book_item.category.all()))

        for i in book_item.category.all():
            item = {}
            item['id'] = i.id
            item['text'] = i.text
            resp_book['category'].append(item)

        for i in book_item.tag.all():
            item = {}
            item['id'] = i.id
            item['text'] = i.text
            resp_book['tag'].append(item)

        response_data['result'] = 'ok'

        response_data['data'] = resp_book
    except:
        response_data['result'] = 'error'
        response_data['message'] = 'Book not found'

    return JsonResponse(response_data)

# Show lib book details


class Processes:
    # Process Name, Arrival Time, Burst Time, Priority
    Process_List = []
    # Process Name, Arrival Time, Finish Time, Waiting Time
    FCFS_List = []
    waiting_time = 0

    def addProcess(self, Name, Arrival_Time, Burst_Time, Priority):
        self.Process_List.append(
            {"task": Name, "arrival_time": Arrival_Time, "burst_time": Burst_Time, "priority": Priority})

    def FCFS(self):
        # Sort According to the Arrival Time
        self.Process_List.sort(key=lambda x: x["arrival_time"])
        # Implementation of FCFS List
        for i in range(len(self.Process_List)):
            # The First Process will have 0 Waiting Time
            if i == 0:
                self.FCFS_List.append(
                    {"Task": self.Process_List[0]["task"], "Start": self.Process_List[0]["arrival_time"],
                     "Finish": (self.Process_List[0]["burst_time"] + self.Process_List[0]["arrival_time"])})
            else:
                self.FCFS_List.append(
                    {"Task": self.Process_List[i]["task"], "Start": self.FCFS_List[i - 1]["Finish"],
                     "Finish": self.Process_List[i]["burst_time"] + self.FCFS_List[i - 1]
                     ["Finish"]})

                self.waiting_time += self.FCFS_List[i - 1]["Finish"] - self.Process_List[i]["arrival_time"]

        self.waiting_time /= len(self.Process_List)
        return self.FCFS_List, self.waiting_time

def FCFS(process):
    FCFS_List = []
    waiting_time=0
    # Sort According to the Arrival Time
    process.sort(key=lambda x: x["arrival_time"])
    # Implementation of FCFS List
    for i in range(len(process)):
        # The First Process will have 0 Waiting Time
        if i == 0:
            FCFS_List.append(
                {"Task": process[0]["task"], "Start": process[0]["arrival_time"],
                 "Finish": (process[0]["burst_time"] + process[0]["arrival_time"])})
        else:
            gstart = max([FCFS_List[i - 1]["Finish"],process[i]['arrival_time']])
            FCFS_List.append(
                {"Task": process[i]["task"], "Start": gstart,"Finish": process[i]["burst_time"] + gstart})

            #waiting_time += FCFS_List[i - 1]["Finish"] - process[i]["arrival_time"]
            waiting_time += FCFS_List[i]["Start"] - process[i]["arrival_time"]

    waiting_time /= len(process)
    #if waiting_time<0:
    #    waiting_time = 0
    return FCFS_List, waiting_time


def imc_or_basal():
    escolha = input("Você quer calcular IMC ou BASAL?")

    if escolha.upper == "IMC" or "imc":
        calcular_imc()
    else:
        calculadora_basal()

def calcular_imc():
    name = input("Olá meu nobre internalta, qual o seu nome? ")
    print(f"Então vamos lá {name}! ")
    peso = int(input(f"{name} qual o seu peso? "))
    altura = int(input(f"Já temos o seu peso {name}, agora só falta sua altura. qual a sua altura? "))

    altura_imc = altura * altura

    imc = peso / altura_imc

    print(f"Seu IMC é {imc}")

def calculadora_basal():
    name = input("Olá meu nobre internalta, qual o seu nome? ")
    print(f"Então vamos lá {name}! ")
    idade = int(input(f"Qual a sua idade {name}? "))
    peso = int(input(f"{name} qual o seu peso? "))
    altura = int(input(f"Já temos sua idade e seu peso {name}, agora só falta sua altura. qual a sua altura? "))

    basalpeso = 13.7 * peso
    basalaltura = 5 * altura
    basalidade = 6.8 * idade

    basal = 66 + basalpeso + basalaltura - basalidade

    print(f"Seu basal é {basal}")
    print(f"Seu corpo consome {basal} calorias diariamente só para se manter")

def recalcular():
    while True:
        print("Você quer calcular seu Basal novamente? ")
        recal = input("Aperte Y para sim e N para não! ")
        if recal.upper() == "Y":
             calculadora_basal()
        else:
             print("até mais!")
             break

imc_or_basal()


import os
import smtplib
from email.message import EmailMessage
from string import Template
from pathlib import Path
from dotenv import load_dotenv

load_dotenv()

html = Path('index.html').read_text()
htmlTemplate = Template(html)

email = EmailMessage()
email['from'] = 'ThomasCode92'
email['to'] = os.environ['EMAIL_SENDER']
email['subject'] = 'Hi Developer'

email.set_content(htmlTemplate.substitute({'name': 'TinTin'}), 'html')

with smtplib.SMTP(host='smtp.gmail.com', port=587) as smtp:
    smtp.ehlo()
    smtp.starttls()
    smtp.login(os.environ['EMAIL_ADDRESS'], os.environ['EMAIL_PASSWORD'])
    smtp.send_message(email)
    print('all good boss!')


#!/usr/bin/python

import cv2
import numpy as np
import math
import serial
import time

log = open('camlog.txt','a')
log.write("\n\n\nStart at "+time.strftime("%d-%m-%Y, %H:%M:%S")+"\n\n")

ser = serial.Serial('/dev/ttyS0', 9600, timeout=0)
ser.flushInput()

#-----------------------CALIBRATION--------------------------#
# White area detection
WIDTH=0
HEIGHT=0
HMIN=0
HMAX=0
TMIN=0
TMAX=0

# Define view areas
LOWER_VIEW = 0
GAP = 0
ALFA = 0.0
ALFA_RADS = 0.0

CENTER_VIEW = 0
LEFT_VIEW = 0
RIGHT_VIEW = 0
#------------------------------------------------------------#

def settings():
	#get calibration constants as "320,240,000,240,100,200,050,020,070,080,080,0,." (len=47)
	c = "";
	while 1:
		c = ser.read(47)
		cal = c.split(',')
		if cal[-1] == ".":
			WIDTH=int(cal[0])
			HEIGHT=int(cal[1])
			HMIN=int(cal[2])
			HMAX=int(cal[3])
			TMIN=int(cal[4])
			TMAX=int(cal[5])
			LOWER_VIEW=int(cal[6])
			GAP=int(cal[7])
			ALFA=float(cal[8])
			ALFA_RADS=float(1.0*ALFA/180*math.pi)
			CENTER_VIEW=WIDTH/2
			LEFT_VIEW=int(cal[9])
			RIGHT_VIEW=int(cal[10])
			IMGSAVE=int(cal[11])
			log.write(time.strftime("%d-%m-%Y, %H:%M:%S")+"Configuration: "+c)
			cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH,WIDTH)
			cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT,HEIGHT)
			break

def region(cx,cy):
	if ((cx == -1 or cy == -1) or (cx >= WIDTH - GAP - (cy/math.tan(ALFA)))):
		return "R"
	if (cy > LOWER_VIEW and cx < WIDTH - GAP - (cy/(math.tan(ALFA))) and cx > GAP + (cy/(math.tan(ALFA))) ):
		return "S"
	if (cx <= GAP + (cy/math.tan(ALFA))):
		return "L"
	return "F"

cap=cv2.VideoCapture(-1)

q=""
while 1:
	q = ser.read(1)
	if q == "S":
		break

	if q == "C":
		settings()

	if q == "Q":
		ret,frame = cap.read()
		if ret:
			cframe = frame[HMIN:HMAX, 1:WIDTH]
			gray = cv2.cvtColor(cframe, cv2.COLOR_BGR2GRAY)
			_,gray = cv2.threshold(gray,TMAX,TMIN,0)

			edges = cv2.Canny(gray,100,200)
			kernel = np.ones((5,5),np.float32)/10
			edges = cv2.filter2D(edges,-1,kernel)

			cnts,_ = cv2.findContours(edges.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
			cnts = sorted(cnts, key = cv2.contourArea, reverse = True)

			if len(cnts):
				cnt = cnts[0] #choose biggest contour
				M = cv2.moments(cnt)
				if M['m00']:
					cx = int(M['m10']/M['m00'])
					cy = int(M['m01']/M['m00'])
				else:
					log.write(time.strftime("%d-%m-%Y, %H:%M:%S")+"Error(1): cannot calculate centroid")
			else:
				cx = -1
				cy = -1
			R = region(cx,cy)
			log.write(time.strftime("%d-%m-%Y, %H:%M:%S")+"cx="+str(cx)+", cy="+str(cy)+", region="+str(R)+"\n")
			if IMGSAVE==1:
				cv2.imwrite("pic_"+str(time.time())+"_cframe.jpg",edges)
				cv2.imwrite("pic_"+str(time.time())+"_edges.jpg",edges)
			ser.write(str(R))
		else:
			log.write(time.strftime("%d-%m-%Y, %H:%M:%S")+"Error(0): Problem with reading")
		q = ""

ser.close()
cap.release();


from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.shortcuts import get_object_or_404, redirect, render
from django.views.decorators.cache import cache_page

from .forms import CommentForm, PostForm
from .models import Follow, Group, Post, User

@cache_page(20)
def index(request):
    post_list = Post.objects.all()
    paginator = Paginator(post_list, 10)
    page_number = request.GET.get('page')
    page = paginator.get_page(page_number)
    return render(request, 'index.html', {'page': page, })

def group_posts(request, slug):
    group = get_object_or_404(Group, slug=slug)
    group_list = group.posts.all()
    paginator = Paginator(group_list, 10)
    page_number = request.GET.get('page')
    page = paginator.get_page(page_number)
    return render(request, 'group.html',
                  {'page': page, 'group': group, 'posts': group_list})

def profile(request, username):
    author = get_object_or_404(User, username=username)
    user = request.user
    posts = Post.objects.filter(author=author)
    following = user.is_authenticated and (Follow.objects.filter(user=user,
                                           author=author).exists())
    paginator = Paginator(posts, 5)
    page_number = request.GET.get('page')
    page = paginator.get_page(page_number)
    return render(request, 'profile.html',
                  {'author': author, 'page': page, 'following': following})

def post_view(request, username, post_id):
    post = get_object_or_404(Post, author__username=username, pk=post_id)
    comments = post.comments.all()
    form = CommentForm()
    return render(request, 'post.html',
                  {'post': post, 'comments': comments, 'form': form})

@login_required
def new_post(request):
    form = PostForm(request.POST or None, files=request.FILES or None)
    if form.is_valid():
        post = form.save(commit=False)
        post.author = request.user
        post.save()
        return redirect('index')
    return render(request, 'new.html', {'form': form})

@login_required
def post_edit(request, username, post_id):
    post = get_object_or_404(Post, author__username=username, pk=post_id)
    form = PostForm(request.POST or None, files=request.FILES or None,
                    instance=post)
    if post.author != request.user:
        return redirect('post', username=username, post_id=post_id)
    if form.is_valid():
        post = form.save()
        return redirect('post', username=username, post_id=post_id)

    return render(request, 'new.html', {'form': form, 'post': post})

@login_required
def add_comment(request, username, post_id):
    post = get_object_or_404(Post, author__username=username, pk=post_id)
    form = CommentForm(request.POST or None)
    if form.is_valid():
        comment = form.save(commit=False)
        comment.author = request.user
        comment.post = post
        comment.save()
    return redirect('post', username=post.author.username, post_id=post_id)

@login_required
def follow_index(request):
    post_list = Post.objects.filter(author__following__user=request.user)
    paginator = Paginator(post_list, 10)
    page_number = request.GET.get('page')
    page = paginator.get_page(page_number)
    return render(request, 'follow.html',
                  {'page': page})

@login_required
def profile_follow(request, username):
    user = request.user
    author = get_object_or_404(User, username=username)
    if user.username != username:
        # такая запись не работает т.к. не хватает author_id
        # Follow.objects.get_or_create(user=user, author__username=username)
        Follow.objects.get_or_create(user=user, author=author)
    return redirect('profile', username=username)

@login_required
def profile_unfollow(request, username):
    user = request.user
    Follow.objects.filter(user=user, author__username=username).delete()
    return redirect('profile', username=username)

def page_not_found(request, exception):
    return render(
        request,
        'misc/404.html',
        {'path': request.path},
        status=404
    )

def server_error(request):
    return render(request, 'misc/500.html', status=500)


import os
import aiohttp
import discord
from dotenv import load_dotenv
from core import database
from core.checks import is_botAdmin
from discord.ext import commands
from core import redirect_sdk

load_dotenv()

class RedirectURL(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.domain = "rs.schoolsimplified.org"
        self.raOBJ = redirect_sdk.RedirectClient(
            os.getenv("RP_TK"), domain="https://rs.schoolsimplified.org"
        )

    @commands.command(alliases=["redirectadd", "addredirect"])
    @is_botAdmin
    async def ra(self, ctx, redirect_code, destination_url: str):
        val = self.raOBJ.add_redirect(redirect_code, destination_url)
        await ctx.send(
            f"Redirect added for {destination_url} with redirect path /{redirect_code}\nCreated with the ID: {val.id}. In order to delete this redirect, you'll need this ID!\n\nAccess it at https://rs.schoolsimplified.org/{redirect_code}"
        )

    @commands.command(alliases=["redirectremove", "removeredirect"])
    @is_botAdmin
    async def rr(self, ctx, ID):
        self.raOBJ.del_redirect(ID)
        await ctx.send(f"Redirect removed for {ID}")

    @commands.command(alliases=["redirectlist", "listredirect"])
    @is_botAdmin
    async def rl(self, ctx):
        objlist = self.raOBJ.get_redirects()
        newlist = []
        for obj in objlist:
            newlist.append(
                f"**ID:** {obj.id} | **URL:** `https://{obj.domain}/{obj.source}` -> `{obj.destination}`"
            )
        newlist = "\n".join(newlist)
        embed = discord.Embed(
            title=f"Redirects for {self.raOBJ.domain}", color=discord.Color.blue()
        )
        embed.add_field(name="Redirects", value=newlist)
        await ctx.send(embed=embed)

def setup(bot):
    bot.add_cog(RedirectURL(bot))


import sys,os
import ast
from abc import ABCMeta,abstractproperty,abstractmethod

from distutils import config

if sys.version_info.major>=3:
	import _pickle as pkl
	from configparser import NoOptionError
else:
	import cPickle as pkl
	from ConfigParser import NoOptionError

import json

import numpy as np
import astropy.units as u

###################################
#Select parser from file extension#
###################################

def select_parser(filename,read=True):

	if filename.endswith(".ini"):

		options = config.ConfigParser()
		if read:
			options.read([filename])
			options.filename = filename

		return options

	elif filename.endswith(".pkl") or filename.endswith(".p"):

		options = PickleParser()
		if read:
			with open(filename,"r") as fp:
				options._buffer = options.load(fp)
				options.filename = filename

		return options

	elif filename.endswith(".json"):

		options = JSONParser()
		if read:
			with open(filename,"r") as fp:
				options._buffer = options.load(fp)
				options.filename = filename

		return options

	else:
		raise NotImplementedError("Config file type not supported!")

############################
#Generic LensTools settings#
############################

class LTSettings(object):

	__metaclass__ = ABCMeta

	@abstractmethod
	def __init__(self,*args,**kwargs):
		pass

	#Read
	@classmethod
	def read(cls,config_file,*args):
		options = select_parser(config_file)
		return cls.get(options,*args)

	#Read from dictionary
	@classmethod
	def from_dict(cls,d):
		options = DictParser()
		options._buffer = d
		options.filename = "buffer"
		return cls.get(options)

	#Convert into dictionary
	def to_dict(self):

		#Create object dictionary
		obj_dict = dict()

		#Fill in the values and make JSON serialization possible
		self_dict = self.__dict__
		for key in self_dict:

			if isinstance(self_dict[key],u.core.UnitBase):
				obj_dict[key] = self_dict[key].to_string()

			elif type(self_dict[key])==u.quantity.Quantity:

				numeric_value = self_dict[key].value
				if isinstance(numeric_value,np.ndarray):
					obj_dict[key] = list(numeric_value)
				else:
					obj_dict[key] = numeric_value

			elif type(self_dict[key])==np.ndarray:
				obj_dict[key] = list(self_dict[key])

			else:
				obj_dict[key] = self_dict[key]

		#Return
		return obj_dict

#########################
#Types of option parsers#
#########################

#Generic parser
class GenericParser(object):

	__metaclass__ = ABCMeta

	@abstractmethod
	def has_section(self,section):
		pass

	@abstractmethod
	def get(self,section,option):
		pass

	@abstractmethod
	def getint(self,section,option):
		pass

	@abstractmethod
	def getfloat(self,section,option):
		pass

	@abstractmethod
	def getboolean(self,section,option):
		pass

	@abstractmethod
	def dumps(obj):
		pass

	@abstractmethod
	def loads(s):
		pass

	################################################

	@classmethod
	def dump(obj,fp):
		fp.write(cls.dumps(obj))

	@classmethod
	def load(cls,fp):
		return cls.loads(fp.read())

#Pickle parser
class PickleParser(GenericParser):

	def has_section(self,section):
		return True

	def get(self,section,option):
		if hasattr(self._buffer,option):

			parsed = getattr(self._buffer,option)

			if type(parsed) in [list,np.ndarray]:
				return ",".join([str(p) for p in parsed])
			elif type(parsed)==u.quantity.Quantity:
				try:
					return ",".join([str(p) for p in parsed.value])
				except TypeError:
					return parsed.value
			elif isinstance(parsed,u.core.UnitBase):
				return parsed.to_string()

			return parsed

		else:
			raise NoOptionError(section,option)

	def getint(self,section,option):
		return self.get(section,option)

	def getfloat(self,section,option):
		return self.get(section,option)

	def getboolean(self,section,option):
		return self.get(section,option)

	@staticmethod
	def dumps(obj):
		return pkl.dumps(obj)

	@staticmethod
	def loads(s):
		return pkl.loads(s)

#JSON parser
class JSONParser(GenericParser):

	def has_section(self,section):
		return section in self._buffer

	def get(self,section,option):
		if option in self._buffer[section]:
			parsed = self._buffer[section][option]
			if isinstance(parsed,dict):
				return parsed
			else:
				return str(parsed)
		else:
			raise NoOptionError(section,option)

	def getint(self,section,option):
		return int(self.get(section,option))

	def getfloat(self,section,option):
		return float(self.get(section,option))

	def getboolean(self,section,option):
		parsed = self.get(section,option)

		if type(parsed)==bool:
			return parsed
		if parsed=="True":
			return True
		if parsed=="False":
			return False

		raise ValueError("Cannot cast option {0} to boolean!".format(option))

	@staticmethod
	def dumps(obj):
		return json.dumps(obj.to_dict())

	@staticmethod
	def loads(s):
		return json.loads(s)

#Parser from dictionary
class DictParser(JSONParser):

	def has_section(self,section):
		return True

	def get(self,section,option):
		if option in self._buffer:
			parsed = self._buffer[option]
			if isinstance(parsed,dict):
				return parsed
			elif isinstance(parsed,list):
				return ",".join([str(p) for p in parsed])
			else:
				return str(parsed)
		else:
			raise NoOptionError(section,option)

###############################################################################################################################################


"""empty message

Revision ID: 13d80f9a4318
Revises: a5e213dc3583
Create Date: 2022-02-05 12:40:39.689142

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '13d80f9a4318'
down_revision = 'a5e213dc3583'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('banner',
    sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
    sa.Column('name', sa.String(length=200), nullable=False, comment='轮播图名称'),
    sa.Column('image_url', sa.String(length=250), nullable=False, comment='图片链接'),
    sa.Column('link_url', sa.String(length=250), nullable=False, comment='跳转链接'),
    sa.Column('priority', sa.Integer(), nullable=True, comment='优先级'),
    sa.Column('create_time', sa.DateTime(), nullable=True, comment='创建时间'),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('comment',
    sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
    sa.Column('content', sa.Text(), nullable=False, comment='评论内容'),
    sa.Column('create_time', sa.DateTime(), nullable=True, comment='创建时间'),
    sa.Column('post_id', sa.Integer(), nullable=True, comment='所属贴子id'),
    sa.Column('author_id', sa.String(length=100), nullable=False, comment='所属作者id'),
    sa.ForeignKeyConstraint(['author_id'], ['user.id'], ),
    sa.ForeignKeyConstraint(['post_id'], ['post.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('comment')
    op.drop_table('banner')
    # ### end Alembic commands ###


# math.py
# base code provided by @Prismatic

# Clean up code to catch and explain exceptions/errors
# Implement Official Website Trees

from utils import urlDecrypt as url
from utils import mathMoze as Moze
from utils import mathZane as Zane
from utils import mathAmara as Amara
from utils import mathFL4K as FL4K

"""
gear {Normal hit, v1, v2, Splash, elemental, crit, bonus element}
"""
def unpack(link, mods, gear, author="Testing"):
    toReturn=""

    if "bl3zone.com" in link:
        index = link.find("planner/")+11
        if "A" == link[index-1]:
            skills = url.zoneAmaraSpec(link[index:len(link)+1])
            toReturn = Amara.skillsSpec(skills, mods, gear)
        elif "B" == link[index-1]:
            skills = url.zoneFlakSpec(link[index:len(link)+1])
            toReturn = FL4K.skillsSpec(skills, mods, gear)
        elif "C" == link[index-1]:
            skills = url.zoneMozeSpec(link[index:len(link)+1])
            toReturn = Moze.skillsSpec(skills, mods, gear)
        elif "D" == link[index-1]:
            skills = url.zoneZaneSpec(link[index:len(link)+1])
            toReturn = Zane.skillsSpec(skills, mods, gear)

    elif "bl3skills" in link:
        index = link.find("#")+1
        if "gunner" in link:
            skills = url.skillsMozeSpec(link[index:len(link)+1])
            toReturn = Moze.skillsSpec(skills, mods, gear)
        elif "operative" in link:
            skills = url.skillsZaneSpec(link[index:len(link)+1])
            toReturn = Zane.skillsSpec(skills, mods, gear)
        elif "siren" in link:
            skills = url.skillsAmaraSpec(link[index:len(link)+1])
            toReturn = Amara.skillsSpec(skills, mods, gear)
        elif "beastmaster" in link:
            skills = url.skillsFlakSpec(link[index:len(link)+1])
            toReturn = FL4K.skillsSpec(skills, mods, gear)

    print(str(author) + "\n\n" + toReturn)
    return toReturn

"""
mults {Normal hit, v1, v2, Splash, elemental, crit, bonus element}
"""
def calc_bonus_elements(mults, experimental_munitions=0):
    bonus_element = mults[6] * (1+mults[0]) * (1+mults[1]) * (1+mults[2]) * (1+mults[4])
    str_bonus_element = "Bonus Element Damage: " + str(round(bonus_element,2))

    crit_bonus_element = (bonus_element+experimental_munitions) * 2 * (1+mults[5])
    str_crit_bonus_element = "Critical Bonus Element Damage: " + str(round(crit_bonus_element,2))
    return str_bonus_element + "\n" + str_crit_bonus_element, bonus_element, crit_bonus_element

"""
mults is expected to be a list of modifiers
{Gun Damage, V1, V2, Splash, Elemental, Critical, Bonus Element}
"""
def calc_Damage(mults):
    damage = (1+mults[0]) * (1+mults[1]) * (1+mults[2]) * (1+mults[3]) * (1+mults[4])
    body = "Damage: " + str(round(damage,2))

    crit_damage = damage * 2 * (1+mults[5])
    crit = "Critical Hit Damage: " + str(round(crit_damage,2))
    return body + "\n" + crit, damage, crit_damage