from functools import lru_cache
from deap import creator, base, tools, algorithms
import random
import numpy as np
import os
import logging
import dask.dataframe as dd
from csci_final_project.dataloader import filehandler

creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)

class GeneticAlgorithm:
    """
    The Genetic algorithm optimizer
    """

    def __init__(self, filename, filepath, target_name="pnl"):
        self.data = filehandler.loadCSV(filename, filepath)
        self.target_name = target_name
        self.results = []
        self.filename = filename
        self.filepath = filepath

    def _calculate_metrics(self, data):
        """The objective function metrics"""
        if len(data) > 0:
            return data[self.target_name].sum().compute()
        return 0

    @lru_cache(maxsize=100000)
    def _ga_optimize(self, parameter_values: tuple):
        """
        Here I use lru cache to memorize the parameter combinations that have searched before
        """
        ind = dict(parameter_values)
        data_filtered = dd.from_pandas(
            self.data, npartitions=max(1, os.cpu_count() - 1)
        )
        for col, val in ind.items():
            lower = val[0]
            upper = val[1]
            data_filtered = data_filtered.loc[
                (data_filtered[col] > lower) & (data_filtered[col] <= upper)
            ]

        return (self._calculate_metrics(data_filtered),)

    def _evaluate(self, parameter_values: list):
        return self._ga_optimize(tuple(parameter_values))

    def run_optimization(self, optimization_setting, population_size=100, ngen_size=30):
        """
        The entry point to run optimization
        """  # Get optimization setting and target
        settings = optimization_setting.generate_setting_ga()
        self.target_name = optimization_setting.target_name

        # Define parameter generation function
        def generate_parameter():
            return random.choice(settings)

        def mutate_individual(individual, indpb):
            size = len(individual)
            paramlist = generate_parameter()
            for i in range(size):
                if random.random() < indpb:
                    individual[i] = paramlist[i]
            return (individual,)

        # Set up genetic algorithem
        toolbox = base.Toolbox()
        toolbox.register(
            "individual", tools.initIterate, creator.Individual, generate_parameter
        )
        toolbox.register("population", tools.initRepeat, list, toolbox.individual)
        toolbox.register("mate", tools.cxTwoPoint)
        toolbox.register("mutate", mutate_individual, indpb=1)
        toolbox.register("evaluate", self._evaluate)
        toolbox.register("select", tools.selNSGA2)

        total_size = len(settings)
        pop_size = population_size  # number of individuals in each generation
        lambda_ = pop_size  # number of children to produce at each generation
        mu = int(
            pop_size * 0.8
        )  # number of individuals to select for the next generation

        cxpb = 0.95
        mutpb = 1 - cxpb
        ngen = ngen_size

        pop = toolbox.population(pop_size)
        hof = tools.ParetoFront()

        stats = tools.Statistics(lambda ind: ind.fitness.values)
        # np.set_printoptions(suppress=True)
        stats.register("mean", np.mean, axis=0)
        stats.register("std", np.std, axis=0)
        stats.register("min", np.min, axis=0)
        stats.register("max", np.max, axis=0)

        # Run ga optimization
        logging.info(f"total size：{total_size}")
        logging.info(f"population size：{pop_size}")
        logging.info(f"individuals for the next generation：{mu}")
        logging.info(f"number of generation：{ngen}")
        logging.info(f"probability of mating two individuals：{cxpb:.0%}")
        logging.info(f"probability of mutating an individual：{mutpb:.0%}")

        algorithms.eaMuPlusLambda(
            pop, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats, halloffame=hof
        )

        # Return result list
        results = []

        for parameter_values in hof:
            setting = dict(parameter_values)
            target_value = self._evaluate(parameter_values)
            results.append((setting, target_value, {}))

        self.results = results
        logging.info(f"Best signal combination {results[0]} ")
        return results

    def output_data_best_signal(self, output_filename):
        """
        Output optimized data to csv
        """
        data_filtered = self.data.copy()
        for col, val in self.results[0][0].items():
            lower = val[0]
            upper = val[1]
            data_filtered = data_filtered.loc[
                (data_filtered[col] > lower) & (data_filtered[col] <= upper)
            ]
        filehandler.saveCSV(data_filtered, output_filename, self.filepath)

# from csci_final_project.optimizer.setting import OptimizationSetting
# setting = OptimizationSetting()
# setting.set_target('pnl')
# setting.add_parameter('signal_1', start=0, end=1, step=0.5)
# setting.add_parameter('signal_2', start=0, end=1, step=0.5)
#
# ga = GeneticAlgorithm(filename='sample.csv', filepath='/Users/xiaotan/Course/2020fa-csci_final_project-tanxiao64/data/')
# print(ga.run_optimization(setting))
# ga.output_data_best_signal('best.csv')


import datetime, os, re, threading, time
from threading import Lock
#
# LOCAL IMPORTS
#
import ControlError
import ControlUtil
from Logger import Logger
from InventoryTask_NMAP import NMAP_TASK
from InventoryTask_WMI import WMI_TASK
from InventoryTask_LDAP import LDAP_TASK
from InventoryTask_OCS import OCS_TASK
from InventoryTask_Nagios import NAGIOS_TASK
import Utils

#
# GLOBAL VARIABLES
#
logger = Logger.logger
class InventoryManager(object):

    def __init__(self,fmkip,fmkport):
        self.__inventory = None
        self._fmkip = fmkip
        self._fmkport = fmkport
        if self.__inventory == None:
            self.__inventory = DoInventory()
            self.__inventory.start()
            self.__taskRegex = re.compile("task_name=(?P<task_name>[^,]+),task_type=(?P<task_type>[^,]+),task_type_name=(?P<task_type_name>[^,]+),task_params=(?P<task_params>.*),task_period=(?P<task_period>[^,]+),task_reliability=(?P<task_reliability>[^,]+),task_enable=(?P<task_enable>[^,]+)")

    def process(self, data, base_response):
        logger.info("Inventory Manager: Processing: %s" % data)
        response = []
        action = Utils.get_var("action=\"([A-Za-z_]+)\"", data)
        if action == "refresh_inventory_task":
            tmp_tasks = Utils.get_var("inventory_task_list=\{(?P<task_list>.*)\}", data)
            task_list = tmp_tasks.split('|')
            inventory_task_list = []
            for task in task_list:
                task_values = self.__taskRegex.match(task)
                if task_values:
                    groupdict = task_values.groupdict()
                    if groupdict['task_type_name'].lower() =='nmap':
                        inventory_task_list.append(NMAP_TASK(groupdict['task_name'], \
                                                             groupdict['task_params'], \
                                                             groupdict['task_period'], \
                                                             groupdict['task_reliability'], \
                                                             groupdict['task_enable'], \
                                                             groupdict['task_type'],\
                                                             groupdict['task_type_name']))
                    elif groupdict['task_type_name'].lower() =='wmi':
                        inventory_task_list.append(WMI_TASK(groupdict['task_name'], \
                                                             groupdict['task_params'], \
                                                             groupdict['task_period'], \
                                                             groupdict['task_reliability'], \
                                                             groupdict['task_enable'], \
                                                             groupdict['task_type'],\
                                                             groupdict['task_type_name']))
                    elif groupdict['task_type_name'].lower() =='ldap':
                        inventory_task_list.append(LDAP_TASK(groupdict['task_name'], \
                                                             groupdict['task_params'], \
                                                             groupdict['task_period'], \
                                                             groupdict['task_reliability'], \
                                                             groupdict['task_enable'], \
                                                             groupdict['task_type'],\
                                                             groupdict['task_type_name']))
                    elif groupdict['task_type_name'].lower() =='ocs':
                        inventory_task_list.append(OCS_TASK(groupdict['task_name'], \
                                                             groupdict['task_params'], \
                                                             groupdict['task_period'], \
                                                             groupdict['task_reliability'], \
                                                             groupdict['task_enable'], \
                                                             groupdict['task_type'],\
                                                             groupdict['task_type_name'],\
                                                             self._fmkip,\
                                                             self._fmkport))
                    elif groupdict['task_type_name'].lower() =='nagios':
                        inventory_task_list.append(NAGIOS_TASK(groupdict['task_name'], \
                                                             groupdict['task_params'], \
                                                             groupdict['task_period'], \
                                                             groupdict['task_reliability'], \
                                                             groupdict['task_enable'], \
                                                             groupdict['task_type'],\
                                                             groupdict['task_type_name'],\
                                                             self._fmkip,\
                                                             self._fmkport))
                    else:
                        logger.warning("task not implemented:%s" % groupdict['task_type_name'])
                else:
                    logger.warning("Invalid task: %s" % task)
            self.__inventory.set_tasks(inventory_task_list)
            response.append(base_response + ' status="%d" %s ackend\n' % (0, ControlError.get(0)))
        else:
            response.append(base_response + ' %s ackend\n' % ControlError.get(2002))
        return response

class DoInventory (threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self._keepWorking = True
        self._taskListMutex = Lock()
        self._taskList = []
        self._updatingTaskList = threading.Event()
        self._workingEvent = threading.Event()
    def set_tasks(self, tasklist):
        '''
        Set the inventory task list.
        '''
        self._taskListMutex.acquire()
        while self._workingEvent.isSet():
            logger.info("Waiting to finish current work before updating the task list")
            time.sleep(1)
        logger.info("Updating task list..")
        self._updatingTaskList.set()
        del self._taskList[:]
        self._taskList = tasklist
        self._updatingTaskList.clear()
        self._taskListMutex.release()

    def _run_task(self, task):

        if not task.isEnable() or not task.isValid():
            return
        current_time = time.time()
        period = task.getPeriod()
        last_run = task.getLastRun()
        elapsed_time = current_time - last_run
        if elapsed_time>period and not task.get_running():
            logger.info("Running task...%s - Period:%s" % (task.getTaskName(),task.getPeriod()))
            task.doJob()
            task.updateLastRun()

    def run(self):

        while self._keepWorking:
            if not self._updatingTaskList.isSet():
                self._workingEvent.set()
                for task in self._taskList:
                    #logger.info("Try running task: %s" % task.getTaskName())
                    self._run_task(task)
                self._workingEvent.clear()
            else:
                logger.info("Waiting to update..")
            time.sleep(10)


"""Advent of Code 2019, day 21: https://adventofcode.com/2019/day/21"""
import logging

from advent_of_code.aoc2019.intcode import IntcodeMachine
from advent_of_code.base import Solution

log = logging.getLogger("aoc")

class AocSolution(Solution[int, int]):
    def __init__(self, **kwargs):
        super().__init__(21, 2019, **kwargs)

    def run_springscript(self, script: list[str]) -> int:
        with self.open_input() as f:
            program = IntcodeMachine.read_buffer(f)
        script_bytes = ("\n".join(script) + "\n").encode("ASCII")
        machine = IntcodeMachine(program, iter(script_bytes))
        result = list(machine.run())
        if result[-1] == 10:
            log.debug(bytes(result).decode("ASCII"))
            raise SpringScriptError()
        return result[-1]

    def solve_part_one(self) -> int:
        script = [
            "OR D J",  # Jump if we can.
            "OR A T",  # Unless...
            "AND B T",
            "AND C T",
            "NOT T T",
            "AND T J",  # A, B, and C are all True.
            "WALK",
        ]
        return self.run_springscript(script)

    def solve_part_two(self) -> int:
        script = [
            "OR D J",  # Jump if we can.
            "OR A T",  # Unless...
            "AND B T",
            "AND C T",
            "NOT T T",
            "AND T J",  # A, B, and C are all True.
            "NOT A T",  # (Reset T -> False)
            "AND A T",
            "OR E T",  # Or...
            "OR H T",
            "AND T J",  # E and H are both False.
            "RUN",
        ]
        return self.run_springscript(script)

class SpringScriptError(Exception):
    ...


from sys import stdin
global lis
# Determine if the K-solution is viable
def validBoard(sParcial, phase,m):
    isValid = True
    for x in range(0, phase):
        if sParcial[x] == sParcial[phase] or abs(sParcial[x] - sParcial[phase]) == abs(x - phase):
            isValid = False
            break
    return isValid

#Use backtracking to iterate over all posible solutions
def bactrackNQueens(sParcial, phase, N,m,matriz):
    if phase < N:
        global c
        #print('=============== ETAPA %d %s =============' % (phase, str(sParcial)))
        for x in range(N):
            sParcial[phase] = x
            #print(sParcial)
            if validBoard(sParcial[:], phase,m)  and (x,phase) not in matriz:
                if phase < N-1:
                    bactrackNQueens(sParcial[:], phase + 1, N,m,matriz)
                    #print('=============== BACTRACK %s ============' % (str(sParcial)))
                else:
                    #print('=============== SOLUCION ===============')
                    c+=1
                    #print(sParcial)

                    #print('========================================')

# Initialize phase Zero in order to solve n-queens using backtracking
def solveNQueens(N,m,matriz):
    global c
    sParcial, phase = [int(-1) for x in range(0, N)], 0
    bactrackNQueens(sParcial[:], phase, N,m,matriz)

# Given an N size chess-board program solve n-queens problems using backtracking technique
def main():
    global c
    '''line = stdin.readline()
    while line != '':'''
    N =int( stdin.readline())
    e=1
    while N != 0:
        m=[]
        c=0

        for i in range(N):
            a=stdin.readline().strip()
            tab=[]
            for j in range(len(a)):
                tab.append(a[j])
            m.append(tab)
        matriz=[]
        for x in range(len(m)):
            for y in range(len(m)):
                if m[x][y]=="*":
                    matriz.append((x,y))
        solveNQueens(N,m,matriz)
        print('case '+str(e)+':',c)

        N =int(stdin.readline().strip())
        e+=1
       # line = stdin.readline()

main()


from scrapy.dupefilters import BaseDupeFilter, referer_str
import logging
import hashlib
from scrapy.utils.python import to_bytes

class MyRFPDupeFilter(BaseDupeFilter):
    """My Request Fingerprint duplicates filter"""

    def __init__(self, debug=False):
        self.fingerprints = set()
        self.logdupes = True
        self.debug = debug
        self.logger = logging.getLogger(__name__)

    @classmethod
    def from_settings(cls, settings):
        debug = settings.getbool('DUPEFILTER_DEBUG')
        return cls(debug)

    def request_seen(self, request):
        fp = self.request_fingerprint(request)
        if fp in self.fingerprints:
            return True
        self.fingerprints.add(fp)

    def request_fingerprint(self, request) -> str:
        return hashlib.md5(to_bytes(request.url)).hexdigest()

    def close(self, reason):
        msg = "The number of URLs: %(url_num)d"
        args = {'url_num': len(self.fingerprints)}
        self.logger.info(msg, args)

    def log(self, request, spider):
        if self.debug:
            msg = "Filtered duplicate request: %(request)s (referer: %(referer)s)"
            args = {'request': request, 'referer': referer_str(request)}
            self.logger.debug(msg, args, extra={'spider': spider})
        elif self.logdupes:
            msg = ("Filtered duplicate request: %(request)s"
                   " - no more duplicates will be shown"
                   " (see DUPEFILTER_DEBUG to show all duplicates)")
            self.logger.debug(msg, {'request': request}, extra={'spider': spider})
            self.logdupes = False

        spider.crawler.stats.inc_value('dupefilter/filtered', spider=spider)


import re
from urllib import request
from urllib import error

class Mooc:
    urlInit = 'https://mooc1.chaoxing.com/course/{{courseId}}.html'
    urlK = 'https://mooc1.chaoxing.com/nodedetailcontroller/visitnodedetail?courseId={{courseId}}&knowledgeId={{knowledgeId}}'
    workUrl = 'https://mooc1.chaoxing.com/api/selectWorkQuestion?workId={{workId}}&ut=null&classId=0&courseId={{courseId}}&utenc=null'

    headers = {
        'User-Agent': r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
        r'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3'
    }

    def __returnWorkUrl(self, courseId, workId):
        url = self.workUrl.replace('{{courseId}}', courseId).replace(
            '{{workId}}', workId)
        return url

    def __getRequest(self, url):
        req = request.Request(url, headers=Mooc.headers)
        try:
            page = request.urlopen(req).read()
            page = page.decode('utf-8')
            return page
        except error.URLError as e:
            print('courseId可能不存在哦！', e.reason)
            exit()

    def __getFristData(self, courseId):
        # 组装初始URL，获取第一个包含knowledge
        url = self.urlInit.replace('{{courseId}}', courseId)

        htmls = self.__getRequest(url)

        #
        #re_rule = 'courseId='+courseId+'&knowledgeId=(.*)">'

#

#

        re_rule = 'courseId='+courseId+'&knowledgeId=(.*)">'
        url_frist = re.findall(re_rule, htmls)

        if len(url_frist) > 0:
            return url_frist[0]
        else:
            print('courseId错误！')

    def __returnTitle(self, courseId, knowledgeId):
        url = self.urlK.replace('{{courseId}}', courseId).replace(
            '{{knowledgeId}}', knowledgeId)
        htmls = self.__getRequest(url)

        re_rule = '":"work-(.*?)"'
        wordId = re.findall(re_rule, htmls)
        wordId = list(set(wordId))  # 先转集合，再转队列  去重复

        title = []
        for x in wordId:
            wordUrl = self.__returnWorkUrl(courseId, x)
            html_work = self.__getRequest(wordUrl)
            title_rule = '
\s*.*\s*
(.*?)
'
            title = title + re.findall(title_rule, html_work)

#

#

        #re_rule = ''
        # re_rule = '
?'
        re_rule = '
?'
        datas = re.findall(re_rule, htmls)

        return(title, datas)

    def getTextByCourseId(self, courseId):
        data_now = self.__getFristData(courseId)  # 第一个data需要再单独的一个链接里获取
        j = 1
        while data_now:
            listR = self.__returnTitle(courseId, data_now)

            title = listR[0]
            data = listR[1]

            for i, x in enumerate(data):
                if data_now == x:
                    if len(data) > (i+1):
                        data_now = data[i+1]
                    else:
                        data_now = None
                        print('获取题目结束.')

                    break

            # 打印题目  去除题目中的

获取其他标签，只有部分题目有，可能是尔雅自己整理时候加入的。
            for t in title:
                p_rule = '<.*?>'
                t = re.sub(p_rule, '', t)
                p_rule = '&.*?;'
                t = re.sub(p_rule, '', t)

                print(j, t)
                j += 1

mooc = Mooc()
courseId = '200080607'#input('请输入courseId:')  # '200837021'  200080607 = 189题
if courseId:
    mooc.getTextByCourseId(courseId)
else:
    print('请输入正确的courseId.')


import multiprocessing
import time

def depositMoney(money,lock):
    for i in range(50):
        lock.acquire()
        money.value+=1
        lock.release()
        print("Deposit!")

def withdrawMoney(money,lock):
    for i in range(50):
        lock.acquire()
        money.value-=1
        lock.release()
        print("Withdrawn!")

if __name__ == "__main__":
    balanceMoney = multiprocessing.Value('i',0)
    lockProcess=multiprocessing.Lock()
    process1=multiprocessing.Process(target=depositMoney, args=(balanceMoney,lockProcess))
    process2=multiprocessing.Process(target=withdrawMoney, args=(balanceMoney,lockProcess))

    process1.start()
    process2.start()
    process1.join()
    process2.join()

    print("Final Balance: ",balanceMoney.value)


n = int(input())
nums = []
names = []
for i in range (n):
    names.append(input().split(" ")[0])
names.sort()
counter = 0
for i in range(n):
    if i == n-1:
        nums.append(counter+1)
    else:
        if names[i] != names[i+1]:
            nums.append(counter+1)
            counter = 0
        else:
            counter += 1
nums.sort()
print(nums[len(nums)-1])


import pygame, os, random

# My modules #
import colors, fonts, paths

from ball import PongBall
from paddle import Paddle
from difinfo import DifficultyInfo as difficulties

# The main function where everything runs #
def main():
    def resetArena(pointReset):
        ball.position.x = screen_Width / 2 - ball.size
        ball.position.y = screen_Height / 2
        ball.velocity.x = ball_speed
        ball.velocity.y = random.randint(-1, 1)

        paddle_left.position.y = screen_Height / 2 - paddle_size_y / 2
        paddle_right.position.y = screen_Height / 2 - paddle_size_y / 2

        if pointReset:
            points[0] = 0
            points[1] = 0

    def hitPaddle():
        ball.velocity.x = ball.velocity.x - (ball.velocity.x * 2)
        ball.velocity.y = random.randint(-1 - selected_difficulty, 1 + selected_difficulty) + ball.velocity.y - (ball.velocity.y * 2)
        pygame.mixer.Sound.play(ball_hit)

    # Starting pygame #
    pygame.init()

    # Window Settings #
    screen_Width, screen_Height, max_FrameRate = 640, 480, 30
    game_Title, bg_Color, icon = "Pong!", colors.BLACK, "pong_icon"

    # Setting up the screen #
    screen = pygame.display.set_mode((screen_Width, screen_Height))
    pygame.display.set_caption(game_Title)
    screen.fill(bg_Color)
    pygame.display.set_icon(pygame.image.load(paths.findPath(["images"], icon, "png")))

    # Main Variables #
    clock = pygame.time.Clock()
    points = [0, 0]
    ball_speed = 5

    ball = PongBall((320, 240), 20, colors.WHITE)

    paddle_speed = 10
    ai_speed = 9

    paddle_size_x = 20
    paddle_size_y = 100

    paddle_right = Paddle((screen_Width - paddle_size_x, screen_Height / 2 - paddle_size_y / 2), (paddle_size_x, paddle_size_y), colors.WHITE)
    paddle_left = Paddle((0, screen_Height / 2 - paddle_size_y / 2), (paddle_size_x, paddle_size_y), colors.WHITE)

    selected_difficulty = 1
    difficulty_string = "Fair"
    selection_screen = True

    # Fonts #
    pixel = pygame.font.Font(paths.findPath(["fonts"], fonts.pixel_font, "ttf"), 32)

    # Sounds #
    ball_hit = pygame.mixer.Sound(paths.findPath(["sounds"], "ball-hit", "wav"))
    score = pygame.mixer.Sound(paths.findPath(["sounds"], "score", "wav"))
    select = pygame.mixer.Sound(paths.findPath(["sounds"], "menu-select", "wav"))

    # Window Loop #
    running = True

    pygame.key.set_repeat(100)

    while running:
        # Caps the framerate #
        clock.tick(max_FrameRate)

        # Delta time for making things consistent #
        dt = clock.get_time()

        # Refreshes the screen with the background color #
        screen.fill(bg_Color)

        # Event handling #
        for event in pygame.event.get():
            # If you hold a key #
            if event.type == pygame.KEYDOWN:
                if not selection_screen:
                    # Paddle Movement #
                    if event.key == pygame.K_w:
                        paddle_right.position.y -= (paddle_speed / 10) * dt

                        if paddle_right.position.y < 0:
                            paddle_right.position.y = 0

                    if event.key == pygame.K_s:
                        paddle_right.position.y += (paddle_speed / 10) * dt

                        if paddle_right.position.y > screen_Height - paddle_right.size.y:
                            paddle_right.position.y = screen_Height - paddle_right.size.y

            if event.type == pygame.KEYUP:
                if selection_screen:
                    if event.key == pygame.K_RETURN:
                        resetArena(True)
                        selection_screen = False
                        pygame.mixer.Sound.play(select)

                    if event.key == pygame.K_UP:
                        selected_difficulty -= 1
                        pygame.mixer.Sound.play(select)

                    if event.key == pygame.K_DOWN:
                        selected_difficulty += 1
                        pygame.mixer.Sound.play(select)

                    if event.key == pygame.K_ESCAPE:
                        running = False
                else:
                    if event.key == pygame.K_ESCAPE:
                        resetArena(True)
                        selection_screen = True
                        pygame.mixer.Sound.play(select)

            # If you quit the program with the window's x button #
            if event.type == pygame.QUIT:
                # Stop running this loop #
                running = False

        # Draw UI before everything else so nothing goes behind it #

        # Difficulty Select #
        if selection_screen:
            if selected_difficulty < 0:
                selected_difficulty = len(difficulties) - 1
            elif selected_difficulty > len(difficulties) - 1:
                selected_difficulty = 0

            for x in range(0, len(difficulties)):
                string_val = difficulties[x][0]

                if x == selected_difficulty:
                    string_val = ">" + string_val + "<"

                    paddle_speed = difficulties[x][2][0]
                    ai_speed = difficulties[x][2][1]
                    difficulty_string = difficulties[x][0]

                text = pixel.render(string_val, True,  difficulties[x][1], bg_Color)
                text_rect = text.get_rect()
                text_rect.center = (630 // 2, (400 + (x * 100)) // 2)
                screen.blit(text, text_rect)

            splash = pixel.render("-- Difficulty Select --", True, colors.WHITE, bg_Color)
            splash_rect = splash.get_rect()
            splash_rect.center = (630 // 2, 200 // 2)
            screen.blit(splash, splash_rect)

            version_num = pixel.render("v0.0.1", True, colors.GREY, bg_Color)
            version_num_rect = version_num.get_rect()
            version_num_rect.center = (0, 0)
            version_num_rect.x = 0
            version_num_rect.y = screen_Height - version_num_rect.height
            screen.blit(version_num, version_num_rect)

        # Score Text #
        if not selection_screen:
            score_text = pixel.render(str(points[0]) + " - " + str(points[1]), True, colors.WHITE, bg_Color)
            score_text_rect = score_text.get_rect()
            score_text_rect.center = (630 // 2, 50 // 2)
            screen.blit(score_text, score_text_rect)

            selected = pixel.render("Difficulty: " + difficulty_string, True, colors.GREY, bg_Color)
            selected_rect = selected.get_rect()

            selected_rect.center = (0, 0)
            selected_rect.x = 0
            selected_rect.y = screen_Height - selected_rect.height

            screen.blit(selected, selected_rect)

        # Drawing Paddles To The Screen #
        if not selection_screen:
            pygame.draw.rect(screen, paddle_right.color, pygame.Rect(paddle_right.position.x, paddle_right.position.y, paddle_right.size.x, paddle_right.size.y))
            pygame.draw.rect(screen, paddle_left.color, pygame.Rect(paddle_left.position.x, paddle_left.position.y, paddle_left.size.x, paddle_left.size.y))

        # Draws the ball to the screen #
        if not selection_screen:
            pygame.draw.circle(screen, ball.color, ball.position, ball.size)

        # Adds the velocity of the ball to the ball's movement #
        if not selection_screen:
            ball.position.x += (ball.velocity.x / 10) * dt
            ball.position.y += (ball.velocity.y / 10) * dt

        # Ball Collision #
        # We use a rectangular hit box for simplicity #

        if not selection_screen:
            if paddle_right.is_touching(ball):
                hitPaddle()
            elif paddle_left.is_touching(ball):
                hitPaddle()

        # Ball Outside Checks #

        # Checks if the ball is out of bounds on the right side #
        if ball.position.x >= screen_Width + ball.size:
            points[0] += 1
            resetArena(False)
            pygame.mixer.Sound.play(score)
        # Checks if the ball is out of bounds on the right side #
        elif ball.position.x <= 0 - ball.size:
            points[1] += 1
            resetArena(False)
            pygame.mixer.Sound.play(score)

        # Ball Screen Check #
        if not selection_screen:
            if ball.position.y < 0 + ball.size:
                ball.position.y = 0 + ball.size
                ball.velocity.y = random.randint(-5, 5)

                if not ball.velocity.y <= 0:
                    pygame.mixer.Sound.play(ball_hit)
            elif ball.position.y > screen_Height - ball.size:
                ball.position.y = screen_Height - ball.size
                ball.velocity.y = random.randint(-5, 5)

                if not ball.velocity.y <= 0:
                    pygame.mixer.Sound.play(ball_hit)

        # Move Left Paddle #
        if not selection_screen:
            if ball.position.y > paddle_left.position.y:
                paddle_left.position.y += (ai_speed / 10) * dt

            if ball.position.y < paddle_left.position.y:
                paddle_left.position.y -= (ai_speed / 10) * dt

        # Left Paddle Screen Check #
        if paddle_left.position.y < 0:
            paddle_left.position.y = 0
        elif paddle_left.position.y > screen_Height - paddle_left.size.y:
            paddle_left.position.y = screen_Height - paddle_left.size.y

        # Updates the display #
        pygame.display.update()

    pygame.quit()

main()


__author__ = "Jason, Sonny, Matt"
__Copyright__ = "Copyright @2022"

class circuit(object):              #Circuit Class
    def __init__(self, in1, in2):
        self.in1_ = in1
        self.in2_ = in2

class andgate(circuit):             #AND Gate
    def getCircuitOutput(self):
        if self.in1_ == 1 and self.in2_ == 1:
            return 1
        else:
            return 0

class orgate(circuit):              #OR Gate
    def getCircuitOutput(self):
        if self.in1_ == 0 and self.in2_ == 0:
            return 0
        else:
            return 1

class notgate(circuit):             #NOT Gate
    def __init__(self, in1):
        self.in1_ = in1

    def getCircuitOutput(self):
        if self.in1_ == 1:
            return 0
        elif self.in1_ == 0:
            return 1

class orgate3(circuit):             # 3to1 OR implemented with 2to1 ORs
    def __init__(self, in1, in2, in3):
        self.in1_ = in1
        self.in2_ = in2
        self.in3_ = in3

    def getCircuitOutput(self):
        org0 = orgate(self.in1_, self.in2_)
        out_org0 = org0.getCircuitOutput()

        org1 = orgate(out_org0, self.in3_)
        out_org1 = org1.getCircuitOutput()

        return out_org1

class orgate4(circuit):             # 4to1 OR implemented with 3to1 OR & 2to1 OR
    def __init__(self, in1, in2, in3, in4):
        self.in1_ = in1
        self.in2_ = in2
        self.in3_ = in3
        self.in4_ = in4

    def getCircuitOutput(self):
        org0 = orgate3(self.in1_, self.in2_, self.in3_)
        out_org0 = org0.getCircuitOutput()

        org1 = orgate(out_org0, self.in4_)
        out_org1 = org1.getCircuitOutput()

        return out_org1

class orgate8(circuit):             # 8to1 OR implemented with 4to1 ORs & 2to1 OR
    def __init__(self, in1, in2, in3, in4, in5, in6, in7, in8):
        self.in1_ = in1
        self.in2_ = in2
        self.in3_ = in3
        self.in4_ = in4
        self.in5_ = in5
        self.in6_ = in6
        self.in7_ = in7
        self.in8_ = in8

    def getCircuitOutput(self):
        org0 = orgate4(self.in1_, self.in2_, self.in3_, self.in4_)
        out_org0 = org0.getCircuitOutput()

        org1 = orgate4(self.in5_, self.in6_, self.in7_, self.in8_)
        out_org1 = org1.getCircuitOutput()

        org2 = orgate(out_org0, out_org1)
        out_org2 = org2.getCircuitOutput()

        return out_org2

class andgate3(circuit):            #3 input AND Gate implemented with 2 to 1 AND gates
    def __init__(self, in1, in2, in3):
        self.in1_ = in1
        self.in2_ = in2
        self.in3_ = in3

    def getCircuitOutput(self):
        andg0 = andgate(self.in1_, self.in2_)
        out_andg0 = andg0.getCircuitOutput()

        andg1 = andgate(out_andg0, self.in3_)
        out_andg1 = andg1.getCircuitOutput()

        return out_andg1

class andgate4(circuit):            # 4to1 AND gate implemented with 3to1 AND & 2to1 AND
    def __init__(self, in1, in2, in3, in4):
        self.in1_ = in1
        self.in2_ = in2
        self.in3_ = in3
        self.in4_ = in4

    def getCircuitOutput(self):
        andg0 = andgate3(self.in1_, self.in2_, self.in3_)
        out_andg0 = andg0.getCircuitOutput()

        andg1 = andgate(out_andg0, self.in4_)
        out_andg1 = andg1.getCircuitOutput()

        return out_andg1

class andgate6(circuit):            # 6to1 AND gate implemented with 2x 3to1 AND gates & 1 2to1 AND gate
    def __init__(self, in1, in2, in3, in4, in5, in6):
        self.in1_ = in1
        self.in2_ = in2
        self.in3_ = in3
        self.in4_ = in4
        self.in5_ = in5
        self.in6_ = in6

    def getCircuitOutput(self):
        andg0 = andgate3(self.in1_, self.in2_, self.in3_)
        out_andg0 = andg0.getCircuitOutput()

        andg1 = andgate3(self.in4_, self.in5_, self.in6_)
        out_andg1 = andg1.getCircuitOutput()

        and_result = andgate(out_andg0, out_andg1)
        out_and_result = and_result.getCircuitOutput()

        return out_and_result

class mux_2to1(circuit):            # 2to1 MUX implemented with NOT gate, AND gates and OR gates
    def __init__(self, in1, in2, inS):
        self.in1_ = in1
        self.in2_ = in2
        self.inS_ = inS

    def getCircuitOutput(self):
        notg0 = notgate(self.inS_)
        out_notg0 = notg0.getCircuitOutput()

        andg0 = andgate(out_notg0, self.in1_)
        out_andg0 = andg0.getCircuitOutput()

        andg1 = andgate(self.in2_, self.inS_)
        out_andg1 = andg1.getCircuitOutput()

        org0 = orgate(out_andg0, out_andg1)
        out_org0 = org0.getCircuitOutput()

        return out_org0

class mux_4to1(circuit):            # 4to1 MUX implemented by 2to1 MUXes
    def __init__(self, in1, in2, in3, in4, inS0, inS1):
        self.in1_ = in1
        self.in2_ = in2
        self.in3_ = in3
        self.in4_ = in4
        self.inS0_ = inS0
        self.inS1_ = inS1

    # 3 multiplexers used. First two get same control signal S0, last gets S1.
    def getCircuitOutput(self):
        mux0 = mux_2to1(self.in1_, self.in2_, self.inS0_)
        out_mux0 = mux0.getCircuitOutput()

        mux1 = mux_2to1(self.in3_, self.in4_, self.inS0_)
        out_mux1 = mux1.getCircuitOutput()

        mux3 = mux_2to1(out_mux0, out_mux1, self.inS1_)
        out_mux3 = mux3.getCircuitOutput()

        return out_mux3

class fulladder(circuit):           # fulladder implemented with logic gates
    def __init__(self, in1, in2, in3):
        self.in1_ = in1
        self.in2_ = in2
        self.in3_ = in3

    def getCout(self):              # Carry-Out portion of adder
        cout1 = andgate(self.in1_, self.in2_)
        out_cout1 = cout1.getCircuitOutput()

        cout2 = andgate(self.in1_, self.in3_)
        out_cout2 = cout2.getCircuitOutput()

        cout3 = andgate(self.in2_, self.in3_)
        out_cout3 = cout3.getCircuitOutput()

        cout_OR = orgate3(out_cout1, out_cout2, out_cout3)
        out_cout_OR = cout_OR.getCircuitOutput()

        return out_cout_OR

    def getSum(self):               # Sum portion of adder
        andg0 = andgate3(notgate(self.in1_).getCircuitOutput(), notgate(self.in2_).getCircuitOutput(), self.in3_)
        out_andg0 = andg0.getCircuitOutput()

        andg1 = andgate3(notgate(self.in1_).getCircuitOutput(), self.in2_, notgate(self.in3_).getCircuitOutput())
        out_andg1 = andg1.getCircuitOutput()

        andg2 = andgate3(self.in1_, notgate(self.in2_).getCircuitOutput(), notgate(self.in3_).getCircuitOutput())
        out_andg2 = andg2.getCircuitOutput()

        andg3 = andgate3(self.in1_, self.in2_, self.in3_)
        out_andg3 = andg3.getCircuitOutput()

        sum_OR = orgate4(out_andg0, out_andg1, out_andg2, out_andg3)
        out_sum_OR = sum_OR.getCircuitOutput()

        return out_sum_OR

class ALU_1bit(object):             # 1-bit ALU implemented with logic gates

    def __init__(self, a_vert, b_vert, in0, in1, cin, op0, op1):
        self.a_vert = a_vert
        self.b_vert = b_vert
        self.in0 = in0
        self.in1 = in1
        self.cin = cin
        self.op0 = op0
        self.op1 = op1
        self.less = 0

    # --------Inverters----------
    def a_mux(self):
        notg0 = notgate(self.in0)
        out_notg0 = notg0.getCircuitOutput()

        mux0 = mux_2to1(self.in0, out_notg0, self.a_vert)
        output_mux0 = mux0.getCircuitOutput()
        return output_mux0

    def b_mux(self):
        notg1 = notgate(self.in1)
        out_notg1 = notg1.getCircuitOutput()

        mux1 = mux_2to1(self.in1, out_notg1, self.b_vert)
        output_mux1 = mux1.getCircuitOutput()
        return output_mux1

    # --------- AND Operation-----
    def getAND(self):
        and0 = andgate(self.a_mux(), self.b_mux())
        out_and0 = and0.getCircuitOutput()

        return out_and0

    # ------- OR Operation--------
    def getOR(self):
        or0 = orgate(self.a_mux(), self.b_mux())
        out_or0 = or0.getCircuitOutput()

        return out_or0

    # ------ADDER Operations-------
    def getSum(self):
        sum0 = fulladder(self.a_mux(), self.b_mux(), self.cin)
        out_sum0 = sum0.getSum()

        return out_sum0

    def getCout(self):
        cout0 = fulladder(self.a_mux(), self.b_mux(), self.cin)
        out_cout0 = cout0.getCout()

        return out_cout0

    # ------SLT Operation----------
    def getLess(self):
        return self.less

    # Used by ALU_0 to set the Less variable equal to the sum of ALU_31
    def setLess(self, lessValue):
        self.less = lessValue

    # ------Result Multiplexer-----

    def getResult(self):
        result = mux_4to1(self.getAND(), self.getOR(), self.getSum(), self.getLess(), self.op1, self.op0).getCircuitOutput()
        return result

    # ------Overflow Detection-----

    def getOverflow(self):   # Overflow Detection
        overflow_r = fulladder(self.a_mux(), self.b_mux(), self.cin).getSum()
        overflow_not_r = notgate(overflow_r).getCircuitOutput()
        overflow_not_in0 = notgate(self.a_mux()).getCircuitOutput()
        overflow_not_in1 = notgate(self.b_mux()).getCircuitOutput()

        overflow0 = andgate3(self.a_mux(), self.b_mux(), overflow_not_r)
        out_overflow0 = overflow0.getCircuitOutput()

        overflow1 = andgate3(overflow_not_in0, overflow_not_in1, overflow_r)
        out_overflow1 = overflow1.getCircuitOutput()

        overflow_or = orgate(out_overflow0, out_overflow1)
        out_overflow_or = overflow_or.getCircuitOutput()

        return out_overflow_or

#===========================32-Bit ALU=================================
class ALU_32bit(object):
    def __init__(self, a_vert, b_vert, in0, in1, init_cin, op1, op0):
        self.a_vert = a_vert
        self.b_vert = b_vert
        self.in0 = in0
        self.in1 = in1
        self.init_cin = init_cin
        self.op0 = op0
        self.op1 = op1

    def getCircuitOutput(self):
        ALU_0 = ALU_1bit(self.a_vert, self.b_vert, self.in0[31], self.in1[31], self.init_cin, self.op1, self.op0)

        ALU_1 = ALU_1bit(self.a_vert, self.b_vert, self.in0[30], self.in1[30], ALU_0.getCout(), self.op1, self.op0)

        ALU_2 = ALU_1bit(self.a_vert, self.b_vert, self.in0[29], self.in1[29], ALU_1.getCout(), self.op1, self.op0)

        ALU_3 = ALU_1bit(self.a_vert, self.b_vert, self.in0[28], self.in1[28], ALU_2.getCout(), self.op1, self.op0)

        ALU_4 = ALU_1bit(self.a_vert, self.b_vert, self.in0[27], self.in1[27], ALU_3.getCout(), self.op1, self.op0)

        ALU_5 = ALU_1bit(self.a_vert, self.b_vert, self.in0[26], self.in1[26], ALU_4.getCout(), self.op1, self.op0)

        ALU_6 = ALU_1bit(self.a_vert, self.b_vert, self.in0[25], self.in1[25], ALU_5.getCout(), self.op1, self.op0)

        ALU_7 = ALU_1bit(self.a_vert, self.b_vert, self.in0[24], self.in1[24], ALU_6.getCout(), self.op1, self.op0)

        ALU_8 = ALU_1bit(self.a_vert, self.b_vert, self.in0[23], self.in1[23], ALU_7.getCout(), self.op1, self.op0)

        ALU_9 = ALU_1bit(self.a_vert, self.b_vert, self.in0[22], self.in1[22], ALU_8.getCout(), self.op1, self.op0)

        ALU_10 = ALU_1bit(self.a_vert, self.b_vert, self.in0[21], self.in1[21], ALU_9.getCout(), self.op1, self.op0)

        ALU_11 = ALU_1bit(self.a_vert, self.b_vert, self.in0[20], self.in1[20], ALU_10.getCout(), self.op1, self.op0)

        ALU_12 = ALU_1bit(self.a_vert, self.b_vert, self.in0[19], self.in1[19], ALU_11.getCout(), self.op1, self.op0)

        ALU_13 = ALU_1bit(self.a_vert, self.b_vert, self.in0[18], self.in1[18], ALU_12.getCout(), self.op1, self.op0)

        ALU_14 = ALU_1bit(self.a_vert, self.b_vert, self.in0[17], self.in1[17], ALU_13.getCout(), self.op1, self.op0)

        ALU_15 = ALU_1bit(self.a_vert, self.b_vert, self.in0[16], self.in1[16], ALU_14.getCout(), self.op1, self.op0)

        ALU_16 = ALU_1bit(self.a_vert, self.b_vert, self.in0[15], self.in1[15], ALU_15.getCout(), self.op1, self.op0)

        ALU_17 = ALU_1bit(self.a_vert, self.b_vert, self.in0[14], self.in1[14], ALU_16.getCout(), self.op1, self.op0)

        ALU_18 = ALU_1bit(self.a_vert, self.b_vert, self.in0[13], self.in1[13], ALU_17.getCout(), self.op1, self.op0)

        ALU_19 = ALU_1bit(self.a_vert, self.b_vert, self.in0[12], self.in1[12], ALU_18.getCout(), self.op1, self.op0)

        ALU_20 = ALU_1bit(self.a_vert, self.b_vert, self.in0[11], self.in1[11], ALU_19.getCout(), self.op1, self.op0)

        ALU_21 = ALU_1bit(self.a_vert, self.b_vert, self.in0[10], self.in1[10], ALU_20.getCout(), self.op1, self.op0)

        ALU_22 = ALU_1bit(self.a_vert, self.b_vert, self.in0[9], self.in1[9], ALU_21.getCout(), self.op1, self.op0)

        ALU_23 = ALU_1bit(self.a_vert, self.b_vert, self.in0[8], self.in1[8], ALU_22.getCout(), self.op1, self.op0)

        ALU_24 = ALU_1bit(self.a_vert, self.b_vert, self.in0[7], self.in1[7], ALU_23.getCout(), self.op1, self.op0)

        ALU_25 = ALU_1bit(self.a_vert, self.b_vert, self.in0[6], self.in1[6], ALU_24.getCout(), self.op1, self.op0)

        ALU_26 = ALU_1bit(self.a_vert, self.b_vert, self.in0[5], self.in1[5], ALU_25.getCout(), self.op1, self.op0)

        ALU_27 = ALU_1bit(self.a_vert, self.b_vert, self.in0[4], self.in1[4], ALU_26.getCout(), self.op1, self.op0)

        ALU_28 = ALU_1bit(self.a_vert, self.b_vert, self.in0[3], self.in1[3], ALU_27.getCout(), self.op1, self.op0)

        ALU_29 = ALU_1bit(self.a_vert, self.b_vert, self.in0[2], self.in1[2], ALU_28.getCout(), self.op1, self.op0)

        ALU_30 = ALU_1bit(self.a_vert, self.b_vert, self.in0[1], self.in1[1], ALU_29.getCout(), self.op1, self.op0)

        ALU_31 = ALU_1bit(self.a_vert, self.b_vert, self.in0[0], self.in1[0], ALU_30.getCout(), self.op1, self.op0)

        # Assign less than value for ALU_0
        ALU_0.setLess(ALU_31.getSum())

        ALU_32bit_result = [
                             ALU_31.getResult(), ALU_30.getResult(), ALU_29.getResult(), ALU_28.getResult(),
                             ALU_27.getResult(),
                             ALU_26.getResult(), ALU_25.getResult(), ALU_24.getResult(), ALU_23.getResult(),
                             ALU_22.getResult(),
                             ALU_21.getResult(), ALU_20.getResult(), ALU_19.getResult(), ALU_18.getResult(),
                             ALU_17.getResult(),
                             ALU_16.getResult(), ALU_15.getResult(), ALU_14.getResult(), ALU_13.getResult(),
                             ALU_12.getResult(),
                             ALU_11.getResult(), ALU_10.getResult(), ALU_9.getResult(), ALU_8.getResult(),
                             ALU_7.getResult(),
                             ALU_6.getResult(), ALU_5.getResult(), ALU_4.getResult(), ALU_3.getResult(),
                             ALU_2.getResult(),
                             ALU_1.getResult(), ALU_0.getResult()
                           ]
        return ALU_32bit_result

# ---------------Sign-Extended Operation-----------------------------------
class signExt(circuit):
    def __init__(self, instru):
        self.sign = instru[16]
        self.bit14 = instru[17]
        self.bit13 = instru[18]
        self.bit12 = instru[19]
        self.bit11 = instru[20]
        self.bit10 = instru[21]
        self.bit9 = instru[22]
        self.bit8 = instru[23]
        self.bit7 = instru[24]
        self.bit6 = instru[25]
        self.bit5 = instru[26]
        self.bit4 = instru[27]
        self.bit3 = instru[28]
        self.bit2 = instru[29]
        self.bit1 = instru[30]
        self.bit0 = instru[31]

    def getSignExtend(self):
        extended = [self.sign, self.sign, self.sign, self.sign, self.sign, self.sign, self.sign, self.sign,
                    self.sign, self.sign, self.sign, self.sign, self.sign, self.sign, self.sign, self.sign,
                    self.sign, self.bit14, self.bit13, self.bit12, self.bit11, self.bit10, self.bit9,
                    self.bit8, self.bit7, self.bit6, self.bit5, self.bit4, self.bit3, self.bit2,
                    self.bit1, self.bit0]
        return extended

#==================ALU Control =============================================
class aluControl(circuit):

    def __init__(self, aluOp2, aluOp1, fCode):
        self.aluOp1 = aluOp1
        self.aluOp2 = aluOp2
        self.f5 = fCode[26]
        self.f4 = fCode[27]
        self.f3 = fCode[28]
        self.f2 = fCode[29]
        self.f1 = fCode[30]
        self.f0 = fCode[31]
        self.aluResult = [0, 0, 0, 0]

    def getCircuitOutput(self):
        # operation0
        andg0a = andgate(self.aluOp2, orgate(self.f0, self.f3).getCircuitOutput() )
        out_andg0a = andg0a.getCircuitOutput()
        andg0b = andgate(out_andg0a, notgate(andgate4(notgate(self.f3).getCircuitOutput(), self.f2, self.f1, self.f0).getCircuitOutput() ).getCircuitOutput() )
        out_andg0 = andg0b.getCircuitOutput()

        # operation1
        org0 = orgate(notgate(self.aluOp2).getCircuitOutput(), notgate(self.f2).getCircuitOutput())
        out_org0 = org0.getCircuitOutput()

        # operation2
        org1 = orgate(self.aluOp1, andgate(self.aluOp2, self.f1).getCircuitOutput())
        out_org1 = org1.getCircuitOutput()

        # operation3
        andg1 = andgate4(notgate(self.f3).getCircuitOutput(), self.f2, self.f1, self.f0 )
        out_andg1 = andg1.getCircuitOutput()

        self.aluResult = [out_andg1, out_org1, out_org0, out_andg0]  #[a_invert, b_invert, ALU_OP1, ALU_OP0]

        return self.aluResult

#-------------Carry-In Operation--------------------------------------------
class getCin(circuit):

    def getCircuitOutput(aluCont):
        sub_op = andgate4(notgate(aluCont[0]).getCircuitOutput(), aluCont[1], aluCont[2], notgate(aluCont[3]).getCircuitOutput() )
        sub_out = sub_op.getCircuitOutput()

        slt_op = andgate4(notgate(aluCont[0]).getCircuitOutput(), aluCont[1], aluCont[2], aluCont[3] )
        slt_out = slt_op.getCircuitOutput()

        cin_test = orgate(sub_out, slt_out)
        cin_result = cin_test.getCircuitOutput()

        return cin_result

# ====================Registers ===========================================
class registerFile(circuit):
    def __init__(self, initValue):
        self.reg_zero = [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]
        self.reg_at = initValue
        self.reg_v0 = initValue
        self.reg_v1 = initValue
        self.reg_a0 = initValue
        self.reg_a1 = initValue
        self.reg_a2 = initValue
        self.reg_a3 = initValue
        self.reg_t0 = initValue
        self.reg_t1 = initValue
        self.reg_t2 = initValue
        self.reg_t3 = initValue
        self.reg_t4 = initValue
        self.reg_t5 = initValue
        self.reg_t6 = initValue
        self.reg_t7 = initValue
        self.reg_s0 = initValue
        self.reg_s1 = initValue
        self.reg_s2 = initValue
        self.reg_s3 = initValue
        self.reg_s4 = initValue
        self.reg_s5 = initValue
        self.reg_s6 = initValue
        self.reg_s7 = initValue
        self.reg_t8 = initValue
        self.reg_t9 = initValue
        self.reg_k0 = initValue
        self.reg_k1 = initValue
        self.reg_gp = initValue
        self.reg_sp = initValue
        self.reg_fp = initValue
        self.reg_ra = initValue

        self.registers = [self.reg_ra, self.reg_fp, self.reg_sp, self.reg_gp, self.reg_k1, self.reg_k0, self.reg_t9,
                          self.reg_t8,
                          self.reg_s7, self.reg_s6, self.reg_s5, self.reg_s4, self.reg_s3, self.reg_s2, self.reg_s1,
                          self.reg_s0,
                          self.reg_t7, self.reg_t6, self.reg_t5, self.reg_t4, self.reg_t3, self.reg_t2, self.reg_t1,
                          self.reg_t0,
                          self.reg_a3, self.reg_a2, self.reg_a1, self.reg_a0, self.reg_v1, self.reg_v0, self.reg_at,
                          self.reg_zero
                         ]

    def setRegValue(self, o_regDecoder, valueToSet): #Stores a 32-bit value in a register

        i = 31
        x = o_regDecoder[i]
        if x == 1:
            return #Prevents overwriting register zero

        else:
            while (x != 1 and i > -1):
                x = o_regDecoder[i]
                if x == 1:
                    self.registers[i] = valueToSet
                    break
                else:
                    i -= 1
            else:
                print("Register Not Found")

    def getRegValue(self, o_regDecoder):        #Returns a 32-bit value that was stored in a register

        i = 31
        x = o_regDecoder[i]
        if x == 1:
            return self.registers[i]

        else:
            while (x != 1 and i > -1):
                x = o_regDecoder[i]
                if x == 1:
                    return self.registers[i]
                else:
                    i -= 1
                    '''
            else:
                print("Register Not Found")
                    '''

    def getAllRegValues(self):          #Returns all of the 32-bit values that are stored in the registers

        all_registers = self.registers

        return all_registers

#--------------Register Decoder-----------------------

class decoder_3to8(circuit):
    def __init__(self, in2, in1, in0, control):
        self.in0 = in0
        self.in1 = in1
        self.in2 = in2
        self.control = control

    def getCircuitOutput(self):
        # Not Gates
        in0_not = notgate(self.in0).getCircuitOutput()
        in1_not = notgate(self.in1).getCircuitOutput()
        in2_not = notgate(self.in2).getCircuitOutput()

        andg0 = andgate4(in0_not, in1_not, in2_not, self.control).getCircuitOutput()
        andg1 = andgate4(in0_not, in1_not, self.in2, self.control).getCircuitOutput()
        andg2 = andgate4(in0_not, self.in1, in2_not, self.control).getCircuitOutput()
        andg3 = andgate4(in0_not, self.in1, self.in2, self.control).getCircuitOutput()
        andg4 = andgate4(self.in0, in1_not, in2_not, self.control).getCircuitOutput()
        andg5 = andgate4(self.in0, in1_not, self.in2, self.control).getCircuitOutput()
        andg6 = andgate4(self.in0, self.in1, in2_not, self.control).getCircuitOutput()
        andg7 = andgate4(self.in0, self.in1, self.in2, self.control).getCircuitOutput()

        return [andg7, andg6, andg5, andg4, andg3, andg2, andg1, andg0]

class decoder_2to4(circuit):
    def __init__(self, in1, in0):
        self.in0 = in0
        self.in1 = in1

    def getCircuitOutput(self):
        andgate0 = andgate(notgate(self.in1).getCircuitOutput(),
                           notgate(self.in0).getCircuitOutput()).getCircuitOutput()
        andgate1 = andgate(self.in1, notgate(self.in0).getCircuitOutput()).getCircuitOutput()
        andgate2 = andgate(notgate(self.in1).getCircuitOutput(), self.in0).getCircuitOutput()
        andgate3 = andgate(self.in1, self.in0).getCircuitOutput()

        AndValues = [andgate3, andgate2, andgate1, andgate0]

        return AndValues

class decoderReg(circuit):
    def __init__(self, regIns1, regIns2, regIns3, regIns4, regIns5):
        self.in4 = regIns1
        self.in3 = regIns2
        self.in2 = regIns3
        self.in1 = regIns4
        self.in0 = regIns5

    def getCircuitOutput(self):
        decoder2to4 = decoder_2to4(self.in3, self.in4).getCircuitOutput()
        decoder3 = decoder_3to8(self.in0, self.in1, self.in2, decoder2to4[0]).getCircuitOutput()
        decoder2 = decoder_3to8(self.in0, self.in1, self.in2, decoder2to4[1]).getCircuitOutput()
        decoder1 = decoder_3to8(self.in0, self.in1, self.in2, decoder2to4[2]).getCircuitOutput()
        decoder0 = decoder_3to8(self.in0, self.in1, self.in2, decoder2to4[3]).getCircuitOutput()

        return decoder3 + decoder2 + decoder1 + decoder0

class decoderReg(circuit):          #5 to 32 register decoder implemented with 2 to 4 decoder and 3 to 8 decoders
    def __init__(self, regIns1, regIns2, regIns3, regIns4, regIns5):
        self.in4 = regIns1
        self.in3 = regIns2
        self.in2 = regIns3
        self.in1 = regIns4
        self.in0 = regIns5

    def getCircuitOutput(self):
        decoder2to4 = decoder_2to4(self.in3, self.in4).getCircuitOutput()
        decoder3 = decoder_3to8(self.in0, self.in1, self.in2, decoder2to4[0]).getCircuitOutput()
        decoder2 = decoder_3to8(self.in0, self.in1, self.in2, decoder2to4[1]).getCircuitOutput()
        decoder1 = decoder_3to8(self.in0, self.in1, self.in2, decoder2to4[2]).getCircuitOutput()
        decoder0 = decoder_3to8(self.in0, self.in1, self.in2, decoder2to4[3]).getCircuitOutput()

        return decoder3 + decoder2 + decoder1 + decoder0

#============Main Control Module ============================================
class mainCtrl(object):
    def __init__(self, opCode):
        self.op0 = opCode[0]
        self.op1 = opCode[1]
        self.op2 = opCode[2]
        self.op3 = opCode[3]
        self.op4 = opCode[4]
        self.op5 = opCode[5]

        self.not0 = notgate(self.op0).getCircuitOutput()
        self.not1 = notgate(self.op1).getCircuitOutput()
        self.not2 = notgate(self.op2).getCircuitOutput()
        self.not3 = notgate(self.op3).getCircuitOutput()
        self.not4 = notgate(self.op4).getCircuitOutput()
        self.not5 = notgate(self.op5).getCircuitOutput()

        self.opCode = opCode

#----------------------- MainControl Operations-----------------------------------

    def getR_Format(self):          #R_Format Operations(RegDst, RegWrite, ALU_Op1)
        and0 = andgate6(self.not0, self.not1, self.not2, self.not3, self.not4, self.not5)
        out_and0 = and0.getCircuitOutput()

        return out_and0

    def getLW(self):                #LW Operations(ALUSrc, MemtoReg, RegWrite, MemRead)
        and1 = andgate6(self.op0, self.not1, self.not2, self.not3, self.op4, self.op5)
        out_and1 = and1.getCircuitOutput()

        return out_and1

    def getSW(self):                #SW Operations(ALUSrc, MemWrite)
        and2 = andgate6(self.op0, self.not1, self.op2, self.not3, self.op4, self.op5)
        out_and2 = and2.getCircuitOutput()

        return out_and2

    def getBEQ(self):               #BEQ Operations(Branch & ALU_Op0)
        and3 = andgate6(self.not0, self.not1, self.not2, self.op3, self.not4, self.not5)
        out_and3 = and3.getCircuitOutput()

        return out_and3

#------------------ MainCtrol Outputs---------------------------------------
    def getReg_Dst(self, mainOut):          #Reg_Dst Output
        return mainOut.getR_Format()

    def getALU_Src(self, mainOut):          #ALU_Src Output
        or0 = orgate(mainOut.getLW(), mainOut.getSW())
        ALU_Src = or0.getCircuitOutput()

        return ALU_Src

    def getReg_Write(self, mainOut):        #Reg_Write Output
        or1 = orgate(mainOut.getR_Format(), mainOut.getLW())
        Reg_Write = or1.getCircuitOutput()

        return Reg_Write

    def getALU_OP(self, mainOut):           #ALU_Op1 & ALU_Op0 Output
        return aluControl(mainOut.getR_Format(), mainOut.getBEQ(), self.opCode)

    '''===========================Simple MIPS============================='''
class simpleMIPS(circuit):
    def __init__(self, regValue):       #Initialize Registers

        self.registers = registerFile(regValue)

    def getCircuitOutput(self, instru):         # Input 32-bit instructions as a single array/list

        main = mainCtrl(instru)                             #Creates MainCtrl Object

        aluOp = main.getALU_OP(main).getCircuitOutput()     #Retrieves [ainv, binv, op1, op0]

        cin = getCin.getCircuitOutput(aluOp)                #Retreives Carry-In Value

        Reg1 = self.registers.getRegValue( decoderReg(instru[6], instru[7], instru[8],          #Retrieves the location of the first input register
                          instru[9], instru[10]).getCircuitOutput() )

        Reg2 = self.registers.getRegValue( decoderReg(instru[11], instru[12], instru[13],       #Retrieves the location of the second input register
                          instru[14], instru[15]).getCircuitOutput() )

        rt = [instru[11], instru[12], instru[13], instru[14], instru[15] ]      #MUX that is used to determine the destination register that is written to
        rd = [instru[16], instru[17], instru[18], instru[19], instru[20] ]      #    while loop is used to process 32-bit value
        writeReg = [0,0,0,0,0]
        i = 0
        while i < len(writeReg):
            writeReg[i] = mux_2to1(rt[i], rd[i], main.getReg_Dst(main) ).getCircuitOutput()
            i += 1

        extended = signExt(instru).getSignExtend()              #Retrieves the sign-extended value

        in2 = [0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,1 ] # <- random value used to create a 32-bit array
        j = 0
        while j < len(in2):                                                                           #MUX that is used to determine the second input for the ALU
            in2[j] = mux_2to1(Reg2[j], extended[j], main.getALU_Src(main) ).getCircuitOutput()    #   while loop is used to process 32-bit value
            j += 1

        alu = ALU_32bit(aluOp[0], aluOp[1], Reg1, in2, cin, aluOp[2], aluOp[3])

        writeData = alu.getCircuitOutput()      #Stores the output of the ALU

        if main.getReg_Write(main) == 1:        #Determines if the ALU output should be stored in the destination register
            self.registers.setRegValue(decoderReg(writeReg[0], writeReg[1], writeReg[2], writeReg[3], writeReg[4]).getCircuitOutput(), writeData )

        '''
        out2 = "After Instruction: {}"
        out3 = "Register {0} :  {1} "
        print(out2.format(instru) )
        print("Registers Store: ")
        r = self.registers.getAllRegValues()
        k = 31
        for x in r:                             #for loop that prints the contents of the registers
            print(out3.format(k, x) )
            k -= 1
        print( " ")
        '''


from selenium.webdriver.common.by import By
from pages.base_page import BasePage
import allure

class MainPageScooter(BasePage):

    def __init__(self, driver):
        self.driver = driver

    logo_yandex = [By.XPATH, './/img[@alt = "Yandex"]//ancestor::a']
    page_yandex = [By.XPATH, './/button[text() ="Найти"]']

    @allure.step('Получаем ответ на вопрос в блоке "Вопросы о важном"')
    def get_answer_to_question(self, question, answer):
        self.wait_load_any_element(locator=question)
        self.driver.find_element(*question).click()
        self.wait_load_any_element(locator=answer)
        return self.driver.find_element(*answer).text

    @allure.step('Кликаем по логотипу "Яндекса"')
    def click_logo_yandex(self):
        self.wait_load_any_element(locator=self.logo_yandex)
        self.driver.find_element(*self.logo_yandex).click()
        self.switch_to_windows()
        self.wait_load_any_element(locator=self.page_yandex)


v_num = 12
v_mul = 5

for v_num in range(0,v_num+1):
    p = v_num * v_mul
    print(str(v_mul) + 'x' + str(v_num) + '=' + str(p))

"""def f_num(n):
    for i in range(2,n + 1,2):
        print(i)

f_num(10)"""

"""v_edad = int(input("Ingrese edad: "))

def mayor_edad(v_edad):
    if v_edad >= 18:
        print("Eres mayor de edad")
    else:
        print("Eres un bebé")
        return

mayor_edad(v_edad)"""

"""Suma
y = 9
x = 7

def f_suma (x,y):

    s = x + y
    print(s)
    return

f_suma(x,y)"""


from store_api import app, db
from flask import jsonify
from store_api.models import Order, PostStatus, Product

@app.route("/api/admin/update_post_status_order/<order_uuid>/<int:post_status_id>")
def update_post_status_order(order_uuid, post_status_id):

    order = Order.query.filter_by(order_uuid=order_uuid).first()
    ps = PostStatus.query.filter_by(id=post_status_id).first()
    order.post_status = ps
    db.session.add(order)
    db.session.commit()

    return jsonify({"message": "Post status has been updated!"})

@app.route("/api/admin/cancel_order/<order_uuid>")
def cancel_order(order_uuid):
    order = Order.query.filter_by(order_uuid=order_uuid).first()
    if order and order.orderitems:
        for oi in order.orderitems:
            p = Product.query.filter_by(id=oi.product_id).first()
            p.quantity = p.quantity + oi.quantity
            db.session.delete(oi)
        db.session.delete(order)
        db.session.commit()

        return jsonify({"message": "Prodcts has been updated!"}), 200

    else:
        return jsonify({"message": "Order isn't exist!"}), 200


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

df = pd.read_csv('Regression\china_gdp.csv')
x_data, y_data = (df["Year"].values, df["Value"].values)
xdata = x_data / max(x_data)
ydata = y_data / max(y_data)
'''plt.plot(df[['Year']], df[['Value']], color='blue')
plt.show()'''

# We're using a logistic function as it represents the trends in the data well

def sigmoid(x, Beta_1, Beta_2):
    y = 1 / (1 + np.exp(-Beta_1 * (x - Beta_2)))
    return y

beta_1 = 0.10
beta_2 = 1990.0

Y_pred = sigmoid(x_data, beta_1, beta_2)

# plot initial prediction against datapoints
'''plt.plot(x_data, Y_pred*15000000000000.)
plt.plot(x_data, y_data, 'ro')
plt.show()'''

popt, pcov = curve_fit(sigmoid, xdata, ydata)
print('beta1 = {} beta2 = {}'.format(popt[0], popt[1]))

# Visualize the fit/model
y = sigmoid(xdata, popt[0], popt[1])
plt.plot(xdata, ydata, 'ro', label='data')
plt.plot(xdata, y, linewidth=3.0, label='fit')
plt.legend(loc='best')
plt.ylabel('GDP')
plt.xlabel('Year')
plt.show()


import os
import sys
from typing import List

class Crawler:
    """
    A Crawler designed to traverse a file tree and print the files contained in it.
    """

    def __init__(self, target: str, extension_white_list: List[str] = [], abs_path: bool = False):
        """construct the File Crawler

        Arguments:
            target {str} -- the target directory for encryptioin

        Keyword Arguments:
            extension_white_list {List[str]} -- the list of file extensions to encrypt (default: {[]})
            abs_path {bool} -- whether or not to return the absolute path (default: {False})
        """

        self.target_directory: str = target
        self.files: List[str] = []
        self.file_extensions: str = extension_white_list
        self.abs_path: bool = abs_path

    def find_root(self) -> bool:
        """
        Returns whether or not the target directory is a directory, and finds the absolute path
        """
        return os.path.isdir(self.target_directory)

    def walk_tree(self) -> None:
        """
        Walks the given tree, and stores the individual file names encountered in the target directory
        """
        for root, subdirs, files in os.walk(self.target_directory):
            for file_name in files:
                for file_extension in self.file_extensions:
                    if file_name.endswith(file_extension):
                        if self.abs_path:
                            self.files.append(os.path.abspath(
                                root + os.sep + file_name))
                        else:
                            self.files.append(root + os.sep + file_name)

    def get_files(self) -> List[str]:
        """
        Get all the files that have been found by the Crawler

        Return:
            A list of strings, representing the file names of each file inside the target directory,
            with the given file extension.
        """
        return self.files


#!/usr/bin/env python
# coding: utf-8

# In[8]:

from csvtomd import md_table
from casedict import get_issue_list#issue_dict, demo_case_dict

# In[9]:

issuelist = get_issue_list()
table = []
table.append(['Issue#','Description','video path'])
for k, case in issuelist.items():
    table.append([k, case.desc, case.vpath])

issue_list_md = md_table(table)
text_file = open('README.md', 'w')
text_file.write(issue_list_md)
text_file.close()

# In[ ]:


from typing import List

class Transaction():
    def __init__(self, id: int):
        self.id: int = id
        self.write_set: List[str] = []
        self.read_set: List[str] = []
        self.start_timestamp: int = 10e10
        self.validation_timestamp: int = 10e10
        self.finish_timestamp: int = 10e10

    def write(self, timestamp: int, data_item: str):
        if (len(self.write_set) == 0):
            self.validation_timestamp = timestamp

        if (len(self.read_set) == 0):
            self.start_timestamp = timestamp

        if (data_item not in self.write_set):
            print(f'Transaction {self.id} writes data item {data_item}')
            print(f'Current write set = {self.write_set}')
            self.write_set.append(data_item)

        self.start_timestamp = min(self.start_timestamp, timestamp)
        return True

    def read(self, timestamp: int, data_item: str):
        if (data_item not in self.read_set):
            self.read_set.append(data_item)
        print(f'Transaction {self.id} reads data item {data_item}')
        print(f'Current read set = {self.read_set}')

        self.start_timestamp = min(self.start_timestamp, timestamp)
        return True

    def commit(self, timestamp: int, transaction_arr: List['Transaction']):
        print()
        self.finish_timestamp = timestamp
        print(f'Transaction {self.id} commits, updating finish timestamp to {timestamp}')

        fail = True

        if (len(transaction_arr) == 1 and transaction_arr[0].id == self.id):
            fail = False

        for transaction in transaction_arr:
            if (transaction.id == self.id):
                fail = False
                continue

            print(f'Comparing with transaction {transaction.id}')

            if (transaction.start_timestamp >= self.start_timestamp):
                print(f'Compared transaction starts after this transaction, no conflict')
                fail = False
                continue

            # cek kondisi pertama, apakah waktu finish transaksi lain < waktu transaksi sendiri
            if (transaction.finish_timestamp < self.start_timestamp):
                print(f'Compared transaction finishes before current transactionbegins, can be committed')
                fail = False
                continue
            else:
                print(f'Compared transaction finishes after current transaction begins, needs further examination')

            # cek kondisi kedua, apakah waktu finish transaksi lain di antara waktu start dan validasi
            # dan yang dibaca transaksi ini tidak ditulis transaksi lain
            if (fail and self.start_timestamp < transaction.finish_timestamp < self.validation_timestamp):
                print(f'Compared transaction finishes between current transaction start and validation')
                if (set(self.read_set).isdisjoint(transaction.write_set)):
                    print(f'Disjoint between read set and write set of compared transaction, can be committed')
                    fail = False
                    continue
                else:
                    print(f'Intersect between read set and write set of compared transaction, cannot be committed')
            else:
                print(f'Compared transaction doesn\'t finish between current transaction start timestamp and validation timestamp, cannot be committed')

            if (fail):
                break

        if (not fail):
            print(f'Successfully committed transaction {self.id}!')
        else:
            print(f'Failed to commit transaction {self.id}!')
        print()
        return not fail

    def __str__(self):
        return f'T{self.id} ({self.read_set} {self.write_set})'


from .space import Space

class MockHumidity:
    def __init__(self, increment, decrement):
        self.increment = increment
        self.decrement = decrement

    def __call__(self, space: Space):
        if space.humidity.last_value is None:
            space.humidity.current_value = 60
            return

        if space.state.last_value:
            delta = self.decrement
        else:
            delta = self.increment

        space.humidity.current_value = space.humidity.last_value + delta

class MockDehumidifier:
    def __call__(self, space: Space):
        if space.state_request.last_value is not None:
            space.state.current_value = space.state_request.last_value
        else:
            if space.state.last_value is None:
                space.state.current_value = False
            else:
                space.state.current_value = space.state.last_value


import csv
import random

student = [[] for _ in range(12)]  # 生成班级学号空列表
student_dict = {}  # 生成学生信息空字典
with open('20021.csv', encoding="UTF-8") as f:
    f_csv = csv.reader(f)
    for row in f_csv:
        student[int(row[4][5:7]) - 1].append(row[4])
        student_dict[row[4]] = row
while True:
    try:
        bj = int(input("输入班级(1-12)："))
    except NameError and ValueError:
        print("班级输入错误，请重新输入")
    else:
        if 1 <= bj <= 12:
            break
while True:
    luck = random.choice(student[bj - 1])
    print()
    print("恭喜！高一({:0>2})班本次点名回答问题的同学是：{}{}".format(bj, luck[-2:], student_dict[luck][3]))
    if input().lower() == "q":
        break
input("程序运行结束，按回车键退出···")

其他教学参考/随机点名/随机点名.py


def list_of_sum(lst):
    sum_list = []
    for number in lst:
        summ = 0
        while number:
            summ += number % 10
            number = number // 10
        sum_list.append(summ)
    return sorted(sum_list)

list_of_numbers = [int(i) for i in input().split()]

print(list_of_sum(list_of_numbers))


"""
2658. Maximum Number of Fish in a Grid
You are given a 0-indexed 2D matrix grid of size m x n, where (r, c) represents:

A land cell if grid[r][c] = 0, or
A water cell containing grid[r][c] fish, if grid[r][c] > 0.
A fisher can start at any water cell (r, c) and can do the following operations any number of times:

Catch all the fish at cell (r, c), or
Move to any adjacent water cell.
Return the maximum number of fish the fisher can catch if he chooses his starting cell optimally, or 0 if no water cell exists.

An adjacent cell of the cell (r, c), is one of the cells (r, c + 1), (r, c - 1), (r + 1, c) or (r - 1, c) if it exists.

Example1:
Input: grid = [[0,2,1,0],[4,0,0,3],[1,0,0,4],[0,3,2,0]]
Output: 7
Explanation: The fisher can start at cell (1,3) and collect 3 fish, then move to cell (2,3) and collect 4 fish.

Example2:
Input: grid = [[1,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,1]]
Output: 1
Explanation: The fisher can start at cells (0,0) or (3,3) and collect a single fish.

Constraints:
m == grid.length
m == grid[i].length
1 <= m, n <= 10
0 <= grid[i][j] <= 10
"""

"""
Note:
1. UnionFind: O(mn) time | O(mn) space - where m is the length of row, n is the length of col
"""

import unittest
from typing import List
class UnionFind:
    def __init__(self, grid):
        rows, cols = len(grid), len(grid[0])
        total = rows * cols
        self.parents = [i for i in range(total)]
        self.ranks = [1 for _ in range(total)]
        self.counts = [grid[i//cols][i % cols] for i in range(total)]

    def find(self, u):
        if u != self.parents[u]:
            self.parents[u] = self.find(self.parents[u])
        return self.parents[u]

    def union(self, u, v):
        pu, pv = self.find(u), self.find(v)
        if pu == pv:
            return max(self.counts[pu], self.counts[pv])

        if self.ranks[pu] < self.ranks[pv]:
            self.parents[pu] = pv
            self.counts[pv] += self.counts[pu]
        elif self.ranks[pv] < self.ranks[pu]:
            self.parents[pv] = pu
            self.counts[pu] += self.counts[pv]
        else:
            self.parents[pv] = pu
            self.counts[pu] += self.counts[pv]
            self.ranks[pu] += 1

        newCount = max(self.counts[pu], self.counts[pv])
        return newCount

class Solution:
    def findMaxFish(self, grid: List[List[int]]) -> int:
        maxFish = 0
        unionFind = UnionFind(grid)
        rows, cols = len(grid), len(grid[0])

        def convert(r, c):
            return r*cols + c

        for row in range(rows):
            for col in range(cols):
                if grid[row][col] > 0:
                    u = convert(row, col)
                    maxFish = max(maxFish, grid[row][col])
                    if row+1 < rows and grid[row+1][col] > 0:
                        vD = convert(row+1, col)
                        maxFish = max(maxFish, unionFind.union(u, vD))
                    if col+1 < cols and grid[row][col+1] > 0:
                        vR = convert(row, col+1)
                        maxFish = max(maxFish, unionFind.union(u, vR))
        return maxFish

# Unit Tests
funcs = [Solution().findMaxFish]

class TestFindMaxFish(unittest.TestCase):
    def testFindMaxFish1(self):
        for func in funcs:
            grid = [[0, 2, 1, 0], [4, 0, 0, 3], [1, 0, 0, 4], [0, 3, 2, 0]]
            self.assertEqual(func(grid=grid), 7)

    def testFindMaxFish2(self):
        for func in funcs:
            grid = [[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 1]]
            self.assertEqual(func(grid=grid), 1)

if __name__ == "__main__":
    unittest.main()


# Example 1
word = "Python"
for letter in word:
    print(letter, end="*")

# Example 2
for i in range(1, 10):
    if i % 2 == 0:
        print(i)

text = "OpenEDG Python Institute"
for letter in text:
    if letter == "P":
        break
    print(letter, end="")

text = "pyxpyxpyx"
for letter in text:
    if letter == "x":
        continue
    print(letter, end="")


"""
    Ahoj,

    není vůbec od věci si opakovat i základní věci, není prostě možné,
    abychom se po 3 setkáních setkali a nebylo jasné, jak udělat

    šuplíček = input("Něco si přej: ")

    a podobně.

    Tyhle úkoly je BEZPODMÍNEČNĚ nutné umět, jinak nejdeme dál,
    byla by to ztráta času všech.
"""

"""
*   Úkol 1  *

    Vytvoř skriptík, který se zeptá uživatele na nějaké písmenko.

    Program toto písmenko uloží "do šuplíčku."

    Program porovná, jestli se písmenko rovná 'a' a pokud ano,
    napíše "jupí, je to áčko," jinak "nu nic, tohle není áčko."

    Dagmar, vím, že to zvládneš, ale spíše pro M.
"""

# Úkol 1 -- nejsnazší řešení
pismenko = input("Zadej písmenko: ")
if pismenko == 'a':
    print("Jupí, je to áčko.")
else:
    print("Nu nic, není to áčko.")

# Úkol 1 -- vylepšení
# pismenko už buud počítat, že je zadané z předchozího řešení

if len(pismenko) > 1:
    print("Tohle není samostatné písmenko!")
else:
    if pismenko == 'a':
        print("Jupí, áčko.")
    else:
        print("Nu nic, není áčko.")

"""
*   Úkol 2  *

    Vytvoř prográmek, který se zeptá uživatele na číslo.

    Toto číslo se uloží do šuplíčku a převede na int() v jednom kroku.

    Program zjistí, jestli zadané číslo je větší než 3 a podle toho
    napíše buď "číslo je větší než 3," "číslo je rovné 3"
    nebo "číslo je menší než 3."

    Vylepšená verze bude kontrolovat, jestli zadaná věc je číslo,
    ale to už je složitější, bude mi úplně stačit první varianta
    2. úkolu.
"""

# Úkol 2 -- základní verze
zadane_cislo = input("Zadej nějaké celé číslo: ")

"""
# tutu část si odkomentuj, jestli chceš základní řešení

cislo = int(zadane_cislo)
if cislo > 3:
    print(f"Číslo {cislo} je větší než 3.")
elif cislo == 3:
    print(f"Číslo {cislo} je rovné 3.")
else:
    print(f"Číslo {cislo} je menší než 3.")
"""

# Úkol 2 -- vylepšená verze s kontrolou
# Budu počítat s tím, že zadane_cislo máme už

try:
    cislo = int(zadane_cislo)
    if cislo > 3:
        print(f"Číslo {cislo} je větší než 3.")
    elif cislo == 3:
        print(f"Číslo {cislo} je rovné 3.")
    else:
        print(f"Číslo {cislo} je menší než 3.")

except ValueError:
    print("Není číslo.")


N       = int(input())
targets = list(map(int, input().split()))
targets.extend([0, 0])

dp = [[[0]*61 for _ in range(61)] for _ in range(61)] # 남은 체력으로 indexing
dp[targets[0]][targets[1]][targets[2]] = 1 # 첫번째

cases = [(9,3,1), (9,1,3), (3,9,1), (3,1,9), (1,9,3), (1,3,9)]
for i in range(60, -1, -1):
    for j in range(60, -1, -1):
        for k in range(60, -1, -1):
            if dp[i][j][k] > 0: # 체력이 있으면~ 진행
                for case in cases:
                    ni = i-case[0] if i-case[0] >= 0 else 0
                    nj = j-case[1] if j-case[1] >= 0 else 0
                    nk = k-case[2] if k-case[2] >= 0 else 0
                    if dp[ni][nj][nk] == 0 or dp[ni][nj][nk] > dp[i][j][k] + 1:
                        dp[ni][nj][nk] = dp[i][j][k] + 1
print(dp[0][0][0]-1)


import pygame
import pygame.gfxdraw
import random
from variables import *

class Plant:
    def __init__(self, x, y, energy):
        self.x = x
        self.y = y
        self.energy = energy

    def draw(self, screen, PLANT_COLOR, PLANT_COLOR2):
        radius = max(2, min(4, int(self.energy / 20)))
        pygame.gfxdraw.filled_circle(screen, int(self.x), int(self.y), radius, PLANT_COLOR)
        pygame.gfxdraw.aacircle(screen, int(self.x), int(self.y), radius, PLANT_COLOR)
        pygame.gfxdraw.aacircle(screen, int(self.x), int(self.y), radius - 2 , PLANT_COLOR2)
        pygame.gfxdraw.filled_circle(screen, int(self.x), int(self.y), radius - 2, PLANT_COLOR2)

    def generate_new_plant(plant):
        new_x = plant.x + random.randint(-200, 200)
        new_y = plant.y + random.randint(-200, 200)
        if 390 <= new_x <= SCREEN_WIDTH and SCREEN_HEIGHT - 590 <= new_y <= SCREEN_HEIGHT - 10:
            return Plant(new_x, new_y, plant.energy / 200)
        else:
            return None

    def grow(self):
        self.energy = min(self.energy + PLANT_GROWTH_RATE * self.energy, 100)


#!/usr/bin/env python3

# f.py is the main of FluidPyPLC project.
# This script will help you analyze your sequence.
# It will create the folders for storing your data files.
# You can copy and paste the created plc.st code into any PLC programming software.
# You can also convert the plc.st code into PLCopenXML output.xml file.
# You can import the PLCopenXML .xml file into CODESYS and it will start right away.
# Enjoy my little project. Thanks to all for the support.

from tkinter import *

from FluidPyPLC.get_sequence import Sequence
from FluidPyPLC.diagrams import diagrams
from FluidPyPLC.plc import Plc
from FluidPyPLC.GUI import Gui

import argparse
import json
import os
import pkg_resources
import subprocess
import textwrap

config_file_path = pkg_resources.resource_filename('FluidPyPLC', 'resources/config.json')
try:
    with open(config_file_path) as f:
        config = json.load(f)
        path = config["folder_path"]
except Exception as e:
    print(e)

def create_folders(folder_path):
    plots_folder = os.path.join(folder_path, 'Plots')
    plc_folder = os.path.join(folder_path, 'plc')

    # Create the Plots and plc folders
    os.makedirs(plots_folder, exist_ok=True)
    os.makedirs(plc_folder, exist_ok=True)

    print(f"Created 'Plots' and 'plc' folders inside '{folder_path}'.")

    # Set this path to the config.json file
    with open(config_file_path) as f:
        config = json.load(f)
    config["folder_path"] = folder_path

    with open(config_file_path, 'w') as f:
        json.dump(config, f, indent=4)

# function to start the terminal version
def terminal():
    sequence = Sequence()
    s = sequence.s
    diagrams(s)
    Plc(s)

# args management
def main():
    parser = argparse.ArgumentParser(
        description='FluidPyPLC',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=textwrap.dedent('''Example:
        f.py --gui # to use the user interface mode
        f.py -t # to use the terminal version
        f.py --plc # to display the plc ST code
        ''')
    )
    parser.add_argument('-g', '--gui', action='store_true', help='gui mode')
    parser.add_argument('-t', '--terminal', action='store_true', help='terminal mode')
    parser.add_argument('--plc', action='store_true', help='show plc code')
    parser.add_argument('-f', '--folder', type=str, help='Config.json folder path to create the Plot and plc folders')
    args = parser.parse_args()
    if args.folder:
        folder_path = args.folder
        create_folders(folder_path)
        exit(0)
    if args.gui:
        # gui mode
        gui = Gui()
        gui.gui_mode()
        exit(0)
    elif args.terminal:
        # terminal mode
        terminal()
        exit(0)
    elif args.plc:
        try:
            # open plc ST code with notepad
            dir = os.path.join(path, 'plc/plc.st')
            subprocess.call(['notepad.exe', dir])
        except Exception as e:
            print("There is a problem opening the file:")
            print(e)
    else:
        # default argument
        terminal()
        exit(0)


from enum import Enum

class Type(Enum):
    FC = 1
    ACTV = 2
    POOL = 3
    CONV = 4
    DEPTH = 5
    SEPAR = 6
    GEMM = 7
    LSTM = 8

class Buf(Enum):
    UBUF = 1
    WBUF = 2
    ACCQ = 3

class Op(Enum):
    LOAD_TILE = 1
    GEMM_OP = 2
    CONV_OP = 3
    VECTOR_OP = 4
    STORE_TILE = 5
    STORE_FAKE = 6
    NOP = 7

class Sched(Enum):
    FCFS = 1
    RRB = 2
    HPF = 3
    TOKEN = 4
    SJF = 5
    PREMA = 6

class Mecha(Enum):
    STATIC = 1
    DYNAMIC = 2


"""
owtf.db.worklist_manager
~~~~~~~~~~~~~~~~~~~~~~~~

The DB stores worklist
"""

from sqlalchemy.sql import not_

from owtf.db import models
from owtf.dependency_management.dependency_resolver import BaseComponent
from owtf.lib import exceptions

class WorklistManager(BaseComponent):

    COMPONENT_NAME = "worklist_manager"

    def __init__(self):
        self.register_in_service_locator()
        self.db = self.get_component("db")
        self.plugin_output = None
        self.target = None
        self.db_plugin = None

    def init(self):
        self.target = self.get_component("target")
        self.plugin_output = self.get_component("plugin_output")
        self.db_plugin = self.get_component("db_plugin")

    def _generate_query(self, criteria=None, for_stats=False):
        """Generate query based on criteria

        :param criteria: Filter criteria
        :type criteria: `dict`
        :param for_stats: True/False
        :type for_stats: `bool`
        :return:
        :rtype:
        """
        if criteria is None:
            criteria = {}
        query = self.db.session.query(models.Work).join(models.Target).join(models.Plugin).order_by(models.Work.id)
        if criteria.get('search', None):
            if criteria.get('target_url', None):
                if isinstance(criteria.get('target_url'), list):
                    criteria['target_url'] = criteria['target_url'][0]
                query = query.filter(models.Target.target_url.like('%%%s%%' % criteria['target_url']))
            if criteria.get('type', None):
                if isinstance(criteria.get('type'), list):
                    criteria['type'] = criteria['type'][0]
                query = query.filter(models.Plugin.type.like('%%%s%%' % criteria['type']))
            if criteria.get('group', None):
                if isinstance(criteria.get('group'), list):
                    criteria['group'] = criteria['group'][0]
                query = query.filter(models.Plugin.group.like('%%%s%%' % criteria['group']))
            if criteria.get('name', None):
                if isinstance(criteria.get('name'), list):
                    criteria['name'] = criteria['name'][0]
                query = query.filter(models.Plugin.name.ilike('%%%s%%' % criteria['name']))
        try:
            if criteria.get('id', None):
                if isinstance(criteria.get('id'), list):
                    query = query.filter(models.Work.target_id.in_(criteria.get('id')))
                if isinstance(criteria.get('id'), str):
                    query = query.filter_by(target_id=int(criteria.get('id')))
            if not for_stats:
                if criteria.get('offset', None):
                    if isinstance(criteria.get('offset'), list):
                        criteria['offset'] = criteria['offset'][0]
                    query = query.offset(int(criteria['offset']))
                if criteria.get('limit', None):
                    if isinstance(criteria.get('limit'), list):
                        criteria['limit'] = criteria['limit'][0]
                    query = query.limit(int(criteria['limit']))
        except ValueError:
            raise exceptions.InvalidParameterType("Invalid parameter type for transaction db")
        return query

    def _derive_work_dict(self, work_model):
        """Fetch work dict based on work model

        :param work_model: Model
        :type work_model:
        :return: Work dict
        :rtype: `dict`
        """
        if work_model is not None:
            wdict = dict()
            wdict["target"] = self.target.get_target_config_dict(work_model.target)
            wdict["plugin"] = self.db_plugin.derive_plugin_dict(work_model.plugin)
            wdict["id"] = work_model.id
            wdict["active"] = work_model.active
            return wdict

    def _derive_work_dicts(self, work_models):
        """Fetch list of work dicts based on list of work models

        :param work_models: List of work models
        :type work_models: `list`
        :return: List of work dicts
        :rtype: `dict`
        """
        results = []
        for work_model in work_models:
            if work_model is not None:
                results.append(self._derive_work_dict(work_model))
        return results

    def get_work(self, in_use_target_list):
        """Get work for target list in use

        :param in_use_target_list: Target list in use
        :type in_use_target_list: `list`
        :return: A tuple of target, plugin work
        :rtype: `tuple`
        """
        query = self.db.session.query(models.Work).filter_by(active=True).order_by(models.Work.id)
        if len(in_use_target_list) > 0:
            query = query.filter(not_(models.Work.target_id.in_(in_use_target_list)))
        work_obj = query.first()
        if work_obj:
            # First get the worker dict and then delete
            work_dict = self._derive_work_dict(work_obj)
            self.db.session.delete(work_obj)
            self.db.session.commit()
            return (work_dict["target"], work_dict["plugin"])

    def get_all(self, criteria=None):
        """Get all work dicts based on criteria

        :param criteria: Filter criteria
        :type criteria: `dict`
        :return: List of work dicts
        :rtype: `list`
        """
        query = self._generate_query(criteria)
        works = query.all()
        return self._derive_work_dicts(works)

    def get(self, work_id):
        """Get the work for work dict ID

        :param work_id: Work ID
        :type work_id: `int`
        :return: List of work dicts
        :rtype: `list`
        """
        work = self.db.session.query(models.Work).get(work_id)
        if work is None:
            raise exceptions.InvalidWorkReference("No work with id %s" % str(work_id))
        return self._derive_work_dict(work)

    def group_sort_order(self, plugin_list):
        """Sort work into a priority of plugin type

        .note::
            TODO: Fix for individual plugins
            # Right now only for plugin groups launched not individual plugins
            # Giving priority to plugin type based on type
            # Higher priority == run first!

        :param plugin_list: List of plugins to right
        :type plugin_list: `list`
        :return: Sorted list of plugin list
        :rtype: `list`
        """
        priority = {"grep": -1, "bruteforce": 0, "active": 1, "semi_passive": 2, "passive": 3, "external": 4}
        # reverse = True so that descending order is maintained
        sorted_plugin_list = sorted(plugin_list, key=lambda k: priority[k['type']], reverse=True)
        return sorted_plugin_list

    def add_work(self, target_list, plugin_list, force_overwrite=False):
        """Add work to the worklist

        :param target_list: target list
        :type target_list: `list`
        :param plugin_list: plugin list
        :type plugin_list: `list`
        :param force_overwrite: True/False, user choice
        :type force_overwrite: `bool`
        :return: None
        :rtype: None
        """
        if any(plugin['group'] == 'auxiliary' for plugin in plugin_list):
            # No sorting if aux plugins are run
            sorted_plugin_list = plugin_list
        else:
            sorted_plugin_list = self.group_sort_order(plugin_list)
        for target in target_list:
            for plugin in sorted_plugin_list:
                # Check if it already in worklist
                if self.db.session.query(models.Work).filter_by(target_id=target["id"],
                                                                plugin_key=plugin["key"]).count() == 0:
                    # Check if it is already run ;) before adding
                    is_run = self.plugin_output.plugin_already_run(plugin, target_id=target["id"])
                    if (force_overwrite is True) or (force_overwrite is False and is_run is False):
                        # If force overwrite is true then plugin output has
                        # to be deleted first
                        if force_overwrite is True:
                            self.plugin_output.delete_all({"plugin_key": plugin["key"]}, target_id=target["id"])
                        work_model = models.Work(target_id=target["id"], plugin_key=plugin["key"])
                        self.db.session.add(work_model)
        self.db.session.commit()

    def remove_work(self, work_id):
        """Remove work dict from worklist

        :param work_id: Work ID
        :type work_id: `int`
        :return: None
        :rtype: None
        """
        work_obj = self.db.session.query(models.Work).get(work_id)
        if work_obj is None:
            raise exceptions.InvalidWorkReference("No work with id %s" % str(work_id))
        self.db.session.delete(work_obj)
        self.db.session.commit()

    def delete_all(self):
        """Delete all work from the worklist

        :return: None
        :rtype: None
        """
        query = self.db.session.query(models.Work)
        for work_obj in query:
            self.db.session.delete(work_obj)
        self.db.session.commit()

    def patch_work(self, work_id, active=True):
        """Patch work dict in the worklist

        :param work_id: Work dict id
        :type work_id: `int`
        :param active: Is work active or not
        :type active: `bool`
        :return: None
        :rtype: None
        """
        work_obj = self.db.session.query(models.Work).get(work_id)
        if work_obj is None:
            raise exceptions.InvalidWorkReference("No work with id %s" % str(work_id))
        if active != work_obj.active:
            work_obj.active = active
            self.db.session.merge(work_obj)
            self.db.session.commit()

    def pause_all(self):
        """Pause all work in the worklist

        :return: None
        :rtype: None
        """
        query = self.db.session.query(models.Work)
        query.update({"active": False})
        self.db.session.commit()

    def resume_all(self):
        """Resume all work in the worklist

        :return: None
        :rtype: None
        """
        query = self.db.session.query(models.Work)
        query.update({"active": True})
        self.db.session.commit()

    def stop_plugins(self, plugin_list):
        """Stop list of plugins from the worklist

        :param plugin_list: List of plugins to stop
        :type plugin_list: `list`
        :return: None
        :rtype: None
        """
        query = self.db.session.query(models.Work)
        for plugin in plugin_list:
            query.filter_by(plugin_key=plugin["key"]).update({"active": False})
        self.db.session.commit()

    def stop_targets(self, target_list):
        """Stop work in the worklist for a list of targets

        :param target_list: List of targets
        :type target_list: `list`
        :return: None
        :rtype: None
        """
        query = self.db.session.query(models.Work)
        for target in target_list:
            query.filter_by(target_id=target["id"]).update({"active": False})
        self.db.session.commit()

    def search_all(self, criteria):
        """Search the worklist

        .note::
            Three things needed
                + Total number of work
                + Filtered work dicts
                + Filtered number of works

        :param criteria: Filter criteria
        :type criteria: `dict`
        :return: Results of the search query
        :rtype: `dict`
        """
        total = self.db.session.query(models.Work).count()
        filtered_work_objs = self._generate_query(criteria).all()
        filtered_number = self._generate_query(criteria, for_stats=True).count()
        results = {
            "records_total": total,
            "records_filtered": filtered_number,
            "data": self._derive_work_dicts(filtered_work_objs)
        }
        return results


import time
from box import Box

def init_timings():
    return Box({
        'current_time': time.time(),
        'last_time_idle': time.time(),
        'last_time_swapped': time.time(),
    })

def time_to_swap_games(timings):
    been_8_hours_since_change = timings.current_time - timings.last_time_swapped > 60 * 60 * 8
    been_20_mins_since_idle = timings.current_time - timings.last_time_idle > 60 * 20
    between_3_and_5am = 3 < time.localtime().tm_hour < 5
    return been_8_hours_since_change and between_3_and_5am and been_20_mins_since_idle