#!/usr/bin/python
from enum import Enum
import re
import argparse
import sys

class MatchedLineFormat(Enum):
    """Defines different formatting formats for printing pattern matching lines in files"""
    DEFAULT = 1
    UNDERSCORE = 2
    COLOR = 3
    MACHINE = 4

class MatchedLineFormatterFactory:
    """As the pattern matching lines can be presented in 4 different formats (default, underscored,
    colored and machine readable), we will use the factory pattern to instantiate a corresponding
    MatchedLineFormatter for each one.

    Note: this class is an adaptation of the example explained here:
    https://realpython.com/factory-method-python/#supporting-additional-formats
    """

    def __init__(self):
        self._formatters = {}

    def register_format(self, matched_line_format, formatter):
        """Registers a MatchingLineFormatter class for a MatchedLineFormat """
        self._formatters[matched_line_format] = formatter

    def get_formatter(self, matched_line_format):
        """Obtains a MatchingLineFormatter object for a MatchedLineFormat, or an error if not supported """
        formatter = self._formatters.get(matched_line_format)
        if not formatter:
            raise ValueError(matched_line_format)
        return formatter()

class DefaultMatchedLineFormatter:
    """Formats the information related to pattern matched lines in a file using the Default format
    (see details in the format method)
    """

    # noinspection PyMethodMayBeStatic
    def format(self, filename, line_number, line, pattern_match_intervals):
        """
        Returns a string containing the information provided by the input parameters (related to pattern matched
        lines in a file) using this formatting:

        filename:line_number:line

        In case of having multiple matches in the same line the resulting string will have just one line
        for all occurrences, as all are in the same line_number.

        :param filename: Filename of the file being parsed
        :param line_number: Line number
        :param line: String containing the actual line of the file being processed
        :param pattern_match_intervals: Set of tuples (start, end) where the pattern has been found in the line
        :return: Formatted string
        """

        formatted_line = filename + ":" + str(line_number) + ":" + line

        return formatted_line.strip()

class ColorMatchedLineFormatter:
    """Formats the information related to pattern matched lines in a file coloring the matching text
    (see details in the format method)
    """

    CHAR_FORMAT_START_PURPLE = '\033[95m'
    CHAR_FORMAT_END = '\033[0m'

    # noinspection PyMethodMayBeStatic
    def format(self, filename, line_number, line, pattern_match_intervals):
        """
           Returns a string containing the information provided by the input parameters (related to pattern matched
           lines in a file) using this formatting:

           filename:line_number:line (coloring the matching text)

           :param filename: Filename of the file being parsed
           :param line_number: Line number
           :param line: String containing the actual line of the file being processed
           :param pattern_match_intervals: Set of tuples (start, end) where the pattern has been found in the line
           :return: Formatted string
        """

        formatted_line = filename + ":" + str(line_number) + ":"

        last_match_end = 0
        for interval in pattern_match_intervals:
            formatted_line += line[last_match_end:interval[0]] + ColorMatchedLineFormatter.CHAR_FORMAT_START_PURPLE + \
                              line[interval[0]:interval[1]] + ColorMatchedLineFormatter.CHAR_FORMAT_END
            last_match_end = interval[1]
        formatted_line += line[last_match_end:]

        return formatted_line

class UnderscoreMatchedLineFormatter:
    """Formats the information related to pattern matched lines in a file underscoring ^^^ the matching text
      (see details in the format method)
    """

    # noinspection PyMethodMayBeStatic
    def format(self, filename, line_number, line, pattern_match_intervals):
        """
           Returns a string containing the information provided by the input parameters (related to pattern matched
           lines in a file) using this formatting:

            filename:line_number:line (with ^^^^ under the matching text)

           :param filename: Filename of the file being parsed
           :param line_number: Line number
           :param line: String containing the actual line of the file being processed
           :param pattern_match_intervals: Set of tuples (start, end) where the pattern has been found in the line
           :return: Formatted string
        """

        prefix = filename + ":" + str(line_number) + ":"
        formatted_line = prefix + line
        underscored_line = [' '] * len(formatted_line)

        for interval in pattern_match_intervals:
            for i in range(interval[0] + len(prefix), interval[1] + len(prefix)):
                underscored_line[i] = "^"

        return formatted_line + "\n" + "".join(underscored_line)

class MachineReadableMatchedLineFormatter:
    """Formats the information related to pattern matched lines in a file using a machine readable formatting
         (see details in the format method)
    """

    # noinspection PyMethodMayBeStatic
    def format(self, filename, line_number, line, pattern_match_intervals):
        """
        Returns a string containing the information provided by the input parameters (related to pattern matched
        lines in a file) using this formatting:
            filename:line_number:start_pos:matched_text

        In case there are multiple matches several lines will be added:
            filename:line_number:start_pos1:matched_text
            filename:line_number:start_pos2:matched_text

        :param filename: Filename of the file being parsed
        :param line_number: Line number
        :param line: String containing the actual line of the file being processed
        :param pattern_match_intervals: Set of tuples (start, end) where the pattern has been found in the line
        :return: Formatted string
        """
        formatted_line = ""
        prefix = filename + ":" + str(line_number) + ":"

        for interval in pattern_match_intervals:
            formatted_line = formatted_line + prefix + str(interval[0]) + ":" + line[interval[0]:interval[1]] + "\n"

        return formatted_line.strip()

def find_pattern_in_string(input_string, pattern):
    """
    Search for all non-overlapping matches of a pattern in a string

    :param input_string: String where to search the pattern
    :param pattern: Regular expression with the pattern to search
    :return: list of intervals (match start, match end) of input_string where the pattern has been found.
    """
    if not pattern:
        raise ValueError("pattern can't be empty")

    match_intervals = []
    cre = re.compile(pattern)

    for match in cre.finditer(input_string):
        match_intervals.append((match.start(), match.end()))

    return match_intervals

def find_pattern_in_files(files, pattern, print_line_format):
    """
    Search for a pattern in a list of files (or in stdin if none is provided) and print the
    matching lines using the format specified in print_line_format

    :param files: Files to be processed. stdin will be used if none is provided
    :param pattern: Regular expression with the pattern to search
    :param print_line_format: Format to use when printing the matching lines
    """
    factory = MatchedLineFormatterFactory()

    factory.register_format(MatchedLineFormat.DEFAULT, DefaultMatchedLineFormatter)
    factory.register_format(MatchedLineFormat.COLOR, ColorMatchedLineFormatter)
    factory.register_format(MatchedLineFormat.UNDERSCORE, UnderscoreMatchedLineFormatter)
    factory.register_format(MatchedLineFormat.MACHINE, MachineReadableMatchedLineFormatter)
    line_formatter = factory.get_formatter(print_line_format)

    if files is not None:
        for filename in files:
            with open(filename, 'r') as f:
                for line_number, line in enumerate(f, start=1):
                    match_intervals = find_pattern_in_string(line.strip(), pattern)
                    if len(match_intervals) > 0:
                        print(line_formatter.format(filename, line_number, line.strip(), match_intervals))
            f.close()
    else:
        line_number = 0
        for line in sys.stdin:
            line_number += 1
            match_intervals = find_pattern_in_string(line.strip(), pattern)
            if len(match_intervals) > 0:
                print(line_formatter.format("-", line_number, line.strip(), match_intervals))

if __name__ == '__main__':
    # Construct the argument parser
    ap = argparse.ArgumentParser()

    # Add the arguments to the parser
    ap.add_argument("-r", "--regex", required=True, help="regexp to search")
    ap.add_argument("-f", "--files", metavar='FILE', nargs='*', help='files to read, if empty, stdin is used')

    # Create a group for mutually exclusive arguments
    group = ap.add_mutually_exclusive_group()
    group.add_argument("-u", "--underscore", help="prints '^' under the matching text", action="store_true")
    group.add_argument("-c", "--color", help="highlight the matching text", action="store_true")
    group.add_argument("-m", "--machine", help="generate machine-readable output format:\n  "
                                               "file_name:no_line:start_pos:matched_text", action="store_true")
    args = ap.parse_args()

    if args.underscore:
        find_pattern_in_files(args.files, args.regex, MatchedLineFormat.UNDERSCORE)
    elif args.color:
        find_pattern_in_files(args.files, args.regex, MatchedLineFormat.COLOR)
    elif args.machine:
        find_pattern_in_files(args.files, args.regex, MatchedLineFormat.MACHINE)
    else:
        find_pattern_in_files(args.files, args.regex, MatchedLineFormat.DEFAULT)


from typing import List

class Solution:
    '''
    complexity: O(n^2) time and O(n) space
    idea: dynamic programming
    link to problem: https://leetcode.com/problems/arithmetic-slices/
    '''
    def numberOfArithmeticSlices(self, A: List[int]) -> int:
        if len(A) < 3:
            return 0
        n = len(A)
        def isArith(a):
            return a[2]-a[1] if a[2]-a[1] == a[1]-a[0] else 10000
        regis = [isArith(A[i:i+3]) for i in range(n-2)]
        res = sum([1 if e < 10000 else 0 for e in regis])
        for i in range(3, n):
            for j in range(n-i):
                if regis[j] < 10000 and A[j+i] - A[j+i-1] == regis[j]:

                    res += 1
                else:
                    regis[j] = 10000
        return res


from UM.Extension import Extension
from UM.i18n import i18nCatalog

from UM.Preferences import Preferences

from .UpdateCheckerJob import UpdateCheckerJob

i18n_catalog = i18nCatalog("uranium")

## This Extension checks for new versions of the application based on the application name and the version number.
#  The plugin is currently only usable for applications maintained by Ultimaker. But it should be relatively easy
#  to change it to work for other applications.
class UpdateChecker(Extension):
    url = "http://software.ultimaker.com/latest.json"

    def __init__(self):
        super().__init__()
        self.addMenuItem(i18n_catalog.i18nc("@item:inmenu", "Check for Updates"), self.checkNewVersion)

        Preferences.getInstance().addPreference("info/automatic_update_check", True)
        if Preferences.getInstance().getValue("info/automatic_update_check"):
            self.checkNewVersion(True)

    ##  Connect with software.ultimaker.com, load latest.json and check version info.
    #   If the version info is higher then the current version, spawn a message to
    #   allow the user to download it.
    #
    #   \param silent type(boolean) Suppresses messages other than "new version found" messages.
    #                               This is used when checking for a new version at startup.
    def checkNewVersion(self, silent = False):
        job = UpdateCheckerJob(silent = silent, url = self.url)
        job.start()


import pygame

# Function to check for collisions
def checkCollision(x,y,treasureX,treasureY, width, height):
  # Use global keyword to declare global variables
  global screen, textWin

  collisionState = False

  # Check if playerImage touches the treasureImage
  if (y >= treasureY and y <= treasureY + height):
    if (x >= treasureX and x <= treasureX + width):
      # Move playerImage back to original starting position
      y = 550
      x = 0
      collisionState = True
    elif (x + width >= treasureX and x + width <= treasureX + width):
      y = 550
      x = 0
      collisionState = True
  elif (y + height >= treasureY and y + height <= treasureY + height):
    if (x >= treasureX and x <= treasureX + width):
      y = 550
      x = 0
      collisionState = True
    elif (x + width >= treasureX and x + width <= treasureX + width):
      y = 550
      x = 0
      collisionState = True
  return collisionState, y, x

# Initialize Pygame Library
pygame.init()

# Display is an object inside Pygame
# Set Mode method creates a screen with the size inputted
screen = pygame.display.set_mode((1000,700))

# Variable to keep track if our game is finished
finished = False

# Set x & y coordinates
x = 0
y = 550

# Load player image to playerImage variable
playerImage = pygame.image.load("rocket.png")

# Scale and transform Image to fit rectangle
playerImage = pygame.transform.scale(playerImage, (40, 160))

# Make playerImage ready for game
playerImage = playerImage.convert_alpha()

# Load background image to backgroundImage variable
backgroundImage = pygame.image.load("space.jpg")

# Scale and transform Image to fit the screen
backgroundImage = pygame.transform.scale(backgroundImage, (1000,700))

# Put background image into the window
screen.blit(backgroundImage, (0,0))

# Load earth image to earthImage variable
earthImage = pygame.image.load("earth.png")

# Scale and transform Image to be smaller than the playerImage
earthImage = pygame.transform.scale(earthImage, (100, 100))

# Make earthImage ready for game
earthImage = earthImage.convert_alpha()

# Load treasure image to treasureImage variable
treasureImage = pygame.image.load("mars.png")

# Scale and transform Image to be smaller than the playerImage
treasureImage = pygame.transform.scale(treasureImage, (100, 100))

# Make treasureImage ready for game
treasureImage = treasureImage.convert_alpha()

# Load enemy image to enemyImage variable
enemyImage = pygame.image.load("asteroid.png")

# Scale and transform enemyImage
enemyImage = pygame.transform.scale(enemyImage, (35,40))

# Make enemyImage ready for game
enemyImage = enemyImage.convert_alpha()

# Set Earth coordinates
earthX = -40
earthY = 640

# Set treasure coordinates
treasureX = 890
treasureY = 10

# Set enemy coordinates
enemyX = 200
enemyY = 500

# Put treasure image into the window
screen.blit(treasureImage, (treasureX, treasureY))

# Get font from Pygame and store in font variable
font = pygame.font.Font("MuktaMahee.ttf", 60)

# Create Levels variable
level = 1

# Enemy Names Dictionary
enemyNames = {0:"Jeff",1:"Jeff",2:"Jeff",3:"Jeff",4:"Jeff",5:"Jeff",6:"Jeff",7:"Jeff",8:"Jeff"}

# Create a Clock and store in frame variable
frame = pygame.time.Clock()

# Define if the playerImage has collided with the treasure
collisionTreasure = False

# Define if the playerImage has collided with the enemy
collisionEnemy = False

# Determines the direction the enemy is moving
movingUp = True

# Empty string for collision enemy
name = ""

# Create list of enemies with each item in the list as a tuple
enemies = [(enemyX, enemyY, movingUp)]

# While our game is not finished
while (finished == False):
  # get() method gives us all of the events that have happened since last check
  for event in pygame.event.get():
    # Looking at Event type. If type is a Quit Event then finish the game
    if event.type == pygame.QUIT:
      finished = True

  # Check if key is pressed
  pressedKeys = pygame.key.get_pressed()

  enemyIndex = 0

  # For loop to move each enemy
  for enemyX,enemyY,movingUp in enemies:
    # If enemy is about to reach the bottle of the screen then movingUp equals true
    if (enemyY >= 665):
      movingUp = True
    # If enemy is about to reach the bottle of the screen then movingUp equals false
    elif (enemyY <= 10 ):
      movingUp = False

    # If movingUp is true then move enemy up
    if movingUp == True:
      # Scale movement depending on the level
      enemyY -= 10 * level
    # Else if movingUp is false then move enemy down
    else:
      # Scale movement depending on the level
      enemyY += 10 * level
    enemies[enemyIndex] = (enemyX, enemyY, movingUp)
    enemyIndex += 1

  # If Space Key is pressed then increase the y coordinate by 5
  if (pressedKeys[pygame.K_DOWN] == 1):
    y += 30
  elif (pressedKeys[pygame.K_UP] == 1):
    y -= 30
  elif (pressedKeys[pygame.K_LEFT] == 1):
    x -= 30
  elif (pressedKeys[pygame.K_RIGHT] == 1):
    x += 30

  # Store rectangle object in a variable
  # Define x, y, width, and height of rectangle
  # rectOne = pygame.Rect(x,y,30,30)

  # Create a tuple to hold a color
  color = (0,0,255)
  # Define the color black in a variable
  white = (255,255,255)

  # Overwrite the original blue rectangle to black before creating a new one
  # screen.fill((white))

  # Fill background image onto the screen
  screen.blit(backgroundImage, (0,0))

  # Put earth image onto the screen
  screen.blit(earthImage, (earthX, earthY))

  # Put treasure image onto the screen
  screen.blit(treasureImage, (treasureX, treasureY))

  # Put playerImage into window
  screen.blit(playerImage, (x, y))

  # Create enemy index counter
  enemyIndex = 0
  # For loop to load each enemy into the window
  for enemyX, enemyY, movingUp in enemies:
    # Put enemyImage into window
    screen.blit(enemyImage, (enemyX, enemyY))
    # Call checkCollision function and store in variables
    collisionEnemy, y, x = checkCollision(x,y,enemyX,enemyY,35,40)
    # Check if player collided with enemy
    if (collisionEnemy == True):
      # Assign name variable value from enemyNames dictionary
      name = enemyNames[enemyIndex]
      # Create text object and display that the player got destroyed
      textLose = font.render("You were destroyed by the asteroid "+name, True, (255,0,0))
      # Display textLose on the screen and center the text
      screen.blit(textLose, (500 - textLose.get_width()/2, 350 - textLose.get_height()/2))
      # Update the screen
      pygame.display.flip()
      # Slow down frame to make text appear slower
      frame.tick(1)
    # Create frame rate (frames per second)
    frame.tick(30)
    # Increment enemyIndex counter
    enemyIndex += 1

  # Call checkCollision function and store in variables
  collisionTreasure, y, x = checkCollision(x,y,treasureX,treasureY,100,100)

  # Refactor checkCollisions function to make it DRY (Don't Repeat Yourself)
  if (collisionTreasure == True):
    # Increment Level
    level += 1
    # Add new enemy to enemies list
    enemies.append((enemyX + 100, enemyY - 300, False))
    # Create text object and display level that user is on
    textWin = font.render("You've reached level " + str(level), True, (255,255,255))
    # Display textWin on the screen and center the text
    screen.blit(textWin, (500 - textWin.get_width()/2, 350 - textWin.get_height()/2))
    # Update the screen
    pygame.display.flip()
    # Slow down frame to make text appear slower
    frame.tick(1)

  # Draws rectangle onto the screen, need to input screen, color, and rectangle object
  # pygame.draw.rect(screen, color, rectOne)

  # Update the screen
  pygame.display.flip()

  # Create frame rate (frames per second)
  frame.tick(30)


#!/usr/bin/env python3

import sys
import time

padding = ' ' * 5000

sys.stdout.write(
    'Connection: keep-alive\r\n'
    'Content-type: multipart/x-mixed-replace; boundary=boundary\r\n\r\n'
    '--boundary\r\n'
    'Content-Type: text/html\r\n\r\n'
    f'{padding}\n'
    '\n'
    '<script>\n'
    'if (window.testRunner) {\n'
    '    testRunner.dumpAsText();\n'
    '    if (testRunner.setShouldDecideResponsePolicyAfterDelay)\n'
    '        testRunner.setShouldDecideResponsePolicyAfterDelay(true);\n'
    '}\n'
    '</script>\n\n'
)

for i in range(0, 11):
    sys.stdout.write(
        '--boundary\r\n'
        'Content-Type: text/html\r\n\r\n'
    )

    if i < 10:
        sys.stdout.write(
            'This is message {}.<br>'
            'FAIL: The message number should be 10.'.format(i)
        )
    else:
        sys.stdout.write('PASS: This is message {}.'.format(i))

    sys.stdout.write('{}\r\n\r\n'.format(padding))
    sys.stdout.flush()
    time.sleep(0.1)


# -*- coding: utf-8 -*-
"""Bubblesort simple sorting algorithm.

Bubble sort has a worst and average complexity of O(n²).
"""

def bubble_sort(sequence):
    unsorted = True
    # loop until we make one pass with no swaps
    while unsorted:
        unsorted = False
        # iterate from index 0 -> 2nd last item in list as comparing with i + 1
        for i in range(len(sequence) - 1):
            if sequence[i] > sequence[i + 1]:
                unsorted = True  # swap took place, will need to iterate again
                # Swap in one line, no need for temp variable
                sequence[i + 1], sequence[i] = sequence[i], sequence[i + 1]


# OS imports
from multiprocessing import cpu_count

# QLoRA imports
import torch
from peft import (
    PeftModel,
    PeftConfig
)
from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    LlamaTokenizer,
    StoppingCriteria,
    StoppingCriteriaList,
    TextIteratorStreamer
)

# Web imports
from flask import (
    Flask,
    render_template,
    request,
    redirect,
    url_for
)

app = Flask(__name__)
app.config['TEMPLATES_AUTO_RELOAD'] = True

experts = ['Default', 'Physics', 'Biology']

# Loading model and adapters
model_id = 'facebook/opt-1.3b'

m = AutoModelForCausalLM.from_pretrained(
    model_id,
    torch_dtype=torch.bfloat16
)

# Physics adapter
peft_config = PeftConfig.from_pretrained('./data/physics')
m.add_adapter(peft_config, adapter_name='Physics')

# Biology adapter
peft_config = PeftConfig.from_pretrained('./data/biology')
m.add_adapter(peft_config, adapter_name='Biology')

tok = AutoTokenizer.from_pretrained(model_id)

torch.set_num_threads(cpu_count())

@app.route('/')
def index():
    return redirect(url_for('chat', expert='Default'))

@app.post('/expert')
@app.post('/expert/')
def selectExpert():
    body = request.form
    expert_name = body.get('expert')
    if expert_name == None or not expert_name in experts:
        return redirect(url_for('index'))
    return redirect(url_for('chat', expert=expert_name))

@app.route('/chat/<expert>')
def chat(expert):
    return render_template('index.html', experts=experts, expert=expert)

@app.post('/message')
@app.post('/message/')
def genMessage():
    body = request.get_json()
    expert = body.get('expert')
    if not expert:
        m.disable_adapters()
    else:
        if expert != 'Default' and expert in experts:
            m.enable_adapters()
            m.set_adapter(expert)
        else:
            m.disable_adapters()

    prompt = body.get('message')
    if not prompt:
        return {'error': 'Message field is required'}

    response_msg = ''

    prompt = prompt + '\nA.'

    inputs = tok(prompt, return_tensors='pt').input_ids

    try:
        with torch.no_grad():
            outputs = m.generate(
                input_ids=inputs,
                do_sample=True,
                max_new_tokens=40
            )

            outputs = tok.batch_decode(
                outputs.detach().cpu().numpy()
            )
            outputs = outputs[0]

            outputs = outputs.split('\nA.')
            outputs = outputs[1]

            if outputs.find('.') > 0:
                outputs = outputs.split('.')[:-1]

            if len(outputs[-1].strip()) <= 1:
                outputs = outputs[:-1]

            if type(outputs) is list:
                outputs = list(map(lambda a: a.strip(), outputs))

            outputs = '. '.join(outputs)

            if not outputs[-1] in '!?.':
                outputs += '.'

            try:
                outputs = outputs.split('\n')[0]
            except:
                pass

            response_msg = outputs
    except:
        pass

    return {'message': response_msg}

print('--- App is ready! ---')


"""
给定一个数组 nums 和一个目标值 k，找到和等于 k 的最长子数组长度。如果不存在任意一个符合要求的子数组，则返回 0。
注意:
 nums 数组的总和是一定在 32 位有符号整数范围之内的。
示例 1:
输入: nums = [1, -1, 5, -2, 3], k = 3
输出: 4
解释: 子数组 [1, -1, 5, -2] 和等于 3，且长度最长。
示例 2:
输入: nums = [-2, -1, 2, 1], k = 1
输出: 2
解释: 子数组 [-1, 2] 和等于 1，且长度最长。
进阶:
你能使时间复杂度在 O(n) 内完成此题吗?

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/maximum-size-subarray-sum-equals-k
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
"""
from collections import defaultdict

class Solution:
    def maxSubArrayLen(self, nums: List[int], k: int) -> int:
        # 统计前缀和，比如[1,-1,5,-2,3] k=3
        # 前缀和为[1,0,5,3,6] 此时如果直接发现有等于k的，那么就是一个，然后发现6-3=3，也就是num[i]-num[j]=k 那就说明j+1到i这段的和为k
        # [-2,-1,2,1] k=1
        # [-2,-3,-1,0]
        sum_set = defaultdict(int)
        max_len = 0
        tmp_sum = 0
        sum_array = [0] * len(nums)
        for i in range(len(nums)):
            tmp_sum += nums[i]
            sum_array[i] = tmp_sum
            if tmp_sum not in sum_set:  # 记录最长的，第一次的肯定会比较长
                sum_set[tmp_sum] = i
            if tmp_sum == k:
                max_len = max(max_len, i + 1)
            if (tmp_sum - k) in sum_set:  # num[i]-num[j]==k
                max_len = max(max_len, i - sum_set[tmp_sum - k])
        return max_len

# 第二次
from collections import defaultdict
class Solution2:
    def maxSubArrayLen(self, nums: List[int], k: int) -> int:
        # [1,-1,5,-2,3] k=3
        # [1,0,5,3,6]
        # [-2,-1,2,1] k=1
        # [-2,-3,-1,0] -1--2=1 nums[i]-nums[j]=k -> j+1到i的和为k
        left,right=0,0
        max_len=0
        tmp_sum=0
        sum_dict=defaultdict(int)
        while(right<len(nums)):
            tmp_sum+=nums[right]
            if tmp_sum not in sum_dict: #记录最开始的那个位置就好了，最近
                sum_dict[tmp_sum]=right
            if tmp_sum==k:
                max_len=max(max_len,right+1)
            if tmp_sum-k in sum_dict:
                max_len=max(max_len,right-sum_dict[tmp_sum-k])

            right+=1
        return max_len

分类/滑动窗口/325.和等于k的最长子数组长度（2次）.py

325.和等于k的最长子数组长度（2次）.py


from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.http import Http404
from django.core import serializers
from django.db.models import Sum

from shopping_registry import accountVerification
from shopping_registry import totalCalculations
from shopping_registry import graphGeneration

from .models import Purchase
from .forms import PurchaseForm

import json
import datetime

def index(request):
    """The home page for Registro-Super."""
    return render(request, 'shopping_registry/index.html')

@login_required
def dates(request):
    """Shows all dates."""
    dates = []

    purchases = Purchase.objects.filter(owner=request.user).order_by('-date_purchase')

    for purchase in purchases:
        if purchase.date_purchase not in dates:
            dates.append(purchase.date_purchase)

    context = {'dates': dates}
    return render(request, 'shopping_registry/dates.html', context)

@login_required
def date(request, date):
    """Shows all the information for a day's purchases."""

    date_string = date
    date = datetime.datetime.strptime(date, '%Y-%m-%d')

    purchases = Purchase.objects.filter(date_purchase=date, owner=request.user)

    total = totalCalculations.calculate_total(purchases)

    products = []

    quantities = []

    prices = []

    ind_prices = []

    # Stores the name of the product, its individual price and its bulk's boolean
    # value
    dictionary = {}

    categories = []

    categories_total = totalCalculations.total_categories(purchases)

    bulk = []

    for purchase in purchases:
        products.append(purchase.product)
        quantities.append(purchase.quantity)
        prices.append(purchase.price)
        bulk.append(purchase.bulk)

    for x in range(0, len(products)):
        if purchases[x].category.title() not in categories:
            categories.append(purchases[x].category.title())

        if bulk[x] == True:
            # If it was a bulk purchase, multiply by 100 to display the price per
            # 100 grams.
            ind_prices.append(float((prices[x] / quantities[x]) * 100))
        else:
            ind_prices.append(float((prices[x] / quantities[x])))

        ind_prices[x] = round(ind_prices[x], 2)

        dictionary[x] = {'Nombre': purchases[x], 'Categoria': purchases[x].category,
            'Bulk': bulk[x], 'Precio': ind_prices[x]}

    # Product and Price visualization

    # Convert the prices list QuerySet to a list of floats.
    prices_float = [float(price) for price in prices]

    # Generating the charts.
    # Bar chart.
    bar_graph = graphGeneration.generateBarGraph(products, prices_float)

    # Pie chart.
    pie_graph = graphGeneration.generatePieGraph(categories_total)

    context = {'date': date, 'date_string': date_string, 'purchases': purchases, 'total':total,
        'products':products, 'ind_prices':ind_prices, 'dictionary': dictionary,
        'categories': categories, 'categories_total': categories_total,
        'bar_graph': bar_graph, 'pie_graph': pie_graph}
    return render(request, 'shopping_registry/date.html', context)

@login_required
def edit_purchase(request, purchase_id):
    """Edit an existing purchase."""
    purchase = get_object_or_404(Purchase, id=purchase_id)

    # Checks if user is using demo account and is the owner of the object.
    accountVerification.check_account(request.user.username, purchase)

    date = purchase.date_purchase

    # Passes the data to the form template.
    formatedDate = date.strftime("%m/%d/%Y")

    initial_dict = {
        "date_purchase" : formatedDate,
        "bulk": True,
    }

    if request.method != 'POST':
        # Initial request; pre-fill form with the current purchase.
        form = PurchaseForm(instance=purchase, initial=initial_dict)
    else:
        # POST data submitted; process data.
        form = PurchaseForm(data=request.POST, instance=purchase)

        if form.is_valid():
            edited_purchase = form.save(commit=False)
            edited_purchase.owner = request.user
            edited_purchase.save()
            return redirect('shopping_registry:date', date=date)

    context = {'purchase': purchase, 'form': form, 'date': formatedDate}
    return render(request, 'shopping_registry/edit_purchase.html', context)

@login_required
def erase_date_confirmation(request, date_string):
    """Confirm the deletion of the purchases done on the selected date."""

    accountVerification.check_account(request.user.username)

    purchases = Purchase.objects.filter(date_purchase=date_string, owner=request.user)

    # Date is stored in string 'YYYY-MM-DD', converted to datetime value.
    date = datetime.datetime.strptime(date_string, '%Y-%m-%d')

    context = {'date': date, 'purchases': purchases, 'date_string': date_string}
    return render(request, 'shopping_registry/erase_date_confirmation.html', context)

@login_required
def erase_date(request, date_string):
    """Delete all the purchases done on the selected date."""

    accountVerification.check_account(request.user.username)

    # Date_string is stored in string format 'YYYY-MM-DD',
    # converted to datetime value.
    date = datetime.datetime.strptime(date_string, '%Y-%m-%d')

    purchases = Purchase.objects.filter(date_purchase=date_string, owner=request.user)

    purchases_erase = purchases.delete()

    context = {'date': date, 'purchase': purchases}
    return render(request, 'shopping_registry/erase_date.html', context)

@login_required
def delete_purchase_confirmation(request, purchase_id):
    """Confirms the deletion of a purchase."""
    purchase = get_object_or_404(Purchase, id=purchase_id)

    accountVerification.check_account(request.user.username, purchase)

    context = {'purchase': purchase}
    return render(request, 'shopping_registry/delete_purchase_confirmation.html',
        context)

@login_required
def delete_purchase(request, purchase_id):
    """Deletes a single purchase."""
    purchase = get_object_or_404(Purchase, id=purchase_id)

    accountVerification.check_account(request.user.username, purchase)

    purchase_erase = purchase.delete()

    context = {'purchase': purchase}
    return render(request, 'shopping_registry/delete_purchase.html', context)

@login_required
def MonthView(request, year, month):
    """Displays all shopping trips in a month."""

    purchases = Purchase.objects.filter(date_purchase__year=year,
        date_purchase__month=month, owner=request.user)

    total = totalCalculations.calculate_total(purchases)

    dates = []

    products_total = {}

    categories_total = totalCalculations.total_categories(purchases)

    for purchase in purchases:
        if purchase.product not in products_total:
            products_total[purchase.product] = 0
            products_total[purchase.product] += purchase.price
        else:
            products_total[purchase.product] += purchase.price

        if purchase.date_purchase not in dates:
            dates.append(purchase.date_purchase)

    date = datetime.datetime(year, month, 1)

    # Stores keys and values from dict to use as labels and values in the charts.
    # Bar chart.
    bar_labels = products_total.keys()
    bar_values = products_total.values()

    # Casts into list for chart compatibility.
    # Bar chart.
    bar_labels = list(bar_labels)
    bar_values = list(bar_values)

    # Generating the charts.
    # Bar chart.
    bar_graph = graphGeneration.generateBarGraph(bar_labels, bar_values)

    # Pie chart.
    pie_graph = graphGeneration.generatePieGraph(categories_total)

    context = {'date': date, 'dates': dates, 'total':total,
        'products_total': products_total, 'categories_total': categories_total,
        'bar_graph': bar_graph, 'pie_graph':pie_graph}
    return render(request, 'shopping_registry/month_view.html', context)

@login_required
def Years(request):
    """Shows all years with registered purchases."""

    purchases = Purchase.objects.filter(owner=request.user).order_by('date_purchase')

    years = []
    for purchase in purchases:
        if purchase.date_purchase.year not in years:
            years.append(purchase.date_purchase.year)
    context = {'years': years}
    return render(request, 'shopping_registry/years.html', context)

@login_required
def Months(request, year):
    """Shows all the months with registered purchases in the selected month."""
    purchases = Purchase.objects.filter(owner=request.user).order_by('date_purchase')

    months = []
    for purchase in purchases:
        if purchase.date_purchase.month not in months:
            months.append(purchase.date_purchase.month)

    datetimes = []
    for month in months:
        datetimes.append(datetime.datetime(year, month, 1).date())

    context = {'months': months, 'dates': datetimes, 'year': year}
    return render(request, 'shopping_registry/months.html', context)

@login_required
def registering_instructions(request):
    """Page that links to the PurchaseForm and includes instructions."""

    accountVerification.check_account(request.user.username)

    return render(request, 'shopping_registry/instrucciones_registro.html')

def demo_account_instructions(request):
    """Page that links to the log-in form and includes instructions regarding the
    use of the demo account."""

    return render(request, 'shopping_registry/instrucciones_demostracion.html')

@login_required
def new_purchase(request):
    """Add a new purchase."""
    username = request.user.username
    accountVerification.check_account(username)

    next = redirect('shopping_registry:dates')

    print("this works")

    if request.method != 'POST':
        # No data submitted; create a blank form.
        form = PurchaseForm()
    else:
        # POST data submitted; process data.
        form = PurchaseForm(data=request.POST)
        if form.is_valid():
            date = form['date_purchase'].value()
            new_purchase = form.save(commit=False)
            new_purchase.owner = request.user
            new_purchase.save()
            # Clears the form incase the user wants to register antoher purchase.
            form = PurchaseForm()
            if 'saveAnother' in request.POST:
                # Find way to store date value in form to display it again.
                next = redirect('shopping_registry:new_purchase')
            return next

    context = {'form': form}
    return render(request, 'shopping_registry/new_purchase.html', context)


import math
import platform

import pygame
import Box2D
from Box2D import *

from game import SCREEN_WIDTH
from game import SCREEN_HEIGHT

VELOCITY_ITERATIONS = 6
POSITION_ITERATIONS = 2
PIXELS_PER_METER = 40

SYSTEM_FILE_PREFIX = "" if platform.system() == "Windows" else "../"

DRAW_DEBUG = False

# Sound from: https://freesound.org/people/ShaneF91/sounds/386572/

def rotate_point_list(origin, points, angle):
    s = math.sin(angle)
    c = math.cos(angle)
    r_points = []
    for p in points:
        px = p[0]
        py = p[1]
        px -= origin[0]
        py -= origin[1]
        rx = px * c - py * s
        ry = px * s + py * c
        nx = rx + origin[0]
        ny = ry + origin[1]
        r_points.append((nx, ny))
    return r_points

def convert_w2s(pos):
    return (PIXELS_PER_METER * (pos[0])) + (SCREEN_WIDTH / 2), PIXELS_PER_METER * (-1 * pos[1]) + SCREEN_HEIGHT

def distance(p, q):
    return math.sqrt((q[0] - p[0])**2 + (q[1] - p[1])**2)

class WorldInstance:
    def __init__(self):
        self.display_surface = pygame.display.get_surface()
        self.background = pygame.transform.scale(
            pygame.image.load(f"{SYSTEM_FILE_PREFIX}resources/background.png"),
            (SCREEN_WIDTH, SCREEN_HEIGHT))

        self.world_objects = []

        # Setup Box2d
        self.gravity = b2Vec2(0.0, -1.6)
        contact_listener = WorldContactListener()
        self.world = b2World(gravity=self.gravity, contactListener=contact_listener)

        # Create ground
        ground_width = SCREEN_WIDTH / PIXELS_PER_METER
        ground_height = SCREEN_HEIGHT / PIXELS_PER_METER
        print(ground_width, ground_height)
        # 1 / 8 ratio for height/width
        # 1280x160 for ground
        self.ground = DrawableWorldObject(
            self.world.CreateBody(
                position=(0.0, ground_height / 16),
                fixtures=b2FixtureDef(shape=b2PolygonShape(box=(ground_width / 2, ground_height / 16)))
            ),
            pygame.image.load(f"{SYSTEM_FILE_PREFIX}resources/ground.png")
        )

        # Create screen borders
        self.world.CreateBody(
            shapes=b2LoopShape(vertices=[
                ((SCREEN_WIDTH / PIXELS_PER_METER)/2, -(SCREEN_HEIGHT / PIXELS_PER_METER)),
                ((SCREEN_WIDTH / PIXELS_PER_METER)/2, (SCREEN_HEIGHT / PIXELS_PER_METER)),
                (-(SCREEN_WIDTH / PIXELS_PER_METER)/2, (SCREEN_HEIGHT / PIXELS_PER_METER)),
                (-(SCREEN_WIDTH / PIXELS_PER_METER)/2, -(SCREEN_HEIGHT / PIXELS_PER_METER))
            ])
        )

        # Create player
        self.player = Player(
            self.world.CreateDynamicBody(
                position=(0.0, 5.0),
                fixtures=b2FixtureDef(
                    shape=b2PolygonShape(box=(0.286, 0.5)),
                    density=50.0,
                    friction=1,
                    restitution=0.5
                ),
                fixedRotation=True
            ),
            pygame.image.load(f"{SYSTEM_FILE_PREFIX}resources/player.png")
        )

        self.platforms = []
        self.gen_platforms()

    def gen_platforms(self):
        self.platforms.append(DrawableWorldObject(
            self.world.CreateStaticBody(
                position=(0.0, 10.0),
                fixtures=b2FixtureDef(shape=b2PolygonShape(box=(1, .555)))
            ),
            pygame.image.load(f"{SYSTEM_FILE_PREFIX}resources/platform.png")
        ))
        self.platforms.append(DrawableWorldObject(
            self.world.CreateStaticBody(
                position=(8.0, 5.0),
                fixtures=b2FixtureDef(shape=b2PolygonShape(box=(1, .555)))
            ),
            pygame.image.load(f"{SYSTEM_FILE_PREFIX}resources/platform.png")
        ))
        self.platforms.append(DrawableWorldObject(
            self.world.CreateStaticBody(
                position=(-10.0, 7.0),
                fixtures=b2FixtureDef(shape=b2PolygonShape(box=(1, .555)))
            ),
            pygame.image.load(f"{SYSTEM_FILE_PREFIX}resources/platform.png")
        ))
        self.platforms.append(DrawableWorldObject(
            self.world.CreateStaticBody(
                position=(-5.0, 13.0),
                fixtures=b2FixtureDef(shape=b2PolygonShape(box=(1, .555)))
            ),
            pygame.image.load(f"{SYSTEM_FILE_PREFIX}resources/platform.png")
        ))
        self.platforms.append(DrawableWorldObject(
            self.world.CreateStaticBody(
                position=(14.0, 13.0),
                fixtures=b2FixtureDef(shape=b2PolygonShape(box=(1, .555)))
            ),
            pygame.image.load(f"{SYSTEM_FILE_PREFIX}resources/platform.png")
        ))

    def step(self, dt: float):
        self.process_inputs()
        self.process_updates(dt)
        self.process_outputs(dt)

    def process_inputs(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_a]:
            if not self.player.jump_cooldown:
                self.player.body.ApplyLinearImpulse(b2Vec2(-2.0, 0.0), self.player.body.position, True)
        if keys[pygame.K_d]:
            if not self.player.jump_cooldown:
                self.player.body.ApplyLinearImpulse(b2Vec2(2.0, 0.0), self.player.body.position, True)
        if keys[pygame.K_SPACE]:
            if not self.player.jump_cooldown:
                self.player.remove_jump()
                self.player.body.ApplyLinearImpulse(b2Vec2(0.0, 75.0), self.player.body.position, True)
        if keys[pygame.K_LSHIFT]:
            if not self.player.smash_cooldown:
                self.player.remove_smash()
                self.player.body.ApplyLinearImpulse(b2Vec2(0.0, -75.0), self.player.body.position, True)

    def process_updates(self, dt: float):
        # Update physics engine
        self.world.Step(dt, VELOCITY_ITERATIONS, POSITION_ITERATIONS)

    def process_outputs(self, dt: float):
        self.draw()
        # print(self.player.body.position)

    def draw(self):
        self.display_surface.fill('black')
        self.display_surface.blit(self.background, self.background.get_rect())

        self.ground.draw()
        self.player.draw()
        for plat in self.platforms:
            plat.draw()
        if DRAW_DEBUG:
            for body in self.world.bodies:
                transform = body.transform
                for fixture in body.fixtures:
                    # rotate fixture vertices around transform's angle
                    r_verts = rotate_point_list((0, 0), fixture.shape.vertices, transform.angle)
                    # translate vertices to transform's world position
                    w_verts = [(v[0] + transform.position.x, v[1] + transform.position.y) for v in r_verts]
                    # translate vertices to screen coordinates
                    s_verts = [convert_w2s(v) for v in w_verts]
                    # draw shape
                    pygame.draw.polygon(self.display_surface, (255, 255, 255), s_verts, 1)
                    # print(s_verts)
        pygame.display.flip()

class DrawableWorldObject:
    def __init__(self, body, image):
        self.body = body
        self.image = image

        self.body_width = 0
        self.body_height = 0
        self.gen_dims()

    def gen_dims(self):
        for fixture in self.body.fixtures:
            transform = self.body.transform
            t_pos = (transform.position.x, transform.position.y)
            # rotate fixture vertices around transform's angle
            r_verts = rotate_point_list((0, 0), fixture.shape.vertices, transform.angle)
            # translate vertices to transform's world position
            w_verts = [(v[0] + t_pos[0], v[1] + t_pos[1]) for v in r_verts]
            # translate vertices to screen coordinates
            s_verts = [convert_w2s(v) for v in w_verts]

            # get width and height of box
            self.body_width = distance(s_verts[0], s_verts[1])
            self.body_height = distance(s_verts[0], s_verts[3])

    def draw(self):
        # box format:
        # tl tr br bl
        display_surface = pygame.display.get_surface()
        transform = self.body.transform
        t_pos = (transform.position.x, transform.position.y)
        # scale image to body size
        w_image = pygame.transform.scale(self.image, (self.body_width, self.body_height))
        # rotate image to body angle
        r_image = pygame.transform.rotate(w_image, transform.angle * (180 / math.pi))
        # move image to body screen position
        s_pos = convert_w2s(t_pos)
        s_rect = r_image.get_rect(center=w_image.get_rect(center=s_pos).center)
        # draw image
        display_surface.blit(r_image, s_rect)
        # pygame.draw.circle(display_surface, (255, 0, 0), s_pos, 3)
        # pygame.draw.rect(display_surface, (255, 0, 0), s_rect, 1)

class Player(DrawableWorldObject):
    def __init__(self, body, image):
        super().__init__(body, image)
        self.body.userData = self
        self.jump_cooldown = False
        self.smash_cooldown = False
        self.jump_sound = pygame.mixer.Sound(f"{SYSTEM_FILE_PREFIX}resources/jump.wav")
        self.smash_sound = pygame.mixer.Sound(f"{SYSTEM_FILE_PREFIX}resources/smash.wav")

    def start_contact(self):
        self.refresh_jump()
        self.refresh_smash()

    def end_contact(self):
        pass

    def refresh_smash(self):
        print("refresh_smash")
        self.smash_cooldown = False

    def refresh_jump(self):
        print("refresh_jump")
        self.jump_cooldown = False

    def remove_smash(self):
        print("remove_smash")
        self.smash_cooldown = True

    def remove_jump(self):
        print("remove_jump")
        self.jump_sound.play()
        self.jump_cooldown = True

# https://www.iforce2d.net/b2dtut/collision-callbacks
class WorldContactListener(b2ContactListener):
    """
    Calls contact methods for objects when colliding (if that object has a given method)
    """
    def BeginContact(self, contact):
        # check if fixture a was player
        bodyUserData = contact.fixtureA.body.userData
        if bodyUserData:
            bodyUserData.start_contact()

        bodyUserData = contact.fixtureB.body.userData
        if bodyUserData:
            bodyUserData.start_contact()

    def EndContact(self, contact):
        bodyUserData = contact.fixtureA.body.userData
        if bodyUserData:
            bodyUserData.end_contact()

        bodyUserData = contact.fixtureA.body.userData
        if bodyUserData:
            bodyUserData.end_contact()


# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

import os

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

project = 'Summoning Frontier'
copyright = '2023, Kai Sforza'
author = 'Kai Sforza'
release = '1.1'
version = release
language = 'en'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = [
    'sphinx.ext.duration',
    'sphinx.ext.extlinks',
    'sphinx.ext.todo',
    'sphinx.ext.imgconverter'
]

templates_path = ['_templates']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'Ideas/bad', 'README.rst', '.venv']

# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

html_theme = 'alabaster'
html_static_path = ['_static']
html_title = f'Summoning Frontier {release}'
html_css_files = ['style/customs.css',]

# -- Options for epub output
suppress_warnings = [
    'epub.unknown_project_files'
]
epub_cover = ('_static/cover.png', '')

## Okay this is hacky af
exclude_epub = []
for root, dirs, files in os.walk('_images/examples/'):
  exclude_epub += ['_build/epub/' + root + f for f in files]
epub_exclude_files = exclude_epub
epub_max_image_width = 1236
epub_fix_images = True

# For skipping unicode stuff.
latex_engine = 'lualatex'


class DeviceInfo:

    def getRoomId(self):
        try:
            f = open('./info.txt', 'r')
            line = f.readline()
            f.close()
            return line
        except:
            return None

    def setRoomId(self, roomId):
        f = open('./info.txt', 'w')
        f.write(str(roomId))
        f.close()

# seat = {}
#
# k = 1
# for i in range(3):
#     a = ('1', k)
#     seat[i] = a
#     k += 1
#
# print(seat)


from Player import Player
from AIPlayer import AIPlayer
from Dealer import Dealer
from Card import Card
def printInstruction(gameResources):
    '''Starts game and shows welcome message and rules'''
    print('Welcome to Linger Longer!')
    print('This is a 4 person game with 1 human player and 3 AI players.')
    print('The game starts with a trump suit.')
    print('Each player is given 4 cards.')
    print('Player 1 plays a card in the beginning of the round and then')
    print('player 2 does next and so on. Player wins a round by playing')
    print('the highest value card that is a trump suit.')
    print('If no card with a trump suit is played, then the highest value')
    print('card wins. Everybody but the winner of a round draws a card at')
    print('the end of the turn.')
    print('Win the game by running out cards in your hand or by having the')
    print('least amount of cards when the deck runs out cards.')

#creates players and deals cards to the players
def setUp(gameResources):
    gameResources["players"] = []
    gameResources["players"].append(Player())
    for x in range(0,3):
        gameResources["players"].append(AIPlayer())

    gameResources["cardsinplay"] = []
    d = Dealer()
    gameResources["dealer"] = d
    d.dealHand(gameResources["players"], 4, 4)
    gameResources["currentPlayer"] = 0
    gameResources["gameOver"] = False
    gameResources["trumpsuit"] = d.dealCard().suit
    gameResources["cardsinplay"] = []

def setUpRound(gameResources):
    gameResources["round"] = 0

def incrementRound(gameResources):
    gameResources["cardsinplay"] = []
    gameResources["playerindex"] = []
    gameResources["currentPlayer"] = 0
    gameResources["roundIsNotOver"] = True
    gameResources["round"] += 1
    print()
    print('---------------------ROUND %d---------------------' % gameResources["round"])
    for i in range(1,4):
        print("AI Player %(num)d has %(cNum)d cards" % {"num": (i+1), "cNum":len(gameResources["players"][i].hand)})
    print()
    print('The trump suit is %s' % Card.SUITS[gameResources["trumpsuit"] - 1])

def playCard(gameResources):
    d = gameResources["dealer"]
    if gameResources["currentPlayer"] == 0:
        player = gameResources["players"][0]
        k = 1
        for card in player.hand:
            cardStr = Card.string(card)
            print(" %(num)d) %(card)s" % {"num": k, "card":cardStr})
            k += 1
        while True:
            try:
                print("Enter desired card position to play:")
                cardnum = int(input())
                gameResources["cardsinplay"].append(player.hand[(cardnum - 1)])
                print("You play %(card)s" % { "card":Card.string(player.hand[(cardnum - 1)])})
                del player.hand[(cardnum - 1)]
                gameResources["playerindex"].append(gameResources["currentPlayer"])
                break
            except:
                print("Invalid number")
        if len(player.hand) <= 0:
            gameResources["emptyHand"] = True
    #the ai moves
    if gameResources["currentPlayer"] >= 1:
        if gameResources["currentPlayer"] == 3:
            gameResources["roundIsNotOver"] = False
        player = gameResources["players"][gameResources["currentPlayer"]]
        try:
            highest = player.hand[0]
            index = 0
            for i, card in enumerate(player.hand):
                if card.suit == gameResources["trumpsuit"] and (card.value > highest.value or highest.suit != gameResources["trumpsuit"]):
                    highest = card
                    index = i
                elif card.suit != gameResources["trumpsuit"]:
                    if highest.suit != gameResources["trumpsuit"] and card.value > highest.value:
                        highest = card
                        index = i
            gameResources["cardsinplay"].append(player.hand[index])
            print("AI Player %(num)d plays %(card)s" % { "num": (gameResources["currentPlayer"] + 1), "card":Card.string(player.hand[index])})
            del player.hand[index]
            gameResources["playerindex"].append(gameResources["currentPlayer"])
        except IndexError:
            print("AI Player %(num)d has no cards left to play" % { "num": (gameResources["currentPlayer"] + 1)})
        if len(player.hand) <= 0:
            gameResources["emptyHand"] = True
    gameResources["currentPlayer"] += 1
    if len(d.deck.cards) <= 4:
        gameResources["emptydeck"] = True

def roundEnd(gameResources):
    d = gameResources["dealer"]
    highest = gameResources["cardsinplay"][0]
    index = 1
    for i, card in enumerate(gameResources["cardsinplay"]):
        if card.suit == gameResources["trumpsuit"] and (card.value > highest.value or highest.suit != gameResources["trumpsuit"]):
            highest = card
            index = i+1
        elif card.suit != gameResources["trumpsuit"]:
            if highest.suit != gameResources["trumpsuit"] and card.value > highest.value:
                highest = card
                index = i+1

    # index = next((i for i, card in enumerate(gameResources["cardsinplay"]) if card.suit == gameResources["trumpsuit"]), -1)
    if index !=  -1:
        # for x in range(0, len(gameResources["cardsinplay"])):
            # for y in range(0, len(gameResources["cardsinplay"])):
                # if gameResources["cardsinplay"][y].value >= gameResources["cardsinplay"][x].value:
                    # index = y
        print("Player %(num)d wins the round and all other players draw a card"% {"num": index})
        for i in range(0, 4):
            if i != (index - 1):
                gameResources["players"][i].hand.append(d.dealCard())
    else:
        print("Player %(num)d wins the round and all other players draw a card"% {"num": index})
        for i in range(0, 4):
            if i != (index - 1):
                gameResources["players"][i].hand.append(d.dealCard())

def winner(gameResources):
    if gameResources["emptydeck"] == True:
        index = 0
        handsize = 100
        for i in range(0, 4):
            if len(gameResources["players"][i].hand) <= handsize:
                index = i
        print("Player %(num)d wins the game because they have the least cards" % {"num": (i + 1)})
    else:
        for i in range(0, 4):
            if len(gameResources["players"][i].hand) <= 0:
                print("Player %(num)d has ran out of cards and won the game" % {"num": (i + 1)})


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
import time
import seaborn as sns
from sklearn.feature_selection import f_classif,SelectKBest
from sklearn.model_selection import train_test_split
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import GridSearchCV
from xgboost import XGBClassifier
from sklearn.metrics import confusion_matrix
from sklearn.metrics import recall_score

# Initialising

# This section handles the generic initialisation of maximum rows and columns to be displayed when executed
# This section also sets the path for the datasets

pd.set_option('display.max_rows',None)
pd.set_option('display.max_columns',None)
os.chdir('/Users/praveenthenraj/Desktop/PycharmProjects/Trial/Hackerearth/Novartis/Data/Dataset')

# Reading the data

# This section handles reading the train,test,and sample submission file and creating respective dataframes

train=pd.read_csv('Train.csv')
test=pd.read_csv('Test.csv')
sample=pd.read_csv('sample_submission.csv')
submis=pd.DataFrame()

# Initialising Variables and Data Structures

# This section handles the initialisation of an empty list for storing the important features identified later

imp_feature=[]

# Basic Health Checks

# This section performs the basic health checks on the train and test dataframes:

print('Training Data Shape : '+str(train.shape)+'\n')                                                           #(23856, 18)
print('Testing Data Shape  : '+str(test.shape)+'\n')                                                            #(15903, 17)
print('Training Data Non-int type : '+'\n'+'\n'+str(train.dtypes!=np.int64)+'\n')                               #INCIDENT_ID,DATE,X_12
print('Testing Data Non-int type : '+'\n'+'\n'+str(test.dtypes!=np.int64)+'\n')                                 #INCIDENT_ID,DATE,X_12
print('Training Data Null Columns : '+'\n'+'\n'+str(train.isna().any())+'\n')                                   #X_12
print('Testing Data Null Columns : '+'\n'+'\n'+str(test.isna().any())+'\n')                                     #X_12
print('Count of Null Data in Train : '+'\n'+'\n'+str(train.isna().sum())+'\n')                                  #182
print('Count of Null Data in Test : '+'\n'+'\n'+str(test.isna().sum())+'\n')                                    #127
print('Balance of Dependant Variables : '+'\n'+'\n'+str(train['MULTIPLE_OFFENSE'].value_counts())+'\n')         #0-1068 1-22788
print('No of duplicates in Train Data : '+str(len(train.loc[train['INCIDENT_ID'].duplicated()]==True))+'\n')
print('No of duplicates in Train Data : '+str(len(test.loc[test['INCIDENT_ID'].duplicated()]==True))+'\n')
print('IQR for feature X_12 : '+str(train.describe()))                                                         #0.9740
print('IQR for feature X_12 : '+str(test.describe()))                                                          #0.9722

# EDA

# This section is used to create the EDA for the given datasets

# Plot 1: To identify the distribution of values in X_12 feature to impute for NaN values in train data:
# From the plot, it can be seen that 90% of X_12 value in train_data has value of 1

train['X_12'].value_counts().plot(kind='bar')
plt.xlabel('X_12_Train')
plt.ylabel('Value_counts')
plt.title('Distribution of values in X_12_Train')
plt.show()

# Plot 2: To identify the distribution of each predictor variable and their respective mean and std deviation
# This plot helps to identify the scaling range of each features

train_eda = train.iloc[:, 2:17]

for i in train_eda.columns:
    std = np.round(np.std(train[i]), 2)
    mean = np.round(np.mean(train[i]), 2)
    train[i].value_counts().plot(kind='bar',label=r'Mean    ' + ' - ' + str(mean) + '\n' + r'Std Dev' + ' - ' + str(std))
    plt.xlabel(i)
    plt.ylabel('Value_counts')
    plt.legend()
    plt.title('Distribution of Anonymized Logging parameter ' + i)
    plt.show()

# Plot 3: To identify the correlation between the various dependant variables
# This plots helps to identify the features with multicollinearity. This helps in identifying and dropping those
# features which are highly correlated.

sns.heatmap(train.corr(), annot=True)
plt.show()

# Plot 4: To identify the distribution of values in X_12 feature to impute for NaN values in test data:
# From the plot, it can be seen that the distribution in test data is similar to the train data and most
# value is 1

test['X_12'].value_counts().plot(kind='bar')
plt.xlabel('X_12_Test')
plt.ylabel('Value_counts')
plt.title('Distribution of values in X_12_Test')
plt.show()

# From the above plot it can be seen that the following pairs are highly correlated with each other and hence
# both features can be dropped in case of low variance test score(which will be done later below) or either
# feature will be dropped in case of high variance test score.

# (X_2,X_3)   - correlation of 1 (multicollinear)
# (X_10,X_12) - correlation of 0.88 (multicollinear)

# Feature Preprocessing and Feature Transformation:

# This section handles preprocessing of the input dataset like filling the missing values.
# From the given datasets it is found that only feature X_12 has missing values in both train and test dataset.
# Filling the na values with 1 as Plot_1 suggested that X_12 has maximum number of values as 1 and also a
# mean of values in X_12 in train and test data is 0.9740 and 0.9722 respectively
# We are considering mean to fill Nan values, because from plot1 and plot 4 we can see that the distribution
# of data in feature X_12 is right skewed. Considering the central tendency measure mean for
# such distributions is a better approach.

def feature_preprocess_transformation(data):
    global train,test
    data['X_12']=data['X_12'].fillna(value=1.0).astype(int)

# Calling the preprocessing function for Train and Test Data
# Functions to fill the missing values in train and test dataset

feature_preprocess_transformation(train)
feature_preprocess_transformation(test)

# Feature Importance and Train_Test Data Split
# This section handles identifying the important features and splitting the training data as train_test split
# to train and validate the model

# Here the feature incident_id has been dropped because it does not hold any cause for the cyber attack.
# The feature MULTIPLE_OFFENSE has been dropped as it is the target variable

indep=train.drop(['INCIDENT_ID','DATE','MULTIPLE_OFFENSE'],axis=1).values
dep=train['MULTIPLE_OFFENSE'].values

# Here we are doing an ANNOVA TEST to identify the feature importance with respect to the target variable
# ANNOVA Test is chosen, as the independant variables are continous variables whereas the output variables are
# categorical

x=SelectKBest(score_func=f_classif,k='all').fit(indep,dep)
fs=x.transform(indep)
for i in range(len(x.scores_)):
    print('Feature %d: %f' % (i, x.scores_[i]))
    imp_feature.append(i)

#Result of the ANNOVA test:

#X_1: 4.698824
#X_2 17.782549
#X_3: 17.684310
#X_4: 0.203579
#X_5 0.283907
#X_6 1.489952
#X_7: 1.540444
#X_8: 26.635719
#X_9: 0.013363
#X_10: 1491.658800
#X_11: 266.372662
#X_12: 308.553593
#X_13: 1.011512
#X_14: 5.560878
#X_15: 48.221174

# Selecting only features having annova score of atleast more than 20

print([i for i in range(len(x.scores_)) if x.scores_[i]>20])

# Dropping features having ANNOVA score less than 20 and also features that are correlated based on the EDA done earlier

#'X_1','X_4','X_5','X_6','X_7','X_9','X_13','X_14' --- dropped due to low ANNOVA score
#'X_2','X_12'  --- dropped due to interaction effect between these variables and X_3,X_10 respectively

X=train.drop(['INCIDENT_ID','DATE','X_1','X_2','X_4','X_5','X_6','X_7','X_9','X_12','X_13','X_14','MULTIPLE_OFFENSE'],axis=1).values
y=train['MULTIPLE_OFFENSE'].values

# From the basic health checks done earlier it can be seen that the training dataset is an imbalanced dataset
#Below shows the distribution of each class in the training dataset.
            #0-1068
            #1-22788

# SMOTE technique is selected to upsample the minority target class

sm=SMOTE(sampling_strategy='minority',random_state=2)
X_train_sm,y_train_sm=sm.fit_sample(X,y.ravel())
print(X_train_sm.shape)
print(y_train_sm.shape)
print(y_train_sm.value_counts())

# From above, it can be seen that the minority class '0' has been upsampled

# Splitting the training dataset(after SMOTE) into train-test dataset to train the model and validate the model against
#the test data

X_train,X_test,y_train,y_test=train_test_split(X_train_sm,y_train_sm,test_size=0.2,stratify=y_train_sm,random_state=20)

# Hyperparameter Tuning

# Initially the below set of learning_rate and n_estimatores were tried to find the best values

#l=[0.001,0.005,0.01,0.05,0.1,0.5]
#n=[i for i in range(100,1000,100)]

# From the above set it was identified that the best value for learning_rate is 0.5
# and estimators as 100 for the model.
# Hence learning_rate and n_estimators was narrowed down around 0.5 and 100 respectively and hence
# a GridSearchCV in the range of 0.5-0.8 and 100-120 was applied for learning_rate and n_estimators
# respectively

# Below are the final set of hyperparameters selected to tune the model to identify the best
# possible hyperparameters.

#l=[i for i in np.arange(0.5,0.8,0.01)]
#n=[i for i in range(100,120,1)]
#md=[i for i in np.arange(3,8,1)]
#rl=[i for i in np.arange(0,1,0.1)]

#param={'learning_rate':l}
#param={'n_estimators':n}
#param={'n_estimators':n,'max_depth':md}
#param={'reg_lambda':rl}

# A GridSearchCV was chose for trying out the various combinations of hyperparameters on the model.
# GridSearchCV was selected over other methods like RandomSearch as the intention was not to miss the
# local/global minima by missing a particular parameter during optimisation

# XGBoost model has been selected to classify the datapoints due to the below considerations.
          # Decision tree based models are proven to perform better on classification problems
          # Boosting techniques like XGBoost is preferred over traditional Decision Trees because
          #    in boosting algorithms, we combine a set of weak learners to form a strong model thus
          #    improving the performance of the model.
          # XGBoost model is chosen over other boosting model like Gradient Boosting as XGBoost has
          #    inbuilt L1 and L2 regularization which prevents overfitting of the model which is
          #    prone to happen espicially during classification using decision tree based algorithms.

#xgb1=XGBClassifier()
#xgb=GridSearchCV(xgb1,param_grid=param,cv=5)
#xgb.fit(X_train,y_train)
#print(xgb.best_params_)
#print(xgb.best_estimator_)
#y_pred=xgb.best_estimator_.predict(X_test)

# Model

# Based on the above hyperparameter tuning the below parameters have found to be precise for the given model

xgb=XGBClassifier(learning_rate=0.7200000000000001,max_depth=3,n_estimators=100,reg_lambda=0.1)
xgb.fit(X_train,y_train)
y_pred=xgb.predict(X_test)

tn,fp,fn,tp=confusion_matrix(y_test,y_pred).ravel()
recall=recall_score(y_test,y_pred)
print(recall)
print(tn,fp,fn,tp)

# Processing the test file

X_sub=test.drop(['INCIDENT_ID','DATE','X_1','X_2','X_4','X_5','X_6','X_7','X_9','X_12','X_13','X_14'],axis=1).values                           #Dropping features having Annova score less than 1. X_3 dropped even score is 17 as its score is same as X_2
y_sub=xgb.predict(X_sub)

# Preparing the submission file

submis['INCIDENT_ID']=test['INCIDENT_ID']
submis['MULTIPLE_OFFENSE']=y_sub
submis.to_csv('outfile.csv',index=False)


def make_clean_figure(figsize, remove_tooltips=False, remove_keybindings=False):
    """
    Makes a `matplotlib.pyplot.Figure` without tooltips or keybindings

    Parameters
    ----------
    figsize : tuple
        Figsize as passed to `matplotlib.pyplot.figure`
    remove_tooltips, remove_keybindings : bool
        Set to True to remove the tooltips bar or any key bindings,
        respectively. Default is False

    Returns
    -------
    fig : `matplotlib.pyplot.Figure`
    """
    tooltip = mpl.rcParams['toolbar']
    if remove_tooltips:
        mpl.rcParams['toolbar'] = 'None'
    fig = pl.figure(figsize=figsize)
    mpl.rcParams['toolbar'] = tooltip
    if remove_keybindings:
        fig.canvas.mpl_disconnect(fig.canvas.manager.key_press_handler_id)
    return fig


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Thu Jun  7 11:26:56 2018

@author: florian
"""

from __future__ import print_function

import numpy as np
import matplotlib.pyplot as plt
from snad import OSCCurve, GPInterpolator
from sklearn.gaussian_process import kernels
import snad.process.band_transformation as bt

def plot_lc_trans(sn_list, init_bands):
    """
    Plot the light curves after transformation for a Sn using both system of filter (Jhson and gri or g'r'i')

    Parameters
    ----------
    sn_list : list contains Sn to test the transformation
    init_bands : list contains initial bands used to transform to the new system
    """
    for sn_name in sn_list:
        bands_jhonson = init_bands.split(',')
        bands_gri = "g,r,i".split(',')
        k1 = kernels.RBF(length_scale_bounds=(1e-4, 1e4))
        k2 = kernels.RBF(length_scale_bounds=(1e-4, 1e4))
        # k2 = kernels.WhiteKernel()
        # k3 = kernels.ConstantKernel(constant_value_bounds='fixed')
        k3 = kernels.WhiteKernel()

        m = np.array([[1, 0, 0],
                      [0.5, 1, 0],
                      [0.5, 0.5, 1]])
        m_bounds = (np.array([[1e-4, 0, 0],
                              [-1e2, -1e3, 0],
                              [-1e2, -1e2, -1e3]]),
                    np.array([[1e4, 0, 0],
                              [1e2, 1e3, 0],
                              [1e2, 1e2, 1e3]]))
#        m = np.zeros((2,2)); m[0, 0] = 1
#        m = np.array([[1, 0],
#                      [0.5, 1]])
#        m_bounds = (np.array([[1e-4, 0],
#                              [-1e2, -1e3]]),
#                    np.array([[1e4, 0],
#                              [1e2, 1e3]]))
#
        colors = {'B':'b','V':'y' ,'R':'r', 'I':'brown',"g'": 'g', "r'": 'r', "i'": 'brown','g':'g','r':'r','i': 'brown'}

        curve = OSCCurve.from_name(sn_name, bands=bands_jhonson).binned(bin_width=1, discrete_time=True).filtered(sort='filtered')
        x_ = np.linspace(curve.X[:,1].min(), curve.X[:,1].max(), 101)
        interpolator = GPInterpolator(
            curve, (k1, k2, k3), m, m_bounds,
            optimize_method=None,  #'trust-constr',
            n_restarts_optimizer=0,
            random_state=0,
            add_err=10,
            raise_on_bounds=False
        )

        msd = interpolator(x_)

        for i, band in enumerate(bands_jhonson):
            plt.subplot(2, 2, i+1)
            blc = curve[band]
            plt.errorbar(blc['x'], blc['y'], blc['err'], marker='x', ls='', color=colors[band])
            plt.plot(msd.odict[band].x, msd.odict[band].y, color=colors[band], label=band)
            plt.grid()
            plt.legend()
            pdffile = '../plot/lc_BVRI_'+sn_name+'.pdf'
            plt.savefig(pdffile, bbox_inches='tight')
        plt.show()
#        if 'V' in bands_jhonson:
#            new_msd = bt.VR_to_gri(msd)
#        else:
#            new_msd = bt.BR_to_gri(msd)

        new_msd = bt.BRI_to_gri(msd)
        curve2 = OSCCurve.from_name(sn_name, bands=bands_gri).binned(bin_width=1, discrete_time=True).filtered(sort='filtered')
        print(new_msd.odict.keys())
        for i, band in enumerate(bands_gri):
            plt.subplot(2, 2, i+1)
            blc = curve2[band]
            plt.errorbar(blc['x'], blc['y'], blc['err'], marker='x', ls='', color=colors[band])
            plt.plot(new_msd.odict[band].x, new_msd.odict[band].y, color=colors[band], label=band)
            plt.grid()
            plt.title(sn_name)
            pdffile = '../plot/lc_BVRI_gri_'+sn_name+'.pdf'
            plt.savefig(pdffile, bbox_inches='tight')
            plt.legend()
        plt.show()

if __name__=='__main__':

#    sn_list = ['SN2013fs', 'LSQ13zm', 'SN2013ej','SN2004dt', 'SN2009dc', 'SN2009dc'] #BR gri
#    sn_list = ['SN2013gh', 'ASASSN-13ax', 'SN2004gv','SN2016eay','iPTF13bvn','SN2004eo','SN2005el','SN2006hb'] #VR gri
#    sn_list = ['SN2011bm' ,'SN2011hs' ,'SN2010gx' ,'SN2009ib' ,'SN2007fr' ,'SN2006fo' ,'SN2008ax' ,'SN2009N' ,'SN2005hk' ] #BR g'r'i'
#    sn_list = ['SN2015bn','SN2011bm','SN2011hs','SN2013bh','SN2009ib','SN2006fo','SN2008ax','SN2009N','SN2005hk'] #VR g'r'i'

    sn_list =['SN2007bc','ASASSN-13ax','SN2013ej','SN2005am','SN2005M','SN2013fs'] #BRI gri
    init_bands = 'B,R,I'
    plot_lc_trans(sn_list, init_bands)


#%%
# natural language processing module (Extractor)
import spacy
from spacy.matcher import Matcher
from spacy.matcher import PhraseMatcher

# search engine
from whoosh.qparser import QueryParser
import whoosh.index as index
from whoosh.index import open_dir
from whoosh.query import Every

# library for list manipulation
import itertools

# library for context graph
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np

nlp = spacy.load('en_core_web_sm')

def extractor(document, *pattern):
    '''
    @param str file: text file for tuple extraction
    @param list pattern: extraction pattern
    A phrase extractor based on spacy
    '''
    phrases = []
    matcher = Matcher(nlp.vocab)
    matcher.add("pattern extraction", None, *pattern)
    doc = nlp(document)
    matches = matcher(doc)
    for match_id, start, end in matches:
        string_id = nlp.vocab.strings[match_id]  # Get string representation
        span = doc[start:end]  # The matched span
        phrases.append(span.text)
    return phrases

def partition(file, size = 1000000):
    '''
    partition the input file into block with maximum size of 1000000, since SpaCy v2.x parser may have issues allocating memory with size larger than 1000000
    '''
    while True:
        data = file.read(size).lower()
        if not data:
            break
        yield data

#%%
def getPhrases(file, context_pattern):
    new_phrases = set()
    with open(file, 'r') as f:
        t = f.read().lower()
        matcher = Matcher(nlp.vocab)
        doc = nlp(t)
        for cp in context_pattern:
            matcher.add("extraction", None, cp)
            matches = matcher(doc)
            for match_id, start, end in matches:
                span = doc[start+2:end].text
                if span not in new_phrases:
                    new_phrases.add(span)
            matcher.remove("extraction")
    return new_phrases

def patternSearch(T_0, file):
    phrase_patterns = set()
    seed_pattern = [nlp(x) for x in T_0]
    phrase_matcher = PhraseMatcher(nlp.vocab)
    phrase_matcher.add('pattern search', None, *seed_pattern)
    # find occurrences of seed phrases
    with open(file, "r") as f:
        document = nlp(f.read().lower())
        matches = phrase_matcher(document)
        for match_id, start, end in matches:
            p = tuple((start, end))
            if p not in phrase_patterns:
                phrase_patterns.add(p)
    # find patterns around seed phrases
    unranked_patterns = []
    with open(file, "r") as f:
        text = nlp(f.read().lower())
        for phrase_pattern in phrase_patterns:
            start = phrase_pattern[0]
            end = phrase_pattern[1]
            if (text[start - 1].text == '\n'):
                continue
            # add context pattern
            tmp = []
            for i in range(2, 0, -1):
                tmp.append({"TEXT": text[start - i].text})
            # add content pattern
            span = text[start:end]
            for token in span:
                tmp.append({"POS": token.pos_})
            if tmp not in unranked_patterns:
                unranked_patterns.append(tmp)
                print(tmp)
    unranked_phrases = list(getPhrases(file, unranked_patterns))
    # build context graph
    context_graph = nx.Graph()
    # add tuples and patterns into graph
    for i in range(len(unranked_phrases)):
        node = 't' + str(i)
        context_graph.add_node(node, pos=(0, i))
    for i in range(len(unranked_patterns)):
        node = 'p' + str(i)
        context_graph.add_node(node, pos=(2, i))
    context_matrix = np.zeros((len(unranked_phrases), len(unranked_patterns)))
    # find c (t, p)
    with open(file, 'r') as f:
        t = f.read().lower()
        matcher = Matcher(nlp.vocab)
        doc = nlp(t)
        for i in range(len(unranked_patterns)):
            matcher.add("extraction", None, unranked_patterns[i])
            matches = matcher(doc)
            for match_id, start, end in matches:
                span = doc[start+2:end].text
                j = unranked_phrases.index(span)
                context_matrix[j, i] += 1
            matcher.remove("extraction")
    # add context nodes into graph
    c_count = 0
    for i in range(context_matrix.shape[0]):
        for j in range(context_matrix.shape[1]):
            if context_matrix[i, j] != 0:
                occur = context_matrix[i, j]
                node_t = 't' + str(i)
                node_p = 'p' + str(j)
                node_c = 'c' + str(c_count)
                c_count += 1
                context_graph.add_node(node_c, pos=(1, c_count))
                context_graph.add_edge(node_t, node_c, weight=occur)
                context_graph.add_edge(node_c, node_p, weight=occur)
    # draw context graph
    plt.figure()
    pos=nx.get_node_attributes(context_graph,'pos')
    nx.draw(context_graph, pos, with_labels=True)
    labels = nx.get_edge_attributes(context_graph, 'weight')
    nx.draw_networkx_edge_labels(context_graph,pos,edge_labels=labels)
    # return patterns
    return unranked_phrases

#%%
seed = set(['multimedia data types', 'database system', 'cryptographic algorithm'])
new_phrases = patternSearch(seed, 'small.txt')
new_new_phrases = patternSearch(new_phrases, 'small.txt')
# print(context_p)
print(new_phrases)
print(new_new_phrases)

#%%
seed = set(['multimedia data types', 'database system', 'cryptographic algorithm'])
new_phrases = patternSearch(seed, 'small.txt')
new_new_phrases = patternSearch(new_phrases, 'small.txt')
# print(context_p)
print(new_phrases)
print(new_new_phrases)

# %%


import matplotlib.pyplot as plt

friends = [70,65,72,63,71,64,60, 64,67]
minuts = [175,170,205,120,220,130,105,145,190]
labels = ['a','b','c','d','e','f','g','h','i']

plt.scatter(friends,minuts)

for l,f,m in zip(labels,friends,minuts):
    plt.annotate(l,xy=(f,m), xytext=(5,-5), textcoords='offset points')
plt.ax
plt.show()


import numpy
from numba import njit
from The_Treachery_of_Whales import DATA

def partOne(data: list, minimum: int=None, maximum: int=None) -> int:
    if not minimum or not maximum:
        minimum: int = min(data) if not minimum else minimum
        maximum: int = max(data) if not maximum else maximum

    fuel_calc: dict = {}
    for endPoint in range(minimum, maximum + 1):
        fuel_calc[endPoint] = 0
        for startPoint in data:
            fuel_calc[endPoint] += abs(endPoint - startPoint)

    return min([position for position in fuel_calc.values()])

@njit
def partTwo(data: list, minimum: int=0, maximum: int=0) -> int:
    if not minimum or not maximum:
        minimum: int = min(data) if minimum == 0 else minimum
        maximum: int = max(data) if maximum == 0 else maximum

    fuel_calc: dict = {}
    for endPoint in numpy.arange(minimum, maximum + 1, dtype=numpy.int64):
        fuel_calc[endPoint] = 0
        for startPoint in data:
            difference: int = numpy.fabs(startPoint - endPoint)
            # Gauss Method: Sn = 1/2 * abs(begin-end) * (abs(begin-end) + 1)
            fuel_calc[endPoint] += int(0.5 * difference * (difference + 1))

    return min([position for position in fuel_calc.values()])

def main() -> None:
    print(partOne(DATA))

    partTwo(numpy.array([0], dtype=numpy.int64)) # partTwo Numba initialisation
    print(partTwo(numpy.array(DATA, dtype=numpy.int64)))

if __name__ == "__main__":
    main()

2021/Day 7/Day 7 - The Treachery of Whales.py


import sys
from bs4 import BeautifulSoup
import requests

BASE_URL = 'http://admission.cuas.or.th/%s/toppage.html'
MAJOR_URL = 'http://admission.cuas.or.th/%s/search_fac.php?q='

def extract_options(html):
    html.encoding = 'tis-620'
    soup = BeautifulSoup(html.text, 'html.parser')
    return soup.find('select').find_all('option')

def extract_major_name(str):
    items = str.split()
    return ' '.join(items[1:])

def main():
    if len(sys.argv) != 2:
        year_prefix = 'adm60maxmn'
    else:
        year_prefix = sys.argv[1]

    main_url = BASE_URL % (year_prefix,)

    html = requests.get(main_url)
    for opt in extract_options(html):
        uname = opt.text.strip()
        unumber = opt.attrs['value']

        if unumber == '000':
            continue

        major_query_url = (MAJOR_URL % (year_prefix,)) + unumber

        major_html = requests.get(major_query_url)
        majors = extract_options(major_html)
        for m in majors:
            mname = extract_major_name(m.text.strip())
            mnumber = m.attrs['value']

            if mnumber == '0000':
                continue

            items = [mnumber, mname, unumber, uname]
            print(','.join(['"%s"' % s for s in items]))

if __name__=='__main__':
    main()


def prime_number(n):
    if n<=0:
        return "Input positive number, please"
    elif n == 1:
        return []
    elif n == 2:
        return [2]
    else:
        primeNum = [2, 3]
        for i in range(3, n+1):
            if i % 2 != 0 and i % 3 != 0:
                primeNum.append(i)
        return primeNum

print(prime_number(6))


from src.hr import (
    SalaryPolicy,
    HourlyPolicy,
    CommissionPolicy
)

from src.productivity import (
    ManagerRole,
    SecretaryRole,
    SalesPersonRole,
    FactoryWorkerRole
)

class Employee:
    def __init__(self, id: int, name: str):
        self.id = id
        self.name = name

class Manager(Employee, ManagerRole, SalaryPolicy):
    def __init__(self, id, name, weekly_salary):
        SalaryPolicy.__init__(self, weekly_salary)
        Employee.__init__(self, id, name)

class Secretary(Employee, SecretaryRole, SalaryPolicy):
    def __init__(self, id, name, weekly_salary):
        SalaryPolicy.__init__(self, weekly_salary)
        Employee.__init__(self, id, name)

class SalesPerson(Employee, SalesPersonRole, CommissionPolicy):
    def __init__(self, id, name, weekly_salary, commission):
        CommissionPolicy.__init__(self, weekly_salary, commission)
        Employee.__init__(self, id, name)

class FactoryWorker(Employee, FactoryWorkerRole, HourlyPolicy):
    def __init__(self, id, name, hours_worked, hourly_rate):
        HourlyPolicy.__init__(self, hours_worked, hourly_rate)
        Employee.__init__(self, id, name)

class TemporarySecretary(Employee, SecretaryRole, HourlyPolicy):
    def __init__(self, id, name, hours_worked, hourly_rate):
        HourlyPolicy.__init__(self, hours_worked, hourly_rate)
        Employee.__init__(self, id, name)


import os
from pathlib import Path
import sys

import numpy as np
import pytorch_lightning as pl
import torch
from torch.utils.data import Dataset
from torch.utils.data.dataloader import DataLoader

from diffae.data_utilities.io import load_audio, log_mel_spectrogram

class MusicDataset(Dataset):
    def __init__(self,
                 split: str,
                 dataset_path: str,
                 sample_rate: int = 16_000,):
        # Store split
        assert split in ["train", "val", "test"]
        self.split = split

        path = Path(dataset_path)
        self.data_dir = path.parent.absolute()

        # Read data
        with open(dataset_path, "r") as f:
            lines = f.readlines()
        if split == "train":
            self.data = lines[:int(0.9*len(lines))]
        elif split == "val" or split == "test":
            self.data = lines[int(0.9*len(lines)):]
        else:
            raise ValueError()

        self.sample_rate = sample_rate

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

    def _random_cut(self, audio, max_length: int = 10):
        """ audio: audio waveform
            max_length: maximum length of the cut in seconds
        """
        max_length_sample = self.sample_rate*max_length
        if len(audio) < max_length_sample:
            return None
        start = np.random.randint(0, len(audio) - max_length_sample)
        return audio[start : start + max_length_sample]

    def __getitem__(self, idx):
        idx = idx % len(self.data)
        audio_path = os.path.join(self.data_dir, self.data[idx]).strip()

        try:
            audio = load_audio(audio_path)
            audio = self._random_cut(audio)
            mel = log_mel_spectrogram(audio)
        except Exception as e:
            print("Error processing audio file:", audio_path)
            return self.__getitem__(idx + 1)

        # Return if something is not ok
        if torch.isnan(mel).any():
            return self.__getitem__(idx + 1)

        # Spec augment
        return {
            "mel": mel,
        }

class MusicDatamodule(pl.LightningDataModule):
    def __init__(self,
                 dataset_path,
                 batch_size,
                 n_workers=4) -> None:
        super().__init__()
        self.dataset_path = dataset_path
        self.batch_size = batch_size
        self.n_workers = n_workers

    def train_dataloader(self):
        return DataLoader(
            MusicDataset(split="train",
                        dataset_path=self.dataset_path,),
                        n_workers=self.n_workers,
                        batch_size=self.batch_size,
                        shuffle=True,)

    def val_dataloader(self):
        return DataLoader(
            MusicDataset(split="val",
                        dataset_path=self.dataset_path,),
                        n_workers=self.n_workers,
                        batch_size=self.batch_size,
                        shuffle=True,)

    def test_dataloader(self):
        return self.val_dataloader()  # TODO(Oleguer): Test dataloader?

if __name__ == "__main__":
    # Test
    dataset = MusicDataset(split="train",
                           dataset_path="/home/mary/code/diffusion_autoencoder/data/data.lst",
                           sample_rate=16_000)
    dataloader = DataLoader(dataset,
                            batch_size=2,
                            shuffle=True,
                            num_workers=4)
    for batch in dataloader:
        print(batch["mel"].shape)
        break


def vagrant_settings(self, name='', *args, **kwargs):
        """
        Context manager that sets a vagrant VM
        as the remote host.

        Use this context manager inside a task to run commands
        on your current Vagrant box::

            from burlap.vagrant import vagrant_settings

            with vagrant_settings():
                run('hostname')
        """
        config = self.ssh_config(name)

        extra_args = self._settings_dict(config)
        kwargs.update(extra_args)

        return self.settings(*args, **kwargs)