# import pygame module in this program
from concurrent.futures.thread import BrokenThreadPool
import pygame
import random
import time
import threading

def render_multiline(data):
        "Shows a multiline string with text, y pos and color for each line separated by comma"
        tc = []
        for line in data.split("\n"):

            if line != "":
                text, height, color = line.split(",")
                if height == " " or height == "":
                    height = 0
                    if color == " " or color == "":
                        color = "red"
                else:
                    height = int(height)
                tc.append([text, height, color])
        # 2. Each list of the list above is send to write to render text
        cnt = 0
        for t, height, c in tc:
            cnt += 30
            # calls write passing the text, the vertical position and the color
            for i in t.split("\n"):
                if height == 0:
                    height = cnt
                write(i, 200, height, color=c)
                height += 30

"""
INSERT:
text, vertical position, color

1. you can omit the vertical position
2. To put a blank line use ,,
"""
TEXT1 = """*** GERMAPHOBE ***, , gold
A Game by Holden and Matt, , red
,,
https://github.com/holdena12/germophobe, , coral
Game vaguely inspired by fear of germs, , cyan
,,
PRESS ANY KEY TO PLAY, , green
Press left arrow to go left, , blue
Press right arrow to go right ,, blue
Press space to shoot vaccines ,, blue
Press c for instant doom,, red

"""

pygame.init()

Font = pygame.font.SysFont
font1 = Font("Arial", 24)
font2 = Font("Arial", 20)

def write(text, x, y, color="Coral",):
    "Returns a surface with a text in the center of the screen, at y coord."

    surface_text = font1.render(text, 1, pygame.Color(color))
    text_rect = surface_text.get_rect(center=(500 // 2, y))
    win.blit(surface_text, text_rect)
    return surface_text

#the players score
score = 0

rounds = 10

lives = 1
keys = pygame.key.get_pressed()
powerUpSpread = random.randint(7,15)
germRNot = 4
vaccineSpread = 0
BOARD_WIDTH = 550
BOARD_HEIGHT = 700
gameTop = pygame.Rect(0,0,BOARD_WIDTH,1)
gameBottom = pygame.Rect(0,BOARD_HEIGHT,BOARD_WIDTH,1)
gameLeft = pygame.Rect(0,0,1,BOARD_HEIGHT)
gameRight= pygame.Rect(BOARD_WIDTH,0,1,BOARD_HEIGHT)
currentColor = (0, 0, 255)
obstColor = (0,0, 0)
obst2Color = (255,255,255)

germImg = pygame.image.load('rGerm.png')
weirdGermImg = pygame.image.load('rWeirdGerm.png')
level = 1

win = pygame.display.set_mode((BOARD_WIDTH,BOARD_HEIGHT))

DEFAULT_IMAGE_SIZE=(100,100)
germImg = pygame.transform.scale(germImg,DEFAULT_IMAGE_SIZE)

win.blit(germImg,(0,0))

class GameObject:

    dead = False
    collisionBuffer = 0

    def __init__(self, color, rect: pygame.Rect, vel , xdir =1, ydir =1, isBaby = True, xPert = 1, yPert = 1) -> None:
        self.rect = rect
        self.vel = vel
        self.xdir = xdir
        self.ydir = ydir
        self.color = color
        self.isBaby = isBaby
        self.dead = False
        self.xPert = xPert
        self.yPert = yPert

    def setDead(self):
        self.dead = True

class PowerUps(GameObject):
  def __init__(self, color, rect: pygame.Rect, vel, xdir =1, ydir =1, isBaby = True, xPert = 1, yPert = 1, type = 0):
    GameObject.__init__(self,color, rect , vel , xdir, ydir , isBaby , xPert , yPert)
    self.type = type
    #add properties etc.

# activate the pygame library .
# initiate pygame and give permission
# to use pygame's functionality.

font = pygame.font.Font('freesansbold.ttf', 16)
# create the display surface object
# of specific dimension..e(500, 500).

# set the pygame window name
pygame.display.set_caption("GermoPhobe...")

playerSpeed = 13

player_width = 100
player = GameObject((50,50,75), pygame.Rect((BOARD_WIDTH/2), BOARD_HEIGHT-80, player_width, 80),playerSpeed,0,0)
activeGerms = []
activePowerUps = []
obstacles = []
vaccines = []
activeWeirdGerms = []
# create obstacles
obstacle = GameObject(obstColor, pygame.Rect((BOARD_WIDTH/2)+25,(BOARD_HEIGHT/2) -50,200,25), 10)
obstacle2 = GameObject(obst2Color,pygame.Rect(BOARD_WIDTH/2,(BOARD_HEIGHT/2) +50,150,25), 8, -1, 0)
obstacles.append(obstacle)
obstacles.append(obstacle2)

class RepeatedTimer(object):
  def __init__(self, interval, function, *args, **kwargs):
    self._timer = None
    self.interval = interval
    self.function = function
    self.args = args
    self.kwargs = kwargs
    self.is_running = False
    self.next_call = time.time()
    self.start()

  def _run(self):
    self.is_running = False
    self.start()
    self.function(*self.args, **self.kwargs)

  def start(self):
    if not self.is_running:
      self.next_call += self.interval
      self._timer = threading.Timer(self.next_call - time.time(), self._run)
      self._timer.start()
      self.is_running = True

  def stop(self):
    self._timer.cancel()
    self.is_running = False

white = (255,255,255)
blue = (0,0,255)

#vaccine = GameObject((255,165,0), pygame(player.rect.width-player.rect.width/2,player.rect.center, 0,0),0,0)

def shootVaccine(vaccine):

    vaccine.vel = 10
    vaccine.ydir = -1

    vaccines.append(vaccine)

isWeirdGerm = random.randint(1,6)
germSpeed = random.uniform(4,5)
def addWeirdGerms():
    weirdGerm = GameObject((255,0,150), pygame.Rect(random.randint(25,BOARD_WIDTH-25), germSpeed, 50, 10,25),3)
    activeWeirdGerms.append(weirdGerm)

def addGerm():
    isWeirdGerm = random.randint(1,6)
    germ = GameObject((50,255,0), pygame.Rect(random.randint(25,BOARD_WIDTH-25), 50, 25,25),random.randint(3,6),3)
    activeGerms.append(germ)
    if isWeirdGerm == 1:
            isWeirdGerm = True
            germ.color = (255,0,0)
            germ.vel = (random.uniform(6,10))

def addPowerUp():
    powerUpType = random.randint(0,2)

    powerUp = PowerUps((0,255,255), pygame.Rect(random.randint(25,775), 50, 25,25),random.randint(5,7),random.choices([-1,1]),1,True,1,1,powerUpType)
    if powerUpType == 1:
        powerUp.color = (255,255,255)
    if powerUpType == 2:
        powerUp.color = (0,0,0)

    activePowerUps.append(powerUp)

def updateMovingObject(gameObject: GameObject, obstacles =[],dieOnImpact = False):
    if gameObject.isBaby == True:
        gameObject.isBaby = False
        rand = random.randint(0,1)
        if rand == 0:
            gameObject.xdir = -1
        else:
            gameObject.xdir = 1

    if gameObject.collisionBuffer>0:
        gameObject.collisionBuffer -= 1

   # detect if object hits a side wall
    if (gameObject.rect.colliderect(gameRight)):
        gameObject.xdir = gameObject.xdir * -1
    elif (gameObject.rect.colliderect(gameLeft)):
        gameObject.xdir = gameObject.xdir * -1
    elif gameObject.ydir == -1 and gameObject.rect.y <= gameObject.rect.height:
        gameObject.collisionBuffer = 0
        gameObject.ydir *= -1
        if (dieOnImpact):
            gameObject.dead = True
            return True
    # detect if object hits an obstacle
    if gameObject.collisionBuffer == 0:
        for obstacle in obstacles:
            if gameObject.rect.colliderect(obstacle):
                if (dieOnImpact):
                    gameObject.dead = True
                    return True
                gameObject.collisionBuffer = 60
                gameObject.ydir *= -1

                if isWeirdGerm == True:
                    if gameObject.rect.colliderect(obstacle):

                        gameObject.ydir *= -1

                #if (gameObject.rect.left <= obstacle.left+gameObject.rect.width/2):
                    #gameObject.xdir *= -1
                #pick a random number between 1 and 1.5 and random boolean 0 or 1 to indicate positve or negative and then set that value to gameObject.xPert
                # pick a random number between 1 and 1.5 and random boolean 0 or 1 to indicate positve or negative and then set that value to gameObject.yPert

                gameObject.xPert = random.uniform(1,1.5)
                gameObject.yPert = random.uniform(1,1.5)

                #print("Obstacle contact new pertubation is xPert {} and yPert {}".format(gameObject.xPert, gameObject.yPert))

    gameObject.rect = gameObject.rect.move(gameObject.xdir*gameObject.vel*gameObject.xPert, gameObject.ydir*gameObject.vel*gameObject.yPert)

    pygame.draw.rect(win, gameObject.color, gameObject.rect)
    return gameObject.dead

timers = []
rt = RepeatedTimer(germRNot, addGerm)
rpt = RepeatedTimer(powerUpSpread, addPowerUp)
timers.append(rt)
timers.append(rpt)
addGerm()

def detectGermKill(germ, gameObject):
    global score
    global level
    global germSpeed
    global germRNot
    global rt
    if (gameObject.rect.colliderect(germ.rect)):
        score += 1
        if (score % 5 == 0 ):
            level += 1
            germSpeed += 1

            gameObject.rect.width = player_width
            germRNot -= .2 * germRNot
            if germRNot <= 1:
                germRNot = 1
            rt.stop()
            timers.remove(rt)
            rt = RepeatedTimer(germRNot, addGerm)
            timers.append(rt)
        gameObject.rect.width = gameObject.rect.width-15
        if gameObject.rect.width <= 20:
            gameObject.rect.width =20
        germ.dead = True
    return germ.dead

# Indicates pygame is running
run = True
lastFireTime = -1

clock = pygame.time.Clock()
def mainloop():
    global clock, font1, font2
    # infinite loop
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quitGame()
            elif event.type == pygame.KEYDOWN:
                playGame()
        render_multiline(TEXT1)
        clock.tick(30)
        pygame.display.update()

def quitGame():
    for timer in timers:
        timer.stop()
    pygame.quit()
    exit()

def playGame():
    global run, liveString, roundsString, levelString, lives, rounds, lastFireTime, keys, rt
    while run:
        # creates time delay of 10ms
        pygame.time.delay(10)

        # iterate over the list of Event objects
        # that was returned by pygame.event.get() method.
        for event in pygame.event.get():

            # if event object type is QUIT
            # then quitting the pygame
            keys = pygame.key.get_pressed()
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_SPACE:
                    lastFireTime = -1
            if event.type == pygame.QUIT:
                quitGame()

        if (keys[pygame.K_SPACE] and rounds > 0):

            currentTime = round(time.time()*1000)
            if (lastFireTime < 0  or currentTime-lastFireTime > 1500):
                rounds -=1
                lastFireTime = currentTime
                vaccine = GameObject((255, 153, 51), pygame.Rect((player.rect.x + player.rect.width/2), player.rect.y, 10, 45),0,0,0)
                shootVaccine(vaccine)

        # if left arrow key is pressed
        if keys[pygame.K_LEFT] and player.rect.x>0:

            # decrement in x co-ordinate
            player.rect = player.rect.move(-1*player.vel,0)

        # if left arrow key is pressed
        if keys[pygame.K_RIGHT] and player.rect.x<BOARD_WIDTH-player.rect.width:

            # increment in x co-ordinate
            player.rect = player.rect.move(player.vel,0)

        #shootVaccine()

        # covid easter egg
        if keys[pygame.K_c]:
            lives=7
            playerSpeed = 25
            # let the chaos begin!
            rt.stop()
            timers.remove(rt)
            rt = RepeatedTimer(.1, addGerm)
            timers.append(rt)

        win.fill(currentColor)
        for obstacle in obstacles:
            obstacle.ydir = 0
            updateMovingObject(obstacle)
            pygame.draw.rect(win, obstColor, obstacle)

        for vaccine in vaccines:
            if (vaccine.dead == False):
                # only update object if it is not dead
                if (updateMovingObject(vaccine, obstacles, True) == False):
                    vaccine.xdir = 0
                    vaccine.vel = 15
                    pygame.draw.rect(win,vaccine.color,vaccine.rect)
            else:
                vaccines.remove(vaccine)

        # velocity / speed of movement
        scoreString = "Score: {}".format(score)
        text = font.render(scoreString, True, white, blue)
        levelString = "level: {}".format(level)
        text2 = font.render(levelString, True, white, blue )
        liveString = "lives: {}".format(lives)
        text3 = font.render(liveString, True, white, blue )
        roundsString = "Rounds: {}".format(rounds)
        text4 = font.render(roundsString,True,white, blue)

        textRect = text.get_rect()
        text2Rect = text2.get_rect()
        text3Rect = text3.get_rect()
        text4Rect = text4.get_rect()

        # set the center of the rectangular object.
        textRect.center = (35,25)
        text2Rect.center = (BOARD_WIDTH-35, 25)
        text3Rect.center = (35, 50)
        text4Rect.center = (BOARD_WIDTH-45, 50)
        win.blit(text, textRect)
        win.blit(text2, text2Rect)
        win.blit(text3, text3Rect)
        win.blit(text4, text4Rect )

        # process active germs

        for germ in activeGerms:

            if (updateMovingObject(germ, obstacles) == True):
                activeGerms.remove(germ)
            # germ collision detection
            #if (germ.dead == False and germ.rect.colliderect(obstacle2.rect) or powerUp.dead == False and powerUp.rect.colliderect(obstacle2.rect) ):
            if (germ.dead == False):
                win.blit(germImg, germ.rect)
                if (detectGermKill(germ, player) == False):
                    for vaccine in vaccines:
                        if (detectGermKill(germ, vaccine) == True):
                            vaccine.dead = True
                            break

            if germ.dead == False and germ.rect.y >= BOARD_HEIGHT-germ.rect.height:
                germ.dead = True
                lives -=1

                if lives == 0:
                    print("Game Over...")
                    print("your score was",score ,". Level: ", level, " Good job!" )
                    run = False
                    quitGame()
                    break
        #process activePowerUps
        for powerUp in activePowerUps:
            if updateMovingObject(powerUp, obstacles) == True:
                activePowerUps.remove(powerUp)
            if powerUp.dead == False and player.rect.colliderect(powerUp.rect):
                powerUp.dead = True
                if powerUp.type == 0:
                    player.color =(255,255,0)
                    rounds +=5
                elif powerUp.type == 1:
                    lives +=1
                elif powerUp.type == 2:
                    player.rect.width = player.rect.width*3

            if powerUp.rect.y >= BOARD_HEIGHT-powerUp.rect.height:
                powerUp.dead = True

        # drawing object on screen which is rectangle here
        pygame.draw.rect(win, player.color, player.rect)

        # it refreshes the window
        pygame.display.update()

mainloop()
# closes the pygame window
quitGame()

exit()


from django.shortcuts import get_object_or_404
from django.shortcuts import render, redirect
from django.template.response import TemplateResponse
from django.views.generic import TemplateView
from django_tables2 import RequestConfig
from guardian.decorators import permission_required

from .forms import AddressForm, PersonForm, PhoneForm, EmailForm
from .models import Address, Person, Email, Phone
from .tables import ListBookTable

#
# class ListBookView(TemplateView):
#
#     def get(self, request, *args, **kwargs):
#         table = ListBookTable(Person.objects.filter(user=request.user), order_by='-name')
#         RequestConfig(request, paginate={'per_page': 10}).configure(table)
#
#         return render(request, 'template_list.html', {
#             'table': table, 'title': 'List Persons', 'link_add': 'person_new'
#         })
#
# list_book = permission_required('address_book.view_person', return_403=True)(ListBookView.as_view())

# second method to list book view
@permission_required('address_book.view_person', return_403=True)
def list_book(request):
    table = ListBookTable(Person.objects.filter(user=request.user), order_by='-name')
    RequestConfig(request, paginate={'per_page': 10}).configure(table)

    return render(request, 'template_list.html', {
        'table': table, 'title': 'List Persons', 'link_add': 'person_new'
    })

class PersonsView(TemplateView):
    def get(self, request):
        try:
            persons = Person.objects.filter(user=request.user).order_by('surname')
        except:
            persons = None
        column_name = ['id', 'Name', 'Groups', 'Detail']
        column_data = []
        for person in persons:
            group_list = []
            for group in person.group_set.all():
                group_link = '/group/group_detail/{}'.format(group.pk)
                group_list.append(
                    {'col': group.name,
                     'link': group_link
                     }
                )

            edit_list = [

                {'col': 'View', 'link': '/address_book/person/{}'.format(person.pk)},
                {'col': 'Edit', 'link': '/address_book/person_edit/{}'.format(person.pk)},
                {'col': 'Delete', 'link': '/address_book/person_del/{}'.format(person.pk)},

            ]

            row = [
                {'col': person.id},
                {'col': person.name + '' + person.surname},
                {'many_link': group_list},
                {'many_link': edit_list},
            ]
            column_data.append(row)

        ctx = {'title': 'Persons List ({})'.format(request.user),
               'link_add': '/address_book/person_new',
               'column_name': column_name,
               'column_data': column_data
               }
        return render(request=request, template_name="forms.html",
                      context=ctx)

class PersonsAllView(TemplateView):

    def get(self, request):
        column_name = []
        column_data = []
        try:
            persons = Person.objects.all()
        except:
            persons = None

        if persons:
            column_name = [
                'id',
                'Name',
                # 'View detail'
            ]
            for person in persons:
                row = [
                    {'col': person.id},
                    {'col': person.name + '' + person.surname},
                    # {'col': 'View', 'link': '/address_book/person/{}'.format(person.pk)},
                ]
                column_data.append(row)

        ctx = {'title': 'Persons all List',
               # 'link_add': '/address_book/person_new',
               'column_name': column_name,
               'column_data': column_data
               }
        return render(request=request, template_name="forms.html",
                      context=ctx)

        # return render(request=request, template_name="persons_all.html",
        #               context={'persons': persons})

class PersonView(TemplateView):

    def get(self, request, id):
        ctx = {}
        if id:
            person = get_object_or_404(Person, id=id, user=request.user)
            # check persmission if user doesnt have permission return "no permission"
            ctx['instance'] = person

        return TemplateResponse(request, 'person.html', ctx)

    def post(self, request): #TODO ?
        id_person = request.POST.get("id_person")
        id_address = request.POST.get("id_address")
        id_phone = request.POST.get("id_phone")
        id_email = request.POST.get("id_email")
        if id:
            instance_person = get_object_or_404(Person, id=id_person)
            instance_address = get_object_or_404(Address, id=id_address)
            instance_phone = get_object_or_404(Phone, id=id_phone)
            instance_email = get_object_or_404(Email, id=id_email)

            person = PersonForm(request.POST or None, instance=instance_person)
            address = AddressForm(request.POST or None, instance=instance_address)
            phone = PhoneForm(request.POST or None, instance=instance_phone)
            email = EmailForm(request.POST or None, instance=instance_email)

            ctx = {"form_person": person, "form_address": address,
                   "form_phone": phone, "form_email": email,
                   "title": "Person"}

            return TemplateResponse(request, 'person_new.html', ctx)

class PersonNewView(TemplateView):

    def get(self, request):
        person = PersonForm()
        address = AddressForm()

        ctx = {"form_person": person, "form_address": address,
               "title": "Person"}
        return TemplateResponse(request, 'person_new.html', ctx)

    def post(self, request):
        person_form = PersonForm(request.POST)
        address_form = AddressForm(request.POST)
        if person_form.is_valid() and address_form.is_valid():
            address = address_form.save(commit=True)
            person = person_form.save(commit=False)
            person.address_id = address.id
            person.user = request.user
            person.save()
            return redirect('person', id=person.id)

class PersonEditView(TemplateView):

    def get(self, request, id):
        if id:
            instance_person = get_object_or_404(Person, id=id)
            instance_address = get_object_or_404(Address, id=instance_person.address_id)

            person = PersonForm(request.POST or None, instance=instance_person)
            address = AddressForm(request.POST or None, instance=instance_address)

            ctx = {"form_person": person, "form_address": address,
                   "title": "Person", "id": id}

            return TemplateResponse(request, 'person_edit.html', ctx)

    def post(self, request, id):
        instance_person = get_object_or_404(Person, id=id)
        instance_address = get_object_or_404(Address, id=instance_person.address_id)

        person_form = PersonForm(request.POST or None, instance=instance_person)
        address_form = AddressForm(request.POST or None, instance=instance_address)

        if address_form.is_valid():
            address = address_form.save(commit=True)
        if person_form.is_valid():
            person = person_form.save(commit=False)
            person.address_id = address.id
            person.save()
            return redirect('person', id=person.id)

class PersonDelView(TemplateView):

    def get(self, request, id):
        """Method get delete person data in table address phone email and person"""
        if id:
            person = get_object_or_404(Person, id=id)
            # address = person.address
            #
            # address = get_object_or_404(Address, id=person.address_id)
            # phone = get_object_or_404(Phone, id=person.phone_id)
            # email = get_object_or_404(Email, id=person.email_id)
            #
            # if address:
            #     address.delete()
            # if phone:
            #     phone.delete()
            # if email:
            #     email.delete()
            if person:
                person.delete()

        return redirect('persons_list')


class CoffeeMachine:
    # Constructor that initializes a CoffeeMachine with default values.
    def __init__(self):
        self.water = 400
        self.milk = 540
        self.coffee_beans = 120
        self.cups = 9
        self.money = 550
        self.state = 'await_command'

    # Determines if the coffee machine has enough resources to make the specified type of coffee and adjusts
    # attribute values accordingly.
    def buy(self, choice):
        # Change the CoffeeMachine's state so that it is now awaiting another command.
        self.state = 'await_command'

        # Check if the user chose to return to the main menu.
        if choice == 'back':
            return
        else:
            choice = int(choice)

        # Define the number of each resource is needed based upon the type of coffee the user selected.
        water_needed = 0
        milk_needed = 0
        coffee_beans_needed = 0
        cost = 0
        if choice == 1:  # espresso
            water_needed = 250
            coffee_beans_needed = 16
            cost = 4
        elif choice == 2:  # latte
            water_needed = 350
            milk_needed = 75
            coffee_beans_needed = 20
            cost = 7
        elif choice == 3:  # cappuccino
            water_needed = 200
            milk_needed = 100
            coffee_beans_needed = 12
            cost = 6

        # Check that there is enough of each resource to make the coffee, then make it and adjust attribute values.
        if self.water - water_needed < 0:
            print('Sorry, not enough water!')
        elif self.milk - milk_needed < 0:
            print('Sorry, not enough milk!')
        elif self.coffee_beans - coffee_beans_needed < 0:
            print('Sorry, not enough coffee beans!')
        elif self.cups < 1:
            print('Sorry, not enough disposable cups!')
        else:
            print('I have enough resources, making you a coffee!')
            self.water -= water_needed
            self.milk -= milk_needed
            self.coffee_beans -= coffee_beans_needed
            self.cups -= 1
            self.money += cost

    # Adjusts an attribute corresponding to the CoffeeMachine's current state by the specified amount.
    def fill(self, amount):
        if self.state == 'await_amt_water':
            self.water += int(amount)
            self.state = 'await_amt_milk'
            print('Write how many ml of milk do you want to add:')
        elif self.state == 'await_amt_milk':
            self.milk += int(amount)
            self.state = 'await_amt_coffee_beans'
            print('Write how many grams of coffee beans do you want to add:')
        elif self.state == 'await_amt_coffee_beans':
            self.coffee_beans += int(amount)
            self.state = 'await_amt_cups'
            print('Write how many disposable cups of coffee do you want to add:')
        elif self.state == 'await_amt_cups':
            self.cups += int(amount)
            self.state = 'await_command'

    # Prints a message and reduces the CoffeeMachine's money attribute to 0.
    def take(self):
        print('I gave you ${}'.format(self.money))
        self.money = 0

    # Prints the CoffeeMachine's attribute's values.
    def remaining(self):
        print('The coffee machine has:')
        print('{} of water'.format(self.water))
        print('{} of milk'.format(self.milk))
        print('{} of coffee beans'.format(self.coffee_beans))
        print('{} of disposable cups'.format(self.cups))
        print('{} of money'.format(self.money))

    # Handles all incoming commands based on the current state of the CoffeeMachine.
    def command(self, command):
        if self.state == 'await_command':
            if command == 'buy':
                self.state = 'await_buy_choice'
                print('What do you want to buy? 1 - espresso, 2 - latte, 3 - cappuccino, back - to main menu:')
            elif command == 'fill':
                self.state = 'await_amt_water'
                print('Write how many ml of water do you want to add:')
            elif command == 'take':
                self.take()
            elif command == 'remaining':
                self.remaining()
            elif command == 'exit':
                self.state = 'shutdown'
        elif self.state == 'await_buy_choice':
            self.buy(command)
        elif self.state.startswith('await_amt_'):
            self.fill(command)

# Create a CoffeeMachine instance and loop until it reaches the 'shutdown' state.
machine = CoffeeMachine()
while machine.state != 'shutdown':
    if machine.state == 'await_command':
        print('Write action (buy, fill, take, remaining, exit):')
    machine.command(input())


'''
    The tasks of this file are as follows:
        - Test functions within updates_handler.py
'''

from flaskr.updates_handler import add_updates
from flaskr.updates_handler import find_update
from flaskr.updates_handler import delete_updates
from flaskr.updates_handler import cancel_event
from flaskr.updates_handler import update_event
from flaskr.updates_handler import ALARMED_UPDATES
from flaskr.covid_data_handler import schedule_covid_updates
from flaskr.covid_news_handling import schedule_news_updates
from flaskr.shared_scheduler import scheduler

def test_add_updates():
    '''
    test 'add_updates' function
    '''

    #when testing, list should be empty to begin with

    assert len(ALARMED_UPDATES) == 0

    #when a time is given

    add_updates("test", "14:00", False, True, False)

    #test the update has been added to the list

    assert len(ALARMED_UPDATES) == 1

    #when a time is not given

    add_updates("test", None, False, True, False)

    #test the update has been added to the list

    assert len(ALARMED_UPDATES) == 2

def test_find_update():
    '''
    test 'find_update' function
    '''

    #call function to add an update

    add_updates("test", None, False, True, False)

    #call function to find update

    update = find_update("test")

    #test that update should be found

    assert update is not None

    #call function to find update

    update = find_update("hello")

    #test that update should not be found

    assert update is None

def test_delete_updates():
    '''
    test 'delete_updates' function
    '''

    #when testing, list should be empty to begin with

    assert len(ALARMED_UPDATES) == 0

    #call function to add an update

    add_updates("test", "14:00", False, True, False)

    #test the update has been added to the list

    assert len(ALARMED_UPDATES) == 1

    #call function to delete an update

    delete_updates("test")

    #test the update has been removed from the list

    assert len(ALARMED_UPDATES) == 0

def test_cancel_event():
    '''
    test 'cancel_event' function
    '''

    #when testing, queue should be empty to begin with

    assert len(scheduler.queue) == 0

    #schedule a covid update

    event = schedule_covid_updates(5, "hello")

    #test the update has been added to the queue

    assert len(scheduler.queue) == 1

    #cancel the event

    cancel_event("hello")

    #test that the update has been removed from the queue

    assert len(scheduler.queue) == 0

    #schedule a news update

    event = schedule_news_updates(5, "hello")

    #test the update has been added to the queue

    assert len(scheduler.queue) == 1

    #cancel the event

    cancel_event("hello")

    #test that the update has been removed from the queue

    assert len(scheduler.queue) == 0


import asyncio
from asyncio.locks import Event
from contextlib import contextmanager

from replayserver.send.stream import DelayedReplayStream
from replayserver.errors import MalformedDataError, \
    CannotAcceptConnectionError
from replayserver.collections import AsyncCounter

class Sender:
    def __init__(self, delayed_stream):
        self._stream = delayed_stream
        self._conn_count = AsyncCounter()
        self._ended = Event()
        asyncio.ensure_future(self._lifetime())

    @classmethod
    def build(cls, stream, **kwargs):
        delayed_stream = DelayedReplayStream.build(stream, **kwargs)
        return cls(delayed_stream)

    @contextmanager
    def _connection_count(self):
        self._conn_count.inc()
        try:
            yield
        finally:
            self._conn_count.dec()

    async def handle_connection(self, connection):
        if self._stream.ended():
            raise CannotAcceptConnectionError(
                "Reader connection arrived after replay ended")
        with self._connection_count():
            await self._write_header(connection)
            await self._write_replay(connection)

    async def _write_header(self, connection):
        header = await self._stream.wait_for_header()
        if header is None:
            raise MalformedDataError("Malformed replay header")
        await connection.write(header.data)

    async def _write_replay(self, connection):
        position = 0
        while True:
            data = await self._stream.wait_for_data(position)
            if not data:
                break
            position += len(data)
            conn_open = await connection.write(data)
            if not conn_open:
                break

    def close(self):
        pass

    async def _lifetime(self):
        await self._stream.wait_for_ended()
        await self._conn_count.wait_until_empty()
        self._ended.set()

    async def wait_for_ended(self):
        await self._ended.wait()


# -*- coding: utf-8 -*-
# dydrmntion@gmail.com

import sys
import os
import re
from types import FunctionType

class PercuiroUserProvidersException(Exception):
    pass

def get_user_providers(user_providers_fpath):
    user_providers_module = import_user_providers(user_providers_fpath)
    user_providers = validate_user_providers_module(user_providers_module)
    for provider in user_providers:
        validate_provider(provider)
    return user_providers

def import_user_providers(user_providers_fpath):
    if not os.path.exists(user_providers_fpath):
        raise PercuiroUserProvidersException(
            '{0!r} does not exist on filesystem'.format(user_providers_fpath))

    fname = os.path.basename(user_providers_fpath)
    fpath = os.path.dirname(user_providers_fpath)
    sys.path.append(fpath)
    try:
        user_providers = __import__(fname.rstrip('.py'))
    except ImportError as e:
        raise PercuiroUserProvidersException('Could not import `{0}`: {1!r}'.format(
            user_providers_fpath, e.message))
    finally:
        sys.path.remove(fpath)
    return user_providers

def validate_user_providers_module(user_providers_module):
    try:
        user_providers = getattr(user_providers_module, 'my_providers')
    except AttributeError:
        raise PercuiroUserProvidersException(
            'Required variable `my_providers` not found in user_providers module.')

    if not isinstance(user_providers, tuple):
        raise PercuiroUserProvidersException(
            'user_providers variable should be a `tuple`, `{0}` found.'.format(
                type(user_providers)))
    return user_providers

def validate_provider(provider):
    is_function = lambda x: isinstance(x, FunctionType)
    is_url = lambda x: isinstance(x, str) and re.match(r'/|http', x)
    validators = [
        (
            'name',
            lambda x: isinstance(x, str)
        ), (
            'base_url',
            is_url
        ), (
            'query_url',
            lambda x: (is_url(x) and '{query}' in x or is_function(x) or
                       isinstance(x, tuple) and len(x) == 2)
        ), (
            'result_selector',
            lambda x: isinstance(x, list) and len(x) > 0
        ), (
            'get_result_label',
            lambda x: is_function(x)
        ), (
            'next_page_format',
            lambda x: re.search(r'\(\[0-9\]\+\)', x)
        ), (
            'thumbnail_url',
            lambda x: is_url(x) and re.search(r'\.(?:png|jpg)', x)
        )
    ]
    for k, v in validators:
        val = provider.get(k)
        if not val:
            if k not in ['next_page_format', 'thumbnail_url']:
                raise PercuiroUserProvidersException(
                    '{0} provider validation key error: {1!r} not in dictionary'.format(
                        provider.get('name', 'UNKNOWN_NAME'), k))
            else:
                continue
        if not v(val):
            raise PercuiroUserProvidersException(
                '{0} provider validation invalid value error: {1}, {2}'.format(
                    provider.get('name', 'UNKNOWN_NAME'), k, val))
    return True


#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# TalkTalkTalk
#
# is an easy-installable small chat room, with chat history.
#
# author:  Joseph Ernest (twitter: @JosephErnest)
# url:     http://github.com/josephernest/talktalktalk
# license: MIT license

import sys, json, bleach, time, threading, dumbdbm, random, re
import daemon
from bottle import route, run, view, request, post, ServerAdapter, get, static_file
from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler
from geventwebsocket.exceptions import WebSocketError
from collections import deque
from config import PORT, HOST, ADMINNAME, ADMINHIDDENNAME, ALLOWEDTAGS

idx = 0

def websocket(callback):
    def wrapper(*args, **kwargs):
        callback(request.environ.get('wsgi.websocket'), *args, **kwargs)
    return wrapper

class GeventWebSocketServer(ServerAdapter):
    def run(self, handler):
        server = pywsgi.WSGIServer((self.host, self.port), handler, handler_class=WebSocketHandler)
        server.serve_forever()

def main():
    global idx
    db = dumbdbm.open('talktalktalk.db', 'c')
    idx = len(db)

    users = {}
    pings = {}
    usermessagetimes = {}

    def send_userlist():
        for u in users.keys():
            if not u.closed:
                u.send(json.dumps({'type' : 'userlist', 'connected': users.values()}))

    def clean_username(usr, ws):
        username = bleach.clean(usr, tags=ALLOWEDTAGS, strip=True)
        #username = re.sub('[ :]', '', username)      # removes " ", ":", and the evil char "" http://unicode-table.com/fr/200D/
        username = re.sub(r'\W+', '', username)       # because of spam and usage of malicious utf8 characters, let's use alphanumeric usernames only for now
        username = username[:16]
        if username.lower() == ADMINNAME or username == '':
            username = 'user' + str(random.randint(0, 1000))
            ws.send(json.dumps({'type' : 'usernameunavailable', 'username' : username}))
        elif username.lower() == ADMINHIDDENNAME:
            username = ADMINNAME
            ws.send(json.dumps({'type' : 'displayeduser', 'username' : username}))
        return username

    def dbworker():        # when a user disappears during more than 30 seconds (+/- 10), remove him/her from the userlist
        while True:
            userlistchanged = False
            t = time.time()
            for ws in users.copy():
                if t - pings[ws] > 30:
                    del users[ws]
                    del pings[ws]
                    userlistchanged = True
            if userlistchanged:
                send_userlist()
            time.sleep(10)

    dbworkerThread = threading.Thread(target=dbworker)
    dbworkerThread.daemon = True
    dbworkerThread.start()

    @get('/ws', apply=[websocket])
    def chat(ws):
        global idx
        usermessagetimes[ws] = deque(maxlen=10)
        while True:
            try:
                receivedmsg = ws.receive()
                if receivedmsg is not None:

                    receivedmsg = receivedmsg.decode('utf8')
                    if len(receivedmsg) > 4096:      # this user is probably a spammer
                        ws.send(json.dumps({'type' : 'flood'}))
                        break

                    pings[ws] = time.time()

                    if receivedmsg == 'ping':         # ping/pong packet to make sure connection is still alive
                        ws.send('id' + str(idx-1))    # send the latest message id in return
                        if ws not in users:           # was deleted by dbworker
                            ws.send(json.dumps({'type' : 'username'}))
                    else:
                        usermessagetimes[ws].append(time.time())                           # flood control
                        if len(usermessagetimes[ws]) == usermessagetimes[ws].maxlen:
                            if usermessagetimes[ws][-1] - usermessagetimes[ws][0] < 5:     # if more than 10 messages in 5 seconds (including ping messages)
                                ws.send(json.dumps({'type' : 'flood'}))                    # disconnect the spammer
                                break

                        msg = json.loads(receivedmsg)

                        if msg['type'] == 'message':
                            message = (bleach.clean(msg['message'], tags=ALLOWEDTAGS, strip=True)).strip()

                            if ws not in users:         # is this really mandatory ?
                                username = clean_username(msg['username'], ws)
                                users[ws] = username
                                send_userlist()

                            if message:
                                if len(message) > 1000:
                                    message = message[:1000] + '...'
                                s = json.dumps({'type' : 'message', 'message': message, 'username': users[ws], 'id': idx, 'datetime': int(time.time())})
                                db[str(idx)] = s                # Neither dumbdbm nor shelve module allow integer as key... I'm still looking for a better solution!
                                idx += 1
                                for u in users.keys():
                                    u.send(s)

                        elif msg['type'] == 'messagesbefore':
                            idbefore = msg['id']
                            ws.send(json.dumps({'type' : 'messages', 'before': 1, 'messages': [db[str(i)] for i in range(max(0,idbefore - 100),idbefore)]}))

                        elif msg['type'] == 'messagesafter':
                            idafter = msg['id']
                            ws.send(json.dumps({'type' : 'messages', 'before': 0, 'messages': [db[str(i)] for i in range(idafter,idx)]}))

                        elif msg['type'] == 'username':
                            username = clean_username(msg['username'], ws)
                            if ws not in users:          # welcome new user
                                ws.send(json.dumps({'type' : 'messages', 'before': 0, 'messages': [db[str(i)] for i in range(max(0,idx - 100),idx)]}))
                            users[ws] = username
                            send_userlist()
                else:
                    break
            except (WebSocketError, ValueError, UnicodeDecodeError):      # ValueError happens for example when "No JSON object could be decoded", would be interesting to log it
                break

        if ws in users:
            del users[ws]
            del pings[ws]
            send_userlist()

    @route('/')
    @route('/index.html')
    @view('talktalktalk.html')
    def index():
        context = {'request': request}
        return (context)

    @route('/popsound.mp3')
    def popsound():
        return static_file('popsound.mp3', root='.')

    run(host=HOST, port=PORT, debug=True, server=GeventWebSocketServer)

class talktalktalk(daemon.Daemon):
    def run(self):
        main()

if len(sys.argv) == 1:           # command line interactive mode
    main()

elif len(sys.argv) == 2:         # daemon mode
    daemon = talktalktalk(pidfile='_.pid', stdout='log.txt', stderr='log.txt')

    if 'start' == sys.argv[1]:
        daemon.start()
    elif 'stop' == sys.argv[1]:
        daemon.stop()
    elif 'restart' == sys.argv[1]:
        daemon.restart()


import numpy as np
import pandas as pd
import matplotlib.dates as mdates
from matplotlib import *
from matplotlib.pyplot import *
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
from matplotlib.font_manager import FontProperties
from matplotlib import gridspec
from scipy.stats import norm
from tabulate import tabulate
import sys
if not sys.warnoptions:
    import warnings
    warnings.simplefilter("ignore")

def daily_avg(df):
    df['Daily Rt'] = (np.log( df['Close']/df['Close'].shift(1)))*100
    Daily_Average = df['Daily Rt'].mean()
    Daily_SD = np.std(df['Daily Rt'])
    print("Daily Average =", df['Daily Rt'].mean())
    print()
    print("Daily SD = ", Daily_SD,"%")
    print()

def avg_return(df, price, period):
    #CMP = df['Close'].iloc[-1]
    df['Daily Rt'] = (np.log( df['Close']/df['Close'].shift(1)))*100
    Daily_Average = df['Daily Rt'].mean()
    Daily_SD = np.std(df['Daily Rt'])

    period_avg = (Daily_Average*period)
    period_SD = (Daily_SD*np.sqrt(period))

    range_up = (period_avg+period_SD)/100
    range_low = abs((period_avg-period_SD))/100
    price_up = price*(1.0+range_up )
    price_low = price*(1.0-range_low )
    print(period, "Days Average = ",period_avg ,"%")
    print()
    print(period, "Days SD = ",period_SD ,"%")
    print()
    print(period, "days Up range = ", range_up*100, "%")
    print()
    print(period, "days Low range = ", range_low*100 ,"%")
    print()
    print("Upper Price for",period, "days range = ", price_up)
    print()
    print("Lower Price for",period, "days range = ", price_low)
    print()
    print("-----------Suggestions-----------:")
    print("Sell Call Option Above",price_up )
    print()
    print("Sell Put Option Below",price_low )
    print("----------------------------------:")

def sd_price(df, lm):
    if len(df) == 252:
        l = 252
        dfn = df
    elif len(df) > 252:
        dfn = df.iloc[-252:]
        l = len(df)
    else:
        dfn = df
        l = len(df)

    Spot_price = dfn['Close'].iloc[-1]
    dfn['Close'] = dfn['Close'].tail(l)
    dfn['log returns'] = (np.log( dfn['Close']/dfn['Close'].shift(1)))
#
    Daily_avg = abs(np.mean(((dfn['Close'] - dfn['Close'].shift(1))/dfn['Close'].shift(1))*100))
    Daily_std = round(np.std(dfn['log returns']), 4)*100
#
# annual numbers
    yearly_avg = Daily_avg*l
    yearly_std = Daily_std*np.sqrt(l)
    Up_range_1SD = yearly_avg + yearly_std
    Low_range_1SD = yearly_avg - yearly_std

    UP_1SD = Spot_price*(1+(Up_range_1SD/100))
    Low_1SD = Spot_price*(1-(Low_range_1SD/100))
#
    Up_range_2SD = yearly_avg + 2*yearly_std
    Low_range_2SD = yearly_avg - 2*yearly_std
#
    UP_2SD = Spot_price*(1+(Up_range_2SD/100))
    Low_2SD = Spot_price*(1-(Low_range_2SD/100))
#
# Monthly numbers
    #lm = 30
    Mon_Average = Daily_avg*lm
    Mon_Std_dev = Daily_std*np.sqrt(lm)
#
    Mon_Up_range_1SD = Mon_Average + Mon_Std_dev
    Mon_Low_range_1SD = Mon_Average - Mon_Std_dev
    Mon_UP_1SD = Spot_price*(1+ (Mon_Up_range_1SD/100))
    Mon_Low_1SD = Spot_price*(1-(Mon_Low_range_1SD/100))
#
    Mon_Up_range_2SD = Mon_Average + 2*Mon_Std_dev
    Mon_Low_range_2SD = Mon_Average - 2*Mon_Std_dev
    Mon_UP_2SD = Spot_price*(1+ (Mon_Up_range_2SD/100))
    Mon_Low_2SD = Spot_price*(1-(Mon_Low_range_2SD/100))

# annual Probability
    print("Number of days = " ,l)
    print("Daily Average/Mean    = ", round(abs(Daily_avg),4), "%")
    print("Daily Std./Volatility = ", round(Daily_std,4), "%")
    print("Annual Std./Volatility = ", round(yearly_std,4), "%")

    print("Current Market Price = ", round(Spot_price,2), "Rs")
    print()
    print("1SD: 68% Probability in a year")
    print("1Yr UP from 1SD   = ",round(UP_1SD,2), "Rs")
    print("1Yr Low from 1SD   = ", round(Low_1SD,2), "Rs"  )
    print()
    print("2SD: 95% Probability in a year")
    print("1Yr UP from 2SD    = ",round(UP_2SD,2), "Rs")
    print("1Yr Low from 2SD   = ", round(Low_2SD,2), "Rs" )
    print()
    print("1SD: 68% Probability in ", lm, "Days")
    print(lm ," days UP from 1SD   = ",round(Mon_UP_1SD,2), "Rs")
    print(lm ," days Low from 1SD   = ", round(Mon_Low_1SD,2), "Rs" )
    print()
    print("2SD: 95% Probability in ", lm, "Days")
    print(lm ," days UP from 2SD    = ",round(Mon_UP_2SD,2), "Rs")
    print(lm ," days Low from 2SD   = ", round(Mon_Low_2SD,2), "Rs" )
#
def vol_hist(df):
    df['Daily Rt'] = (np.log( df['Close']/df['Close'].shift(1)))*100
    daily_std = np.std(np.log( df['Close']/df['Close'].shift(1)))
    str_vol = str(round(daily_std, 4)*100)
    #df['20 day Volatility'] = 100*df['Daily Rt'].rolling(window=20).std()
    years = mdates.YearLocator()   # every year
    months = mdates.MonthLocator()  # every month
    years_fmt = mdates.DateFormatter('%Y')
    fig = plt.subplots(figsize=(5,4), dpi=400)
    gs = gridspec.GridSpec(1, 1)
    ax0 = plt.subplot(gs[0])
    df['Daily Rt'].hist(ax=ax0, bins=26, alpha=0.75, color='blue')
    ax0.set_title('volatility:'  + str_vol + '%')
    ax0.set_xlabel('Log Daily return')
    ax0.set_ylabel('Freq of log return')
    #plt.tight_layout()
#
def bs_call(S0,X,t,σ,r,q,td):
    σ,r,q,t = σ/100,r/100, q/100,t/td
  #https://unofficed.com/black-scholes-model-options-calculator-google-sheet/

    d1 = (np.log(S0/X)+(r-q+0.5*σ**2)*t)/(σ*np.sqrt(t))
  #stackoverflow.com/questions/34258537/python-typeerror-unsupported-operand-types-for-float-and-int

  #stackoverflow.com/questions/809362/how-to-calculate-cumulative-normal-distribution
    Nd1 = (np.exp((-d1**2)/2))/np.sqrt(2*np.pi)
    d2 = d1-σ*np.sqrt(t)
    Nd2 = norm.cdf(d2)
    call_theta =(-((S0*σ*np.exp(-q*t))/(2*np.sqrt(t))*
                (1/(np.sqrt(2*np.pi)))*np.exp(-(d1*d1)/2))-
                (r*X*np.exp(-r*t)*norm.cdf(d2))+(q*np.exp(-q*t)*S0*norm.cdf(d1)))/td
    call_premium =np.exp(-q*t)*S0*norm.cdf(d1)-X*np.exp(-r*t)*norm.cdf(d1-σ*np.sqrt(t))
    call_delta =np.exp(-q*t)*norm.cdf(d1)
    gamma =(np.exp(-r*t)/(S0*σ*np.sqrt(t)))*(1/(np.sqrt(2*np.pi)))*np.exp(-(d1*d1)/2)
    vega = ((1/100)*S0*np.exp(-r*t)*np.sqrt(t))*(1/(np.sqrt(2*np.pi))*np.exp(-(d1*d1)/2))
    call_rho =(1/100)*X*t*np.exp(-r*t)*norm.cdf(d2)
    print("Call Θ = ", call_theta)
    print("Call premium = " , call_premium)
    print("Call δ =",  call_delta)
    print("Call Gamma, γ =" , gamma)
    print("Call Vega, ν = ",  vega)
    print("Call ρ = ",  call_rho)
    return call_theta,call_premium,call_delta,gamma,vega,call_rho
#
def bs_put(S0,X,t,σ,r,q,td):
    σ,r,q,t = σ/100,r/100, q/100,t/td
  #https://unofficed.com/black-scholes-model-options-calculator-google-sheet/

    d1 = (np.log(S0/X)+(r-q+0.5*σ**2)*t)/(σ*np.sqrt(t))
  #stackoverflow.com/questions/34258537/python-typeerror-unsupported-operand-types-for-float-and-int

  #stackoverflow.com/questions/809362/how-to-calculate-cumulative-normal-distribution
    Nd1 = (np.exp((-d1**2)/2))/np.sqrt(2*np.pi)
    d2 = d1-σ*np.sqrt(t)
    Nd2 = norm.cdf(d2)

    put_theta =(-((S0*σ*np.exp(-q*t))/(2*np.sqrt(t))*
            (1/(np.sqrt(2*np.pi)))*np.exp(-(d1*d1)/2))
            +(r*X*np.exp(-r*t)*norm.cdf(-d2))-(q*np.exp(-q*t)*S0*norm.cdf(-d1)))/td
    put_premium =X*np.exp(-r*t)*norm.cdf(-d2)-np.exp(-q*t)*S0*norm.cdf(-d1)
    put_delta =np.exp(-q*t)*(norm.cdf(d1)-1)
    gamma =(np.exp(-r*t)/(S0*σ*np.sqrt(t)))*(1/(np.sqrt(2*np.pi)))*np.exp(-(d1*d1)/2)
    vega = ((1/100)*S0*np.exp(-r*t)*np.sqrt(t))*(1/(np.sqrt(2*np.pi))*np.exp(-(d1*d1)/2))
    put_rho =(-1/100)*X*t*np.exp(-r*t)*norm.cdf(-d2)
    print("Put Θ = ",  put_theta)
    print("Put premium = ", put_premium)
    print("Put δ =", put_delta)
    print("Put Gamma, γ =" , gamma)
    print("Put Vega, ν = ",  vega)
    print("Put ρ = ", put_rho)
    return put_theta,put_premium,put_delta,gamma,vega,put_rho
#
def bs_call_put(S0,X,t,σ,r,q,td):
    σ,r,q,t = σ/100,r/100, q/100,t/td
  #https://unofficed.com/black-scholes-model-options-calculator-google-sheet/

    d1 = (np.log(S0/X)+(r-q+0.5*σ**2)*t)/(σ*np.sqrt(t))
  #stackoverflow.com/questions/34258537/python-typeerror-unsupported-operand-types-for-float-and-int
  #stackoverflow.com/questions/809362/how-to-calculate-cumulative-normal-distribution
    Nd1 = (np.exp((-d1**2)/2))/np.sqrt(2*np.pi)
    d2 = d1-σ*np.sqrt(t)
    Nd2 = norm.cdf(d2)
    call_theta =(-((S0*σ*np.exp(-q*t))/(2*np.sqrt(t))*(1/(np.sqrt(2*np.pi)))*np.exp(-(d1*d1)/2))-(r*X*np.exp(-r*t)*norm.cdf(d2))+(q*np.exp(-q*t)*S0*norm.cdf(d1)))/td
    put_theta =(-((S0*σ*np.exp(-q*t))/(2*np.sqrt(t))*(1/(np.sqrt(2*np.pi)))*np.exp(-(d1*d1)/2))+(r*X*np.exp(-r*t)*norm.cdf(-d2))-(q*np.exp(-q*t)*S0*norm.cdf(-d1)))/td
    call_premium =np.exp(-q*t)*S0*norm.cdf(d1)-X*np.exp(-r*t)*norm.cdf(d1-σ*np.sqrt(t))
    put_premium =X*np.exp(-r*t)*norm.cdf(-d2)-np.exp(-q*t)*S0*norm.cdf(-d1)
    call_delta =np.exp(-q*t)*norm.cdf(d1)
    put_delta =np.exp(-q*t)*(norm.cdf(d1)-1)
    gamma =(np.exp(-r*t)/(S0*σ*np.sqrt(t)))*(1/(np.sqrt(2*np.pi)))*np.exp(-(d1*d1)/2)
    vega = ((1/100)*S0*np.exp(-r*t)*np.sqrt(t))*(1/(np.sqrt(2*np.pi))*np.exp(-(d1*d1)/2))
    call_rho =(1/100)*X*t*np.exp(-r*t)*norm.cdf(d2)
    put_rho =(-1/100)*X*t*np.exp(-r*t)*norm.cdf(-d2)
    d = [
     ["Premium (Rs)", call_premium, put_premium],
     ["Delta (δ)", call_delta, put_delta],
     ["Gamma (γ )", gamma, gamma] ,
     ["Theta (Θ)",call_theta,put_theta ],
     ["Vega (ν)", vega, vega],
     ["Rho (ρ)",call_rho, put_rho ]]

    print(tabulate(d, headers=["OPTION/Greek", "CALL", "PUT"]))

    ''' print("Call premium = " , call_premium)
    print("Put premium = ", put_premium)
    print("-------------------------------------")
    print("Call δ =",  call_delta)
    print("Put δ =", put_delta)
    print("-------------------------------------")
    print("Gamma, γ =" , gamma)
    print("-------------------------------------")
    print("Call Θ = ", call_theta)
    print("Put Θ = ",  put_theta)
    print("-------------------------------------")
    print("Vega, ν = ",  vega)
    print("Rho is the rate at which the price of a derivative changes relative to a change in the risk-free rate of interest")
    print("Call ρ = ",  call_rho)
    print("Put ρ = ", put_rho)
    return call_theta,put_theta,call_premium,put_premium,call_delta,put_delta,gamma,vega,call_rho,put_rho'''


#!/usr/bin/python3

# IDEA: Put the encryption word into a string. Loop through the string
# if index in string == len(string):
#   counter = 0
# use a counter to keep track of where you are in the string and reset new_char
# when you get to the last character.

import helpers
import caesar
from sys import argv

# Use your desired rotation amount as an argument when running this program

def encrypt(text, encryption_key):
    counter = 0
    new_text = []
    for char in text:
        if char.isalpha():
            if counter < len(encryption_key) - 1:
                new_text.append(caesar.encrypt(
                    char, helpers.alphabet_position(encryption_key[counter])))
                counter += 1
            elif counter == len(encryption_key) - 1:
                new_text.append(caesar.encrypt(
                    char, helpers.alphabet_position(encryption_key[counter])))
                counter = 0
        else:
            new_text.append(char)
    return "".join(new_text)

def main():
    user_text = input("Type a message: ")
    if len(argv) > 1:
        user_key = argv[1]
    else:
        user_key = input("Type an encryption key: ")
    print(encrypt(user_text, user_key))

if __name__ == "__main__":
    main()


import bpy
import math
import random
import os

count = 12

def import_backgrounds():
    directory = os.fsencode('C:\\Users\\Julian\\Desktop\\set\\backgrounds')

    for file in os.listdir(directory):
        filename = os.fsdecode(file)
        bpy.ops.image.open(filepath='C:\\Users\\Julian\\Desktop\\set\\backgrounds\\'+filename)

def import_object(name):
    file_loc = 'C:\\Users\\Julian\\Desktop\\set\\'+name+'\\'+name+'.obj'
    imported_object = bpy.ops.import_scene.obj(filepath=file_loc)

def rotate_cam(amount):
    cam = bpy.context.scene.camera
    cam_loc = cam.location.copy()

    cam_abs = math.sqrt(cam_loc.x*cam_loc.x+cam_loc.y*cam_loc.y)
    alpha = math.atan(cam_loc.y/cam_loc.x)+amount

    if cam_loc.x < 0:
        cam.location.x = -math.cos(alpha)*cam_abs
        cam.location.y = -math.sin(alpha)*cam_abs
    else:
        cam.location.x = math.cos(alpha)*cam_abs
        cam.location.y = math.sin(alpha)*cam_abs

    cam_rot = cam.rotation_euler
    cam_loc = cam.location.copy()

    if cam_loc.y < 0:
        cam_rot.z = math.atan(-cam_loc.x/cam_loc.y)
    else:
        cam_rot.z = math.atan(-cam_loc.x/cam_loc.y)+math.pi

def reset_cam():
    bpy.context.scene.camera.location.x = -20
    bpy.context.scene.camera.location.y = 0
    bpy.context.scene.camera.location.z = 10

    bpy.context.scene.camera.rotation_euler.x = 1.4
    bpy.context.scene.camera.rotation_euler.y = 0
    bpy.context.scene.camera.rotation_euler.z = -math.pi/2

def set_background():
    index = random.randint(1, len(bpy.data.images)-1)
    world = bpy.context.scene.world
    world.active_texture.image = bpy.data.images['background'+str(index)+'.jpg']

def main():
    import_backgrounds()

    for a in range(100):
        for i in range(count):
            reset_cam()
            rotate_cam(random.random()*math.pi*2)

            objects = bpy.context.visible_objects

            for obj in objects:
                if obj.type != 'CAMERA' and obj.type != 'LAMP':
                    obj.select = True
                    bpy.ops.object.delete()

            set_background()
            import_object('object'+str(i))

            bpy.context.scene.render.filepath = 'C:\\Users\\Julian\\Desktop\\set\\output\\'+str(a)+'-'+str(i)+'_0.png'
            bpy.ops.render.render(write_still=True)

            rand = random.random()*math.pi/4
            rotate_cam(rand)
            bpy.context.scene.render.filepath = 'C:\\Users\\Julian\\Desktop\\set\\output\\'+str(a)+'-'+str(i)+'_'+str(rand)+'.png'
            bpy.ops.render.render(write_still=True)

main()


#Importations And Value Table Creation#
from random import randint

bot_field = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

player_field = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

bot_sonar = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

player_sonar = [["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
                ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
                ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
                ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
                ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
                ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
                ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
                ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
                ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
                ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"]]

def printField(A): #Special print command for outputting the above arrays.
    if str.lower(A) == "a":
        print("\n---Players Ships---")
        for i in range(10):
            for j in range(10):
                print(player_field[i][j], "", end = "")
            print()
    if str.lower(A) == "b":
        print("\n---Players Ships--------Tracer Field---")
        for i in range(10):
            for j in range(10):
                print(player_field[i][j], "", end = "")
            for k in range(10):
                print(player_sonar[i][k], "", end = "")
            print()
    print()

def emptyShips(A): #Self check command which helps determine when the game ends.
    isEmpty = True
    for i in range(5):
        if A == "a":
            if bot_ships[i] != 0:
                isEmpty = False
        if A == "b":
            if player_ships[i] != 0:
                isEmpty = False
    return isEmpty

def hasHit(A): #Checks if a given ship has been hit before.
    hasHit = False
    if A == 1:
        if player_ships[0] < 2:
            hasHit = True;
    elif A == 2:
        if player_ships[1] < 3:
            hasHit = True;
    elif A == 3:
        if player_ships[2] < 3:
            hasHit = True;
    elif A == 4:
        if player_ships[3] < 4:
            hasHit = True;
    elif A == 5:
        if player_ships[4] < 5:
            hasHit = True;
    return hasHit

bot_ships = [2, 3, 3, 4, 5] #Number of units left for each of the bots ships.
player_ships = [2, 3, 3, 4, 5] #Number of units left for each of the players ships.
ship_names = ["Destroyer", "Submarine", "Cruiser", "Battleship", "Aircraft Carrier"] #Names for ship referencing.
#End#
#Bot Ship Placement#
i = 0
while i < 5:
    x = randint(0,9)#X-Location
    y = randint(0,9)#Y-Location
    z = randint(0,1)#Is Vertical?
    if z == 1:
        if y + bot_ships[i] <= 9:#Checks if there is enough horizontal space.
            checkVerified = True
            for j in range(bot_ships[i]):#Checks if any other ships are present.
                if bot_field[y + j][x] != 0:
                    checkVerified = False
            if checkVerified == True:#Places current ship and increments i only if all previous checks were successful.
                for j in range(bot_ships[i]):
                    bot_field[y + j][x] = i + 1
                i += 1
    if z == 0:
        if x + bot_ships[i] <= 9:#Checks if there is enough vertical space.
            checkVerified = True
            for j in range(bot_ships[i]):#Checks if any other ships are present.
                if bot_field[y][x + j] != 0:
                    checkVerified = False
            if checkVerified == True:#Places current ship and increments i only if all previous checks were successful.
                for j in range(bot_ships[i]):
                    bot_field[y][x + j] = i + 1
                i += 1
#End#
#Player Ship Placement#
i = 0
for i in range(5):
    suc = False
    if i == 0:
        print("You may now begin placing your ships. Ships are placed onto your map using coordinates.")
        print("Remember, your coordinate plane is in the 4th quadrant. That means that your Y-Coordinate")
        print("increases as you go down on the plane, not up.\n")
    while suc == False:
        suc = True
        print("You may now place your", ship_names[i], "which is", player_ships[i], "units long.\n")
        try:
            x = int(input("Please choose your X-Coordinate (1 - 10): ")) - 1
            if x < 0:
                print("Error: You attempted to place a ship using a negative number. This would potentially result in boat wrapping and is not allowed.")
                suc = False
                continue
        except ValueError:
            print("Error: You entered something that was not an acceptable value. Integers only please.")
            suc = False
            continue
        try:
            y = int(input("Please choose your Y-Coordinate (1 - 10): ")) - 1
            if y < 0:
                print("Error: You attempted to place a ship using a negative number. This would potentially result in boat wrapping and is not allowed.")
                suc = False
                continue
        except ValueError:
            print("Error: You entered something that was not an acceptable value. Integers only please.")
            suc = False
            continue
        try:
            z = int(input("Are you placing horizontally(0) or vertically (1)?"))
            if z < 0 or z > 1:
                suc = False
                print("Error: You attempted to place a ship in the 3rd or higher dimension. This is a two dimensional game, please select one of the two.")
                continue
        except ValueError:
            print("Error: You entered something that was not an acceptable value. Integers only please.")
            suc = False
            continue
        if z == 1:
            succ = True
            for j in range(player_ships[i]):#Checks if any other ships are present.
                if suc == False:
                    continue
                try:
                    if player_field[y + j][x] != 0:
                        print("Error: You attempted to place a ship on top of an existing ship. Please choose another spot.")
                        succ = False
                        suc = False
                except IndexError:
                    print("Error: You attempted to place a ship outside of the arena bounds.")
                    suc = False
                    succ = False
            if succ == True:
                    for j in range(player_ships[i]):
                        player_field[y + j][x] = i + 1
        if z == 0:
            succ = True
            for j in range(player_ships[i]):#Checks if any other ships are present.
                if suc == False:
                    continue
                try:
                    if player_field[y][x + j] != 0:
                        print("Error: You attempted to place a ship on top of an existing ship. Please choose another spot.")
                        succ = False
                        suc = False
                except IndexError:
                    print("Error: You attempted to place a ship outside of the arena bounds.")
                    suc = False
                    succ = False
            if succ == True:
                for j in range(player_ships[i]):
                    player_field[y][x + j] = i + 1
    if i != 4:
        printField("a")
#End#
#Begin Gameplay#
gameOver = False #Boolean that triggers a game-over
playerWins = False #Boolean used to determine whether or not the player has won the game.
playerTurn = True #Boolean value that tells the if-loops whose turn it is.
#Bot Values#
originalShot = [0, 0] #Integer array value that tells the bot where it first hit the current ship. Used by targeting swapper.
previousShot = [0, 0] #Integer array value that tells the bot where it last shot.
firingMode = 0 #Tells the bot the current firing behavior to follow.
attack_origin = [[0, 0, 0, 0]] #Intended to keep track of ships currently being attacked with the format of [x-location, y-location, firing-mode, ship-id]
is_hitting = 0 #Used by the bot to keep track of the ship it's currently hitting. If this value changes outside of mode 0 then the previous array should log the ship.
modes_used = [0] #Keeps track of the firing modes used on the current ship.
ship_just_finished = False #Toggles true when a ship is killed. Used to toggle attack_origin override.
#End Bot Values#
while gameOver == False:
    #Begin Player Turn#
    if playerTurn == True:
        printField("b")
        print("It is now your turn.\n")
        try:
            x = int(input("Choose the X-Coordinate (1 - 10) for your shot: ")) - 1
            y = int(input("Choose the Y-Coordinate (1 - 10) for your shot: ")) - 1
        except ValueError:
            print("\nError: You entered something that was not an acceptable value. Integers only please.")
            continue
        if (x < 0 or x > 9) or (y < 0 or y > 9):
            print("\nError: You attempted to fire a shot outside of the arena bounds.")
            continue
        if bot_field[y][x] != 0: #If a ship was hit...
            player_sonar[y][x] = "X" #Update the players Hit Map
            print("\nYou hit the bots", ship_names[bot_field[y][x] - 1] + ".") #Informs the player which ship was hit.
            bot_ships[bot_field[y][x] - 1] -= 1 #Update the ship ledger.
            if bot_ships[bot_field[y][x] - 1] == 0: #Check if the ship was destroyed.
                print("\nYou have destroyed the bots", ship_names[bot_field[y][x] - 1] + ".")
            if emptyShips("a") == True: #Check if all of the bots ships have been destroyed and ends the game if they have.
                gameOver = True
                playerWins = True
            bot_field[y][x] = 0 #Update the bots map.
            playerTurn = False
            continue
        else:
            player_sonar[y][x] = "O"
            print("\nYour shot missed.")
            playerTurn = False
            continue
    #End#

    #Add handling for issue: Attacks multiple ships, adding them to the array but in the process of killing the primary ship, a non primary ship is destroyed, but not removed from array.

    #Begin bot turn#
    if playerTurn == False:
        #Firing mode 0 - Shoots randomly until ship is found. Values will be overridden if the bot is in a firing mode.
        x = randint(0, 9)
        y = randint(0, 9)
        #################
        if ship_just_finished == True & attack_origin[0][3] != 0: #If this shot is occurring immediately after a ship has been destroyed AND another ship had been found...
            x = attack_origin[0][0] #Override X Value
            y = attack_origin[0][1] #Override Y Value
            modes_used.append(attack_origin[0][2]) #Inform bot that this firing mode was already used.
            while firingMode in modes_used: #Set new random firing mode.
                firingMode = randint(1, 4)
            is_hitting = attack_origin[0][3] #Override ship recognition value.
            originalShot = [y, x] #Override found ship condition values.
            previousShot = [y, x]
            ship_just_finished = False
        else:
            ship_just_finished = False
        if firingMode == 1:#Fires Up
            x = previousShot[1]
            y = previousShot[0] - 1
            previousShot = [y, x]
        if firingMode == 2:#Fires Down
            x = previousShot[1]
            y = previousShot[0] + 1
            previousShot = [y, x]
        if firingMode == 3:#Fires Left
            x = previousShot[1] - 1
            y = previousShot[0]
            previousShot = [y, x]
        if firingMode == 4:#Fires Right
            x = previousShot[1] + 1
            y = previousShot[0]
            previousShot = [y, x]
        if (x < 0 or x > 9) or (y < 0 or y > 9):#If shot is impossible, change firing mode.
            while firingMode in modes_used: #Set new random firing mode.
                firingMode = randint(1, 4)
            previousShot = originalShot #Refresh value for the modes above to use.
            continue
        if firingMode != 0 and firingMode not in modes_used: #If modes_used does not contain the current firing mode, add it.
            modes_used.append(firingMode)
        if bot_sonar[y][x] == 0: #If the bot hasn't shot here before...
            if firingMode == 0: #and this is a whole new ship...
                originalShot = [y, x]
                previousShot = [y, x]
            bot_sonar[y][x] = 1 #Register shot.
            if player_field[y][x] != 0: #If the shot hit...
                if is_hitting != player_field[y][x]: #If hitting a new ship...
                    if attack_origin[0][3] == 0 and hasHit(player_field[y][x]) == False: #Note the new ships location and mode the bot was in at the time.
                        attack_origin[0][0] = x
                        attack_origin[0][1] = y
                        attack_origin[0][2] = firingMode
                        attack_origin[0][3] = player_field[y][x]
                    elif hasHit(player_field[y][x]) == False: #Appends array if it isn't empty.
                        attack_origin.append([x, y, firingMode, player_field[y][x]])
                is_hitting = player_field[y][x]
                print("\nThe bot fired at ", x + 1,", ", y + 1, " and hit your ", ship_names[player_field[y][x] - 1], ".", sep = "")#Inform the player.
                player_ships[player_field[y][x] - 1] -= 1 #Update the ship ledger.
                if firingMode == 0: #Update the firing mode.
                    while firingMode in modes_used: #This allows this loop to start. Loop continues while the firing mode has been used before.

                        firingMode = randint(1, 4) #Note: randint is range inclusive.
                if player_ships[player_field[y][x] - 1] == 0: #Check if the ship was destroyed
                    print("\nThe bot has destroyed your", ship_names[player_field[y][x] - 1] + ".\n")
                    firingMode = 0 #Resets firing mode to 0 to start a new search.
                    modes_used = [0]
                    is_hitting = 0
                    if len(attack_origin) > 1: #The current ship is removed, and the next ship moves up.
                        del attack_origin[0]
                    elif len(attack_origin) == 1: #If this was the last ship...
                        attack_origin = [[0, 0, 0, 0]] #Reset the array.
                    ship_just_finished = True
                if emptyShips("b") == True: #Check if all of the players ships have been destroyed.
                    gameOver = True #If they have, then end the game.
                player_field[y][x] = 0 #Update the players map. Note: The official map is updated last so all previous statements have the necessary information to function without having to hold an extra value.
                playerTurn = True #Informs the turn toggler that it is now the players turn.
            else: #If the bot missed, then change the firing mode.
                print("\nThe bot fired at ", x + 1,", ", y + 1, " and missed.", sep = "")
                playerTurn = True #Informs the swapper that it is now the players turn.
                if firingMode != 0: #If the bot is already tracking a ship, then migrate to the next mode.
                    while firingMode in modes_used:
                        firingMode = randint(1, 4)
                    previousShot = originalShot #Resets previousShot values for new firing mode to use.
        else: #If the bot has shot there before, shoot the next spot. The mode shouldn't change here since it is possible for a ship to still be here even if the bot has shot here before.
            continue
    #End
#End
if playerWins == True:
    print("\nGame Over: The Player Wins")
else:
    print("\nGame Over: The Bot Wins")
input("\nPress enter to close.")#In terminal the program would close automatically, making the game over section un-readable.
exit()#The exit command will make the close out work in IDLE.


import streamlit as st
import cv2
import os
from my_utils import alignment_procedure
from mtcnn import MTCNN
import glob
import ArcFace
import numpy as np
import keras
from keras import layers, Sequential
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import pandas as pd
import tensorflow as tf
from keras.models import load_model

st.title('Face Recognition System')
os.makedirs('data', exist_ok=True)
name_list = os.listdir('data')

# Data Collection
# st.sidebar.title('Data Collection')
webcam_channel = st.sidebar.selectbox(
    'Webcam Channel:',
    ('Select Channel', '0', '1', '2', '3')
)
name_person = st.text_input('Name of the Person:')
img_number = st.number_input('Number of Images:', 50)
FRAME_WINDOW = st.image([])

if not webcam_channel == 'Select Channel':
    take_img = st.button('Take Images')
    if take_img:
        if len(name_list) != 0:
            for i in name_list:
                if i == name_person:
                    st.warning('The Name is Already Exist!!')
                    break
        os.mkdir(f'data/{name_person}')
        st.success(f'{name_person} added Successfully')

        if len(os.listdir(f'data/{name_person}')) == 0:
            face_classifier = cv2.CascadeClassifier(
                'haarcascade_frontalface_default.xml')
            cap = cv2.VideoCapture(int(webcam_channel))
            count = 0
            while True:
                success, img = cap.read()
                if not success:
                    st.error('[INFO] Cam NOT working!!')
                    break

                # Save Image
                cv2.imwrite(f'data/{name_person}/{count}.jpg', img)
                st.success(f'[INFO] Successfully Saved {count}.jpg')
                count += 1

                faces = face_classifier.detectMultiScale(img)
                for (x, y, w, h) in faces:
                    cv2.rectangle(
                        img, (x, y), (x+w, y+h),
                        (0, 255, 0), 2
                    )

                FRAME_WINDOW.image(img, channels='BGR')
                if count == img_number:
                    st.success(f'[INFO] Collected {img_number} Images')
                    break

            FRAME_WINDOW.image([])
            cap.release()
            cv2.destroyAllWindows()

else:
    st.warning('[INFO] Select Camera Channel')

# 2nd Stage - Normalize Image Data
st.sidebar.title('Normalize Image Data')
if st.sidebar.button('Normalize'):
    path_to_dir = "data"
    path_to_save = 'norm_data'

    Flage = True
    detector = MTCNN()

    class_list_update = []
    if os.path.exists(path_to_save):
        class_list_save = os.listdir(path_to_save)
        class_list_dir = os.listdir(path_to_dir)
        class_list_update = list(set(class_list_dir) ^ set(class_list_save))
    else:
        os.makedirs(path_to_save)

    if len(class_list_update) == 0:
        if (set(class_list_dir) == set(class_list_save)):
            Flage = False
        else:
            class_list = os.listdir(path_to_dir)
    else:
        class_list = class_list_update

    if Flage:
        class_list = sorted(class_list)
        for name in class_list:
            st.success(f"[INFO] Class '{name}' Started Normalising")
            img_list = glob.glob(os.path.join(path_to_dir, name) + '/*')

            # Create Save Folder
            save_folder = os.path.join(path_to_save, name)
            os.makedirs(save_folder, exist_ok=True)

            for img_path in img_list:
                img = cv2.imread(img_path)

                detections = detector.detect_faces(img)

                if len(detections) > 0:
                    right_eye = detections[0]['keypoints']['right_eye']
                    left_eye = detections[0]['keypoints']['left_eye']
                    bbox = detections[0]['box']
                    norm_img_roi = alignment_procedure(
                        img, left_eye, right_eye, bbox)

                    # Save Norm ROI
                    cv2.imwrite(
                        f'{save_folder}/{os.path.split(img_path)[1]}', norm_img_roi)
                    # st.success(f'[INFO] Successfully Normalised {img_path}')

                else:
                    st.warning(f'[INFO] Not detected Eyes in {img_path}')

            st.success(
                f"[INFO] All Normalised Images from '{name}' Saved in '{path_to_save}'")
        st.success(
            f'[INFO] Successfully Normalised All Images from {len(os.listdir(path_to_dir))} Classes\n')

    else:
        st.warning('[INFO] Already Normalized All Data..')

# 3rd Stage - Train Model
st.sidebar.title('Train Model')
if st.sidebar.button('Train Model'):
    path_to_dir = "norm_data"
    path_to_save = 'model.h5'

    # Load ArcFace Model
    model = ArcFace.loadModel()
    target_size = model.layers[0].input_shape[0][1:3]

    # Variable for store img Embedding
    x = []
    y = []

    names = os.listdir(path_to_dir)
    names = sorted(names)
    class_number = len(names)

    for name in names:
        img_list = glob.glob(os.path.join(path_to_dir, name) + '/*')
        img_list = sorted(img_list)
        st.success(f'[INFO] Started Embedding {name} Class')

        for img_path in img_list:
            img = cv2.imread(img_path)
            img_resize = cv2.resize(img, target_size)
            # what this line doing? must?
            img_pixels = tf.keras.preprocessing.image.img_to_array(img_resize)
            img_pixels = np.expand_dims(img_pixels, axis=0)
            img_norm = img_pixels/255  # normalize input in [0, 1]
            img_embedding = model.predict(img_norm)[0]

            x.append(img_embedding)
            y.append(name)

        st.success(f'[INFO] Completed Embedding {name} Class')
    st.success('[INFO] All Image Data Embedding Completed...')

    # Model Training
    # DataFrame
    df = pd.DataFrame(x, columns=np.arange(512))
    df['names'] = y

    x = df.copy()
    y = x.pop('names')
    y, _ = y.factorize()
    x = x.astype('float64')
    y = keras.utils.to_categorical(y)

    # Train Deep Neural Network
    x_train, x_test, y_train, y_test = train_test_split(x, y,
                                                        test_size=0.2,
                                                        random_state=0)

    model = Sequential([
        layers.Dense(1024, activation='relu', input_shape=[512]),
        layers.Dense(512, activation='relu'),
        layers.Dense(class_number, activation="softmax")
    ])

    model.compile(
        optimizer='adam',
        loss='categorical_crossentropy',
        metrics=['accuracy']
    )

    # Add a checkpoint callback to store the checkpoint that has the highest
    # validation accuracy.
    checkpoint_path = path_to_save
    checkpoint = keras.callbacks.ModelCheckpoint(checkpoint_path,
                                                 monitor='val_accuracy',
                                                 verbose=1,
                                                 save_best_only=True,
                                                 mode='max')
    earlystopping = keras.callbacks.EarlyStopping(monitor='val_accuracy',
                                                  patience=20)

    st.success('[INFO] Model Training Started ...')
    # Start training
    history = model.fit(x_train, y_train,
                        epochs=200,
                        batch_size=16,
                        validation_data=(x_test, y_test),
                        callbacks=[checkpoint, earlystopping])

    st.success('[INFO] Model Training Completed')
    st.success(f'[INFO] Model Successfully Saved in ./{path_to_save}')

    # Plot History
    metric_loss = history.history['loss']
    metric_val_loss = history.history['val_loss']
    metric_accuracy = history.history['accuracy']
    metric_val_accuracy = history.history['val_accuracy']

    # Construct a range object which will be used as x-axis (horizontal plane) of the graph.
    epochs = range(len(metric_loss))

    # Plot the Graph.
    plt.plot(epochs, metric_loss, 'blue', label=metric_loss)
    plt.plot(epochs, metric_val_loss, 'red', label=metric_val_loss)
    plt.plot(epochs, metric_accuracy, 'blue', label=metric_accuracy)
    plt.plot(epochs, metric_val_accuracy, 'green', label=metric_val_accuracy)

    # Add title to the plot.
    plt.title(str('Model Metrics'))

    # Add legend to the plot.
    plt.legend(['loss', 'val_loss', 'accuracy', 'val_accuracy'])

    # If the plot already exist, remove
    plot_png = os.path.exists('metrics.png')
    if plot_png:
        os.remove('metrics.png')
        plt.savefig('metrics.png', bbox_inches='tight')
    else:
        plt.savefig('metrics.png', bbox_inches='tight')
    st.success('[INFO] Successfully Saved metrics.png')

# 4th Stage - Inference
st.sidebar.title('Inference')
# Confidence
threshold = st.sidebar.slider('Model Confidence:', 0.01, 0.99, 0.6)

if st.sidebar.button('Run/Stop'):
    class_names = os.listdir('data')
    class_names = sorted(class_names)

    if not webcam_channel == 'Select Channel':
        path_saved_model = "model.h5"
        cap = cv2.VideoCapture(int(webcam_channel))
        # Load MTCNN
        detector = MTCNN()
        arcface_model = ArcFace.loadModel()
        target_size = arcface_model.layers[0].input_shape[0][1:3]
        # Load saved FaceRecognition Model
        face_rec_model = load_model(path_saved_model, compile=True)

        while True:
            success, img = cap.read()
            if not success:
                st.warning('[INFO] Error with Camera')
                break

            detections = detector.detect_faces(img)
            if len(detections) > 0:
                for detect in detections:
                    right_eye = detect['keypoints']['right_eye']
                    left_eye = detect['keypoints']['left_eye']
                    bbox = detect['box']
                    xmin, ymin, xmax, ymax = int(bbox[0]), int(bbox[1]), \
                        int(bbox[2]+bbox[0]), int(bbox[3]+bbox[1])
                    norm_img_roi = alignment_procedure(
                        img, left_eye, right_eye, bbox)

                    img_resize = cv2.resize(norm_img_roi, target_size)
                    # what this line doing? must?
                    img_pixels = tf.keras.preprocessing.image.img_to_array(img_resize)
                    img_pixels = np.expand_dims(img_pixels, axis=0)
                    img_norm = img_pixels/255  # normalize input in [0, 1]
                    img_embedding = arcface_model.predict(img_norm)[0]

                    data = pd.DataFrame(
                        [img_embedding], columns=np.arange(512))

                    predict = face_rec_model.predict(data)[0]
                    # print(predict)
                    if max(predict) > threshold:
                        pose_class = class_names[predict.argmax()]
                    else:
                        pose_class = 'Unkown Person'

                    # Show Result
                    cv2.rectangle(
                        img, (xmin, ymin), (xmax, ymax),
                        (0, 255, 0), 2
                    )
                    cv2.putText(
                        img, f'{pose_class}',
                        (xmin, ymin-10), cv2.FONT_HERSHEY_PLAIN,
                        2, (255, 0, 255), 2
                    )

            else:
                st.warning('[INFO] Eyes Not Detected!!')

            FRAME_WINDOW.image(img, channels='BGR')

        FRAME_WINDOW.image([])
        st.success('[INFO] Inference on Videostream is Ended...')

    else:
        st.warning('[INFO] Select Camera Channel')


from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from datetime import datetime, timedelta

def generate_selfsign(hostname):

    passphrase = b"passphrase"
    #Generate our key
    key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048)

    #生成私钥
    key_pem = key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption(passphrase),
    )

    #自签发证书

    name = x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME,hostname),
    ])

    now = datetime.utcnow()

    #path_length=0证明是自签发证书
    basic_contraints = x509.BasicConstraints(ca=True, path_length=0)

    cert=x509.CertificateBuilder().subject_name(
        name).issuer_name(
            name
        ).public_key(
            key.public_key()
        ).serial_number(
            x509.random_serial_number()
        ).not_valid_before(
            now
        ).not_valid_after(
            now+datetime.timedelta(days=10) #10天有效期
        ).add_extension(
            x509.SubjectAlternativeName([x509.DNSName(hostname)]),
            critical=False
        ).add_extension(
            basic_contraints,False
        ).sign(key,hashes.SHA256())

    #证书
    cert_pem = cert.public_bytes(encoding=serialization.Encoding.PEM)

    return cert_pem,key_pem


# Some magic for Python3
try:
  import SocketServer as socketserver
except ImportError:
  import socketserver

import logging
import sys
import threading

class ATCommandUDPHandler(socketserver.BaseRequestHandler):
  def command(self, cmd):
    logging.info('Got command: %s' % (cmd,))

  def handle(self):
    commands = self.request[0].strip().split('\n')
    socket = self.request[1]

    logging.info('%s -> %s' % (self.client_address, repr(commands)))
    for command in commands:
      self.command(command)

class ATCommandListener(threading.Thread):
  def __init__(self):
    super(ATCommandListener, self).__init__()

    self.should_quit = False
    self.cv = threading.Condition()

    (bind_host, bind_port) = '127.0.0.1', 5556
    self._server = socketserver.UDPServer((bind_host, bind_port),
        ATCommandUDPHandler)

  def run(self):
    self._server.serve_forever()

def serve():
  # Create an AT command listener
  at_listener = ATCommandListener()
  at_listener.daemon = True
  at_listener.start()

  # Wait for the quit command
  at_listener.cv.acquire()
  while not at_listener.should_quit:
    at_listener.cv.wait(0.5)
  at_listener.cv.release()

if __name__ == '__main__':
  logging.basicConfig(level=logging.INFO)
  serve()


"""Script to send emails for collecting coke money"""

import argparse
import csv
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from getpass import getpass
import smtplib

# csv fields
NAME = "Name"
EMAIL = "Email"
BALANCE = "Current balance"
UNKNOWN = "???"

# czar info
CZAR_USERNAME = "sacm.coke.czar"
CZAR_EMAIL = "{0}@gmail.com".format(CZAR_USERNAME)
# change these to match your details
CZAR_NAME = "Akshay Sood"
CZAR_OFFICE = "MSC 4715"
CZAR_MAILROOM = "MSC 4730"

# email body
SUBJECT = "MSC Coke Balance"
CLOSE_ACCOUNT = "If you would like to close your account (and stop receiving these emails), reply and let me know."
PAYMENT_DETAILS = ("Cash payments can be brought to my office ({0}). Please be sure to indicate your name in case "
                   "you're not handing over the payment personally. Alternatively, checks can be left in my mailbox "
                   "in {1}. Checks should be written to SACM. I cannot provide change for cash payments, "
                   "but I can carry over any excess payment as a system credit.".format(CZAR_OFFICE, CZAR_MAILROOM))
ONLINE_PAYMENT = ("\n\nIf you prefer, you may also pay online via:\nPaypal: {0}\nVenmo: {1}"
                  "\nGoogle Pay: {2}\nUWCU Moneylink: Upon request")
THANKS = "Thank you, and please let me know if you believe I've made any error.\n\n- {0}, MSC Coke Czar".format(CZAR_NAME)
DEADLINE = "two weeks"
SUCCESSOR_ADVERTISEMENT = ("P.S.: the time has come for me to pass on the envied title of Coke Head to another. "
                           "If you're a graduate student in the Computer Sciences department with an office in MSC, "
                           "here are some reasons you might consider taking the position:\n\n"
                           "1. Refer to yourself either as the Coke Head or Coke Czar depending on whether or not "
                           "you are talking with someone who appreciates drug-related humor!\n"
                           "2. You'll have total, uncontested control over what is ordered and when. Want the whole "
                           "fridge packed with Sprite and nothing but Sprite? Your wish is everyone else's "
                           "begruding acceptance! (So please don't do that.)\n"
                           "3. If you can figure out the logistics involved in the cans being different sizes and "
                           "costing more than regular cans, you could be the hero who brings energy drinks to the "
                           "MSC Coke fridge!\n"
                           "4. Stocking cans is even more fun than whitewashing Tom Sawyer's fence!\n"
                           "5. Very low rate of mutiny.\n"
                           "6. Embezzlement opportunities?\n"
                           "7. Someone's gotta.\n\n"
                           "If you meet the criteria and would like to hold this honor and bear this burden, "
                           "let me know you're interested. If nobody is, someone will be drafted or something. "
                           "The Coke-brand soft drinks must flow!")

def main():
    """Main"""
    parser = argparse.ArgumentParser()
    parser.add_argument("balance_filename", help="file containing balances")
    parser.add_argument("-high_balance_only", help="only send emails to folks with high balance (debt)",
                        action="store_true")
    parser.add_argument("-advertise_successor", action="store_true")
    parser.add_argument("-print_only", help="print emailing summary but don't actually send emails",
                        action="store_true")
    args = parser.parse_args()

    server = setup()
    paypal_email = input("Enter receiving Paypal email: ")
    venmo_id = input("Enter receiving Venmo id: ")
    googlepay_email = input("Enter receiving Google Pay email: ")
    payment_details = PAYMENT_DETAILS + ONLINE_PAYMENT.format(paypal_email, venmo_id, googlepay_email)

    with open(args.balance_filename, "r") as balance_file:
        reader = csv.DictReader(balance_file)
        for row in reader:
            name, destination_email, amount = (row[key] for key in [NAME, EMAIL, BALANCE])
            if not destination_email or not name or name == "???":
                continue
            amount = float(amount.replace("$", ""))
            body = "Hi {0},\n\n".format(name)
            if args.high_balance_only and amount < 5.00:
                continue
            if amount < 0.00:
                # system credit
                body += ("You have a credit of ${0:.2f} for MSC Coke (you do not owe anything).\n\n{1}\n\n{2}"
                         .format(-amount, CLOSE_ACCOUNT, THANKS))
            elif amount == 0.00:
                # zero balance
                body += "Your MSC Coke balance is $0.00 (you do not owe anything).\n\n{0}\n\n{1}".format(CLOSE_ACCOUNT, THANKS)
            elif amount < 5.00:
                # low charge, can pay later
                body += ("You owe ${0:.2f} for your MSC Coke. Because your balance is small, you may wait to pay "
                         "until the next collection if you prefer.\n\n{1}\n\n{2}".format(amount, payment_details, THANKS))
            else:
                # please pay soon
                body += ("You owe ${0:.2f} for your MSC Coke. Please make your payment in {3}.\n\n{1}\n\n{2}"
                         .format(amount, payment_details, THANKS, DEADLINE))
            if args.advertise_successor:
                body += "\n\n\n\n{0}".format(SUCCESSOR_ADVERTISEMENT)

            print("Mailing {0} at {1}...".format(name, destination_email))
            if not args.print_only:
                send_email(server, destination_email, SUBJECT, body)

def setup():
    """Email Setup"""
    server = smtplib.SMTP("smtp.gmail.com", 587)
    server.ehlo()
    server.starttls()
    server.ehlo()
    server.login(CZAR_USERNAME, getpass("Enter password for {0}:".format(CZAR_EMAIL)))
    return server

def send_email(server, destination_email, subject, body):
    """Sends email"""
    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg.attach(MIMEText(body, 'plain'))
    text = msg.as_string()

    server.sendmail(CZAR_EMAIL, destination_email, text)

if __name__ == "__main__":
    main()


import os
from werkzeug.utils import secure_filename
import requests
from flask import Flask, request
from flask_cors import CORS

app = Flask(__name__)
CORS(app)
# uploads_dir = '/home/vest1/Desktop/multi-01-starting-setup/backend/data'
uploads_dir='/app/data'

# post both files at once
# files saved into the data directory
@app.route('/upload', methods=['POST'])
def upload_files():
    if request.method == 'POST':
        f1 = request.files['file1']
        f2 = request.files['file2']
        f1.save(os.path.join(uploads_dir, secure_filename(f1.filename)))
        f2.save(os.path.join(uploads_dir, secure_filename(f2.filename)))
        return 'file uploaded successfully\n'

@app.route('/checksum', methods=['GET'])
def determine_file_similarity():
    if request.method == 'GET':
        f1 = request.args.get('f1')
        f2 = request.args.get('f2')
        payload = {'f1': f1, 'f2': f2}
        response = requests.get("http://checksum:5001", params=payload)
        return response.json()

if __name__ == '__main__':
    app.run(debug=True, port=5555)


import sys
from collections import deque
input = sys.stdin.readline

n, m = map(int, input().split())
graph = []

for i in range(n):
    graph.append(list(map(int, input().strip('\n'))))

visited = [[0 for j in range(m)] for i in range(n)]
d = [[1, 0], [-1, 0], [0, 1], [0, -1]]

q = deque([[0, 0]])
visited[0][0] = 1

while q:

    x, y = map(int, q.popleft())

    for i in range(len(d)):

        dx = x + d[i][0]
        dy = y + d[i][1]

        if dx < 0 or dy < 0 or dx >= n or dy >= m:
            continue

        if visited[dx][dy] >= 1:
            continue

        if graph[dx][dy] == 1:
            visited[dx][dy] = visited[x][y] + 1
            q.append([dx, dy])

print(visited[n-1][m-1])


import tkinter as tk
import tkinter.ttk as ttk
import guiLibs.newSearch as newSearch
import guiLibs.newCards as newCards
import guiLibs.DecksAndLevels as DecksAndLevels

class DAndLgui(tk.Frame):
	def __init__(self, master, controller):
		tk.Frame.__init__(self, master)
		self.frames = {}
		self.controller = controller
		self.bind("<<ShowFrame>>", self.on_show_frame)
		container = tk.Frame(self)
		container.grid()
		container.grid_rowconfigure(0, weight=1)
		container.grid_columnconfigure(0, weight=1)

		for F in (DecksAndLevels.DecksAndLevels, newSearch.newSearch, newCards.newCards):
			page_name = F.__name__
			frame = F(container, self)
			self.frames[page_name] = frame

			# put all of the pages in the same location;
			# the one on the top of the stacking order
			# will be the one that is visible.
			frame.grid(row=0, column=0, sticky="nsew")

	def show_frame(self, page_name, me = None, *args):
		'''Show a frame for the given page name'''
		if me:
			for widget in me.winfo_children():
				widget.destroy()
		if len(args):
			self.deck = args[0]
		frame = self.frames[page_name]
		frame.tkraise()
		frame.event_generate("<<ShowFrame>>")

	def on_show_frame(self, event):
		self.show_frame("DecksAndLevels")


import time

start_time = int(round(time.time() * 1000))

# Input nonsense
f = open("input.txt", "r")
input_str = f.read().split("\n")

# Fun logic
def traverse(dx, dy):
    count = 0

    x = 0
    y = 0
    WIDTH = len(input_str[0])
    HEIGHT = len(input_str) - 1

    while y < HEIGHT:
        check = input_str[y][x]
        if check == '#':
            count += 1

        x += dx
        if x >= WIDTH:
            x -= WIDTH
        y += dy

    print(count)
    return count

a = traverse(1, 1)
b = traverse(3, 1)
c = traverse(5, 1)
d = traverse(7, 1)
e = traverse(1, 2)

print(a * b * c * d * e)

end_time = int(round(time.time() * 1000))

print(f"Time: {end_time - start_time} ms")


def palindrome(x):
    a = list(map(int, str(x)))
    b = a.copy()
    a.reverse()
    if (a == b):
        return True
    else:
        return False
print('Введите число, чтобы проверить, является ли оно палиндромом')
val = input()
res = palindrome(val)
print(res)