#!/usr/bin/env python3
import sys
import logging
from timeit import default_timer as timer

import util

LOG_LEVEL = logging.DEBUG

def reset_program(program):
    for instruction in program:
        instruction[2] = False

def run_program(program):
    reset_program(program)
    accumulator = 0
    ip = 0
    programLoops = True
    while True:
        if ip >= len(program):
            # The program finished
            programLoops = False
            break

        instruction = program[ip]

        if instruction[2] == True:
            programLoops = True
            break
        elif instruction[0] == "jmp":
            ip += instruction[1]
        elif instruction[0] == "acc":
            accumulator += instruction[1]
            ip += 1
        elif instruction[0] == "nop":
            ip += 1
        else:
            logging.error("Unknown operation")
            sys.exit(1)

        instruction[2] = True # Flag the command as seen before

    return programLoops, accumulator

def main(input_file):

    program = []

    with open(input_file) as f:
        while True:
            line = f.readline().strip()
            if not line:
                break
            parts = line.split(" ")
            program.append([parts[0], int(parts[1]), False])
    logging.debug(program)

    programLoops, accumulator = True, 0
    last_flipped_instruction = 0

    while programLoops:

        to_flip = last_flipped_instruction
        flipped = False

        instruction = program[to_flip]
        if instruction[0] == "nop":
            flipped = True
            instruction[0] = "jmp"
        elif instruction[0] == "jmp":
            flipped = True
            instruction[0] = "nop"

        if flipped:
            logging.debug("Flipped instruction {} to {}".format(to_flip, instruction[0]))
            programLoops, accumulator = run_program(program)

            if not programLoops:
                logging.debug("Program Finished Successfully")

            # Flip the instruction back
            instruction[0] = "nop" if instruction[0] == "jmp" else "jmp"
        else:
            logging.debug("Ignoring instruction {}".format(to_flip))

        last_flipped_instruction = to_flip + 1

    logging.info("Answer: Accumulator Value {}".format(accumulator))

if __name__ == "__main__":

    logging.basicConfig(format='%(levelname)s:%(module)s: %(message)s', level=LOG_LEVEL)

    if len(sys.argv) < 2:
        logging.critical("Missing input file")
    else:
        start = timer()
        main(sys.argv[1])
        end = timer()

        logging.info(f'Executed in {(end-start):.5f} seconds')


import inspect, optuna
import numpy as np
from optuna.trial import Trial
from dataclasses import dataclass
from typing import Optional, Dict, Any, Union, Tuple, Iterable, Callable
from types import MappingProxyType

class SpaceTypeValidationMixin:
    def is_space_type(self, space: Union[Dict, Iterable], type: Callable) -> bool:
        if type not in [float, int]:
            raise ValueError(
                f"is_space_type method expects type being checked to be 'int' or 'float', got {type}."
                f" To check for categorical types, try using the `is_valid_categorical_space(...)` method"
            )

        if (isinstance(space, dict) or isinstance(space, MappingProxyType)):
            valid_keys = ["low", "high"]
            for key in valid_keys:
                if key not in space.keys():
                    raise ValueError(f"defined non-categorical space is missing key-value '{key}'")

            if space["low"] > space["high"]:
                raise ValueError(f"low cannot be greater than high in space: {space}")

            if "log" in space.keys():
                if not isinstance(space["log"], bool):
                    raise TypeError(f"log is expected to be bool type, got {type(space['log'])} instead")

            if "step" in space.keys():
                if space["step"] is not None:
                    if not isinstance(space["step"], float) or not isinstance(space["step"], int):
                        raise TypeError(f"step is expected to be numerical type, got {type(space['step'])} instead")

            return all(list(map(lambda x: isinstance(x, type), [space["low"], space["high"]])))

        return False

    def is_valid_int_space(self, space: Iterable) -> bool:
        return self.is_space_type(space, int)

    def is_valid_float_space(self, space: Iterable) -> bool:
        return self.is_space_type(space, float)

    def is_valid_categorical_space(self, space: Iterable) -> bool:
        return (not self.is_valid_float_space(space)) and (not self.is_valid_float_space(space))

class TrialCheckMixin:
    def in_trial(self, trial: Optional[Trial]=None) -> Dict[str, Any]:
        if trial is None: raise ValueError("Method should be called in an optuna trial study")

class SampledModelEvaluationMixin:
    def _evaluate_params(self, model_class: Callable, params: Dict[str, Any]):
        assert isinstance(model_class, Callable), f"Invalid model_class, {model_class} is not Callable"

        param_names = list(params.keys())
        valid_param_names = list(inspect.signature(model_class.__dict__["__init__"]).parameters.keys())

        for param_name in param_names:
            if param_name not in valid_param_names:
                raise ValueError(f"invalid argument {param_name} for {model_class.__name__}")

    def _random_classification_set(self, is_multitask: bool=False) -> Tuple[Iterable]:
        if not is_multitask:
            return np.abs(np.random.randn(25, 5)), np.random.randint(0, 2, size=(25))

        else:
            return np.abs(np.random.randn(25, 5)), np.random.randint(0, 2, size=(25, 2))

    def _random_regression_set(self, is_multitask: bool=False) -> Tuple[Iterable]:
        if not is_multitask:
            return np.abs(np.random.randn(25, 5)), np.abs(np.random.randn(25)) + 1e-4

        else:
            return np.abs(np.random.randn(25, 5)), np.abs(np.random.randn(25, 2)) + 1e-4

    def evaluate_sampled_model(
            self,
            task: str,
            model_class: Callable,
            params: Dict[str, Any],
            is_multitask: bool=False) -> Any:

        valid_tasks: Iterable[str] = ["regression", "classification"]
        assert task in valid_tasks, (
            f"Invalid task for self._evaluate_sampled_model, expected task to be one of {valid_tasks}, got {task}"
        )

        self._evaluate_params(model_class, params)

        if task == "regression":
            X, y = self._random_regression_set(is_multitask)
        else:
            X, y = self._random_classification_set(is_multitask)

        try:
            model_class(**params).fit(X, y)
        except (ValueError, NotImplementedError) as e:
            raise optuna.exceptions.TrialPruned(e)

        model = model_class(**params)

        return model

@dataclass
class BaseTuner(SpaceTypeValidationMixin, TrialCheckMixin, SampledModelEvaluationMixin):
    r"""
    BaseTuner class that everyother tuner extends from

    If you wish to implement a custom tuner class with some default parameters,
    you must first extend from the BaseTuner class. The custom tuner must
    have the class attribute 'model_class' of type (Callable), which indicates
    the class of the model being tuned::

        @dataclass
        class CustomTuner(BaseTuner):
            model_class: Callable = GaussianProcessRegressor
            #int space
            param1_space: Dict[str, Any] = MappingProxyType({
                "low":2,
                "high":1000,
                "step":1,
                "log":True,
            })
            #float space
            param2_space: Dict[str, Any] = MappingProxyType({
                "low":0.1,
                "high":1.0,
                "step":None,
                "log":False,
            })
            #categorical space
            param3_space: Iterable[str] = ("cat1", "cat2", "cat3", "cat4")

            def sample_params(self, trial: Optional[Trial]=None) -> Dict[str, Any]:
                super().sample_params(trial)

                params = {}
                params["param1"] = trial.suggest_int(
                    f"{self.__class__.__name__}_param1", **dict(self.param1_space))
                params["param2"] = trial.suggest_float(
                    f"{self.__class__.__name__}_param2", **dict(self.param2_space))
                params["param3"] = trial.suggest_categorical(
                    f"{self.__class__.__name__}_param3", self.param3_space)

                return params

            def sample_model(self, trial: Optional[Trial]=None) -> Any:
                super().sample_model(trial)
                params = self.sample_params(trial)

                model = super().evaluate_sampled_model(
                    "regression", self.model_class, params)

                self.model = model
                return model
    """
    model: Any = None

    def sample_params(self, trial: Trial) -> Dict[str, Any]:
        r"""

        Parameter
        ---------
        trial: optuna.trial.Trial
            optuna trial

        Return
        ------
        params: Dict[str, Any]
            collected parameters sampled from the defined search space
        """
        super().in_trial(trial)

    def sample_model(self, trial: Trial) -> Any:
        r"""
        Parameter
        ---------
        trial: optuna.trial.Trial
            optuna trial

        Return
        ------
        params: Any
            model initialised with sampled parameters
        """
        super().in_trial(trial)


from kivy.uix.widget import Widget
from kivy.uix.scatter import Scatter
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.properties import BoundedNumericProperty

class Gauge(Widget):
    value = BoundedNumericProperty(0, min=-20, max=120, errorvalue=0)
    def __init__(self, **kwargs):
        super(Gauge, self).__init__(**kwargs)
        self._gauge = Image(
            size = (320, 320),
            pos_hint={'x': 0.1, 'y': .3},
            source = './merilec/temperatura_merilec.png',
        )
        self._needle = Scatter(
            size = (320, 320),
            do_rotation = False,
            do_scale = False,
            do_translation = False
        )
        self._needle.add_widget(Image(
            source = "./merilec/needle.png",
            size = (320, 320)
        ))
        self.add_widget(self._gauge)
        self.add_widget(self._needle)
        self.bind(pos=self._update)
        self.bind(size=self._update)
        self.bind(value=self._turn)

    def _update(self, *args):
        self._gauge.pos = self.pos
        self._needle.pos = (self.x, self.y)
        self._needle.center = self._gauge.center

    def _turn(self, *args):
        self._needle.center_x = self._gauge.center_x
        self._needle.center_y = self._gauge.center_y
        self._needle.rotation = (50 * 1.8) - (self.value * 1.8)


#Math Solve
#Page 7 of CU python101_workbook_v1.0.2
#Input: รับจำนวนเต็ม 1 จำนวนจากแป้นพิมพ์ เก็บใน X
#Process: y = 2-x+(3/7)*x**2-(5/11)x**3+ log(x)
# Output: ค่า y ที่คำนวณได้

import math
x = float(input())
y = 2-x+(3/7)*x**2-(5/11)*x**3+math.log10(x)
print(y)


from language.bert.colotensor.model.hfmodel import ModelFromHF
from colossalai.core import global_context as gpc
from transformers import BertConfig, BertForMaskedLM

_bert_base = dict(
    seq_length=512,
    vocab_size=50304,
    hidden_size=768,
    num_heads=12,
    depth=12,
    ff_size=3072,
    checkpoint=False,
    evaluation='ppl',
)

_bert_large = dict(
    seq_length=512,
    vocab_size=50304,
    hidden_size=1024,
    num_heads=16,
    depth=24,
    ff_size=3072,
    checkpoint=False,
    evaluation='ppl',
)

_bert_configurations = dict(
    bert=_bert_base,
    bert_base=_bert_base,
    bert_large=_bert_large
)

def build_model():
    model_cfg = _bert_configurations[gpc.config.model.type]
    bert_cfg = BertConfig(vocab_size=model_cfg['vocab_size'],
                          hidden_size=model_cfg['hidden_size'],
                          num_hidden_layers=model_cfg['depth'],
                          num_attention_heads=model_cfg['num_heads'],
                          intermediate_size=model_cfg['ff_size'],
                          max_position_embeddings=model_cfg['seq_length'],
                          use_cache=not gpc.config.model.get('checkpoint', False))

    model = ModelFromHF(bert_cfg, BertForMaskedLM)

    return model

__all__ = ["build_model"]


# import contextlib
# import psutil
from pywinauto import Application
import logging
import threading
import warnings

import Utils
import win32gui, win32process

## Replace pyautogui with pywinauto   https://pywinauto.readthedocs.io/en/latest/index.html#what-is-it
import pyautogui

spotify_PID = None

def focus_v3(ids):
    pos = pyautogui.position()
    warnings.filterwarnings("ignore", category=UserWarning)
    #message("debug", f"focus_v3 has begun for {ids}")
    try:
        app = Application().connect(process=ids)
        app.top_window().set_focus()
        pyautogui.moveTo(pos)

    except Exception as e:
        #print(f"Thread {ids}: FAILED\n")
        #logging.info(f"Exception is: {e}")

        #return False
        pass

    else:
        #print(f"Thread {ids}: finished\n")
        global spotify_PID
        spotify_PID = ids
        pyautogui.press("playpause")

def Play_pause_V3():
    # press's play/pause, it will focus spotify if it is running.
    logging.info("Play_pause started")
    global spotify_PID
    listOfProcessIds = Utils.findProcessIdByName('Spotify')

    if listOfProcessIds != []:
        if spotify_PID is None or spotify_PID not in listOfProcessIds:
            # if PID is Not valid, need to find valid one
            threads = [None] * len(listOfProcessIds)
            for n in range(len(listOfProcessIds)):
                threads[n] = threading.Thread(target=focus_v3, args=(listOfProcessIds[n],)).start()

            logging.info("Finished")
            return

        # can use standard thready for focus
        x = threading.Thread(target=Utils.focus_v3, args=(spotify_PID,))
        x.start()
        logging.info("Finished")
        return

    #message("debug", "Spotify is NOT running")
    pyautogui.press("playpause")


from __future__ import print_function
from collections import namedtuple

X, O = 'X', None
Tetromino = namedtuple("Tetrimino", "color shape")

tetrominoes = {
    "long": Tetromino(color="blue",
                      shape=((O,O,O,O),
                             (X,X,X,X),
                             (O,O,O,O),
                             (O,O,O,O))),
    "square": Tetromino(color="yellow",
                        shape=((X,X),
                               (X,X))),
    "hat": Tetromino(color="pink",
                     shape=((O,X,O),
                            (X,X,X),
                            (O,O,O))),
    "right_snake": Tetromino(color="green",
                             shape=((O,X,X),
                                    (X,X,O),
                                    (O,O,O))),
    "left_snake": Tetromino(color="red",
                            shape=((X,X,O),
                                   (O,X,X),
                                   (O,O,O))),
    "left_gun": Tetromino(color="cyan",
                          shape=((X,O,O),
                                 (X,X,X),
                                 (O,O,O))),
    "right_gun": Tetromino(color="orange",
                           shape=((O,O,X),
                                  (X,X,X),
                                  (O,O,O)))
}
list_of_tetrominoes = list(tetrominoes.values())

def rotate(shape, times=1):
    """ Rotate a shape to the right """
    return shape if times == 0 else rotate(tuple(zip(*shape[::-1])), times-1)

def shape_str(shape):
    """ Return a string of a shape in human readable form """
    return '\n'.join(''.join(map({'X': 'X', None: 'O'}.get, line))
                     for line in shape)

def shape(shape):
    """ Print a shape in human readable form """
    print(shape_str(shape))
def test():
    tetromino_shapes = [t.shape for t in list_of_tetrominoes]
    map(rotate,    tetromino_shapes)
    map(shape,     tetromino_shapes)
    map(shape_str, tetromino_shapes)

    assert shape_str(tetrominoes["left_snake"].shape) == "XXO\nOXX\nOOO"

    assert rotate(tetrominoes["square"].shape) == tetrominoes["square"].shape

    assert rotate(tetrominoes["right_snake"].shape, 4) == tetrominoes["right_snake"].shape

    assert rotate(tetrominoes["hat"].shape)    == ((O,X,O),
                                                   (O,X,X),
                                                   (O,X,O))

    assert rotate(tetrominoes["hat"].shape, 2) == ((O,O,O),
                                                   (X,X,X),
                                                   (O,X,O))
    print("All tests passed in {}, things seems to be working alright".format(__file__))

if __name__ == '__main__':
    test()


from socket import *
import time
import json

class RPCClient():
    def __init__(self, ip, port):

        self.tcp_client = socket(AF_INET, SOCK_STREAM)
        self.tcp_client.connect((ip, port))

    def call(self, functionName, parameters):
        data = {
            "type": "request",
            "async":True,
            "functionName": functionName,
            "parameters": parameters
        }
        msg = json.dumps(data)
        self.tcp_client.sendall(msg.encode("utf-8"))
        # result = self.tcp_client.recv(1024).decode("utf-8")
        # print("服务器命令执行的结果是:", result)
        # return result

if __name__ == "__main__":
    c = RPCClient("127.0.0.1",8000)
    i=0
    while True:
        c.call("add",[i,0])
        time.sleep(0.5)


from .basehandler import BaseHandler

from ppmessage.db.models import DeviceInfo
from ppmessage.db.models import DeviceUser
from ppmessage.core.redis import redis_hash_to_dict
from ppmessage.core.constant import INVALID_IOS_TOKEN
from ppmessage.core.constant import API_LEVEL

from ppmessage.api.error import API_ERR

import logging
import json

class SetDeviceInfoHandler(BaseHandler):
    """
    requst:
    header with device uuid
    body {fullname:, ostype:, osversion:, apilevel:, phone:, iostoken:, iosmodel:,}

    ostype: IOS/ANDROID/WP/MAC/WIN/LINUX
    response:
    device id/ device uuid

    """

    def _post(self, _request):
        _device_uuid = _request.get("device_uuid")

        if _device_uuid == None:
            self.setErrorCode(API_ERR.ERR_PARAM)
            return

        _redis = self.application.redis
        _device = redis_hash_to_dict(_redis, DeviceInfo, _device_uuid)

        if _device is None:
            logging.error("Error NO DEVICE for key [%s] ." % (_key))
            self.setErrorCode(API_ERR.NO_DEVICE)
            return

        _values = {
            "uuid": _device_uuid
        }

        if "fullname" in _request:
            _values["device_fullname"]= _request["fullname"]

        if "ostype" in _request:
            _values["device_ostype"] = _request["ostype"].upper()

        if "osversion" in _request:
            _values["device_osversion"] = _request["osversion"]

        # apilevel for android
        if "apilevel" in _request:
            _values["device_android_apilevel"] = _request["apilevel"]

        # phone number for phone
        if "phone" in _request:
            _values["device_phonenumber"] = _request["phone"]

        if "iosmodel" in _request:
            _values["device_ios_model"] = _request["iosmodel"]

        if "iostoken" in _request:
            _values["device_ios_token"] = _request["iostoken"]
            self.application.redis.srem(INVALID_IOS_TOKEN, _request["iostoken"])

        _row = DeviceInfo(**_values)
        _row.update_redis_keys(_redis)
        _row.async_update()
        return

    def initialize(self):
        self.addPermission(api_level=API_LEVEL.PPKEFU)
        self.addPermission(api_level=API_LEVEL.THIRD_PARTY_KEFU)
        return

    def _Task(self):
        super(SetDeviceInfoHandler, self)._Task()
        self._post(json.loads(self.request.body))


#Escribir una funcion que reciba un diccionario con las notas de los alumnos en curso en un examen y devuelva una serie con las notas de los alumnos aprobados ordenadas de mayor a menor.

import pandas as pd

notas={'Anderson': 3.3, 'Beatriz': 3.5, 'Camilo': 3.6, 'Dora': 4.0, 'Anthony': 4.1, 'Carlos': 5.0}

def aprobados(notas):
    notas=pd.Series(notas)
    return notas[notas>=3].sort_values(ascending= False)  #ascendig false para ordenar ascendente

print(aprobados(notas))


#!/usr/bin/python
# -*- coding: UTF-8 -*-
import json

print()
print("Welcome to json analyze")
print("==========================")
print()

def analyzejson(text):
    jsonVlaue = json.loads(text)

    string = ""
    length = len(jsonVlaue)

    for key in jsonVlaue:
        string += key + "=" + jsonVlaue[key] + "&"

    string = string[0:-1]
    print(string)

print("input json string:")
text = input("> ")
while 1:
    if text == 'q' or text == 'quit':
        break
    else:
        analyzejson(text)
        text = input("> ")


def main():
    n = input()
    trees = list(map(int, input().split()))

    trees.sort(reverse=True)

    curr = 0
    _max = trees[0]
    for tree in trees:
        if tree > _max:
            curr += 1
            _max += 1

        _max-=1

    print(curr + trees[0] + 2)

    return

if __name__ == "__main__":
    main()


# -*- coding: utf-8 -*-
"""
Created on Mon Oct 31 19:08:07 2022

@author: zzc
"""

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

class Layer(nn.Module):
    def __init__(self, G, feature_attn_size, dropout, slope):  # dropout参数为了防止过拟合而设定

        super(Layer, self).__init__()

        self.disease_nodes = G.filter_nodes(lambda nodes: nodes.data['type'] == 1)  # list->[0->382]
        self.mirna_nodes = G.filter_nodes(lambda nodes: nodes.data['type'] == 0)  # list->[383->877]

        self.G = G

        # 'type':878列 0-382为1,else为0    'm_sim':878*495,下面是0    'd_sim':878*383,上面是0
        # print(self.G.edges())    # nodes(): tensor([0->877])     edges(): tensor([0...687],[383...337])
        # print(torch.sum(self.G.ndata['type'],dim=0))  结果为383
        self.slope = slope
        self.m_f = nn.Linear(G.ndata['m_sim'].shape[1], feature_attn_size,
                             bias=False)  # 权重矩阵 列数不变,行数变为feature_attn_size
        self.d_f = nn.Linear(G.ndata['d_sim'].shape[1], feature_attn_size, bias=False)
        self.dropout = nn.Dropout(dropout)
        self.reset_parameters()

    # 使用激活函数ReLu对权重进行重新设置
    def reset_parameters(self):
        gain = nn.init.calculate_gain('relu')
        nn.init.xavier_normal_(self.m_f.weight, gain=gain)
        nn.init.xavier_normal_(self.d_f.weight, gain=gain)

    def edge_attention(self, edges):  # 计算边的注意力euv
        a = torch.sum(edges.src['z'].mul(edges.dst['z']), dim=1).unsqueeze(
            1)  # torch.sum对输入的数据求某一维度的和,dim=0竖着求和,dim=1横着求和
        return {'e': F.leaky_relu(a, negative_slope=self.slope)}

    def message_func(self, edges):
        return {'z': edges.src['z'], 'e': edges.data['e']}

    def reduce_func(self, nodes):  # 对边的注意力系数进行归一化再求和
        # alpha注意力系数
        # alpha = 0.5
        alpha = F.softmax(nodes.mailbox['e'], dim=1)
        h = torch.sum(alpha * nodes.mailbox['z'], dim=1)

        return {'h': F.elu(h)}

    def forward(self, G):
        self.G.apply_nodes(lambda nodes: {'z': self.dropout(self.d_f(nodes.data['d_sim']))}, self.disease_nodes)
        self.G.apply_nodes(lambda nodes: {'z': self.dropout(self.m_f(nodes.data['m_sim']))}, self.mirna_nodes)

        self.G.apply_edges(self.edge_attention)
        self.G.update_all(self.message_func, self.reduce_func)

        return self.G.ndata.pop('h')

# 多头注意里机制
class MultiHeadLayer(nn.Module):
    def __init__(self, G, num_heads, dropout, slope, feature_attn_size, merge='cat'):
        super(MultiHeadLayer, self).__init__()

        self.G = G
        self.dropout = dropout
        self.slope = slope  # 激活函数的斜率
        self.merge = merge  # 拼接方式
        self.num_heads = num_heads
        self.feature_attn_size = feature_attn_size
        self.heads = nn.ModuleList()
        for i in range(num_heads):
            self.heads.append(Layer(G, feature_attn_size, dropout, slope))

    def forward(self, G):
        head_outs = [attn_head(G) for attn_head in self.heads]
        if self.merge == 'cat':
            return torch.cat(head_outs, dim=1)  # dim=1,左右拼接
        else:
            return torch.mean(torch.stack(head_outs), dim=0)  # dim=0,上下拼接


# Here you will find all the financial - analysis
# metrics.py
from inventory import get_bought_items, get_sold_items
from rich import print

total_cost_file = './files/total_cost.txt'
total_revenue_file = './files/total_revenue.txt'
cost_data = './files/cost.txt'
revenue_data = './files/revenue.txt'
profit_data = './files/profit.txt'

#  basic logic functions -->
def calculate_total_cost():
    try:
        with open(total_cost_file, 'r') as cost_file:
            return float(cost_file.readline().strip())
    except FileNotFoundError:
        print("Total cost file not found. Creating a new file.")
        with open(total_cost_file, 'w') as cost_file:
            cost_file.write("0.0")
        return 0.0
    except ValueError:
        print("Invalid total cost value in the file. Resetting total cost to 0.0.")
        with open(total_cost_file, 'w') as cost_file:
            cost_file.write("0.0")
        return 0.0

def calculate_total_revenue():
    try:
        with open(total_revenue_file, 'r') as revenue_file:
            total_revenue = revenue_file.readline().strip()
            if total_revenue:
                return float(total_revenue)
            else:
                return 0.0
    except (FileNotFoundError, ValueError):
        print("Error: Total revenue file not found or contains invalid data.")
        return 0.0

def calculate_total_profit():
    total_cost = calculate_total_cost()
    total_revenue = calculate_total_revenue()

    total_profit = total_revenue - total_cost
    return total_profit
# _____________________________________________________

# Computes total revenue on a specific date by iterating through sales data, identifying matching dates, and summing up earnings of sold items.
def calculate_revenue_by_date(target_date):
    sales_data = get_sold_items()
    total_revenue = 0

    for sale in sales_data:
        sale_date = sale.get('sell_date')
        amount = int(sale.get('amount'))
        earnings = float(sale.get('total_earnings'))

        if sale_date and sale_date == target_date:
            total_revenue += earnings

    return total_revenue

#  this one may not be used, but i spend hours and hours debugging, so i leave this "display revenue" code , also as a reference->
def display_revenue(sales_data, target_date):
    total_revenue = calculate_revenue_by_date(sales_data, target_date)
    date_label = f" for {target_date}"
    revenue_info = f"Total revenue{date_label}: ${total_revenue:.2f}"
    print(revenue_info)

# Writes total revenue information to a file for a specific date range.
def write_revenue_to_file(start_date, end_date, total_revenue):
    try:
        date_label = f" for {start_date}" if not end_date else f" between {start_date} and {end_date}"
        revenue_info = f"Total revenue{date_label}: ${total_revenue:.2f}"
        with open(revenue_data, 'a') as file:
            file.write(revenue_info + '\n')
        print(revenue_info)
    except Exception as e:
        print(f"An error occurred: {e}")

# Calculates total cost within a specified date range or on a specific date by summing the costs of items bought within that period.
def calculate_cost_by_date(start_date, end_date=None):
    bought_items = get_bought_items()

    if end_date:
        total_cost = sum(float(item['total_cost'])
                         for item in bought_items if start_date <= item['purchase_date'] <= end_date)
    else:
        total_cost = sum(float(item['total_cost'])
                         for item in bought_items if item['purchase_date'] == start_date)

    return total_cost

# Writes total cost information to a file for a specific date range
def write_cost_to_file(start_date, end_date, total_cost):
    date_label = f" for {start_date}" if not end_date else f" between {start_date} and {end_date}"
    cost_info = f"Total cost{date_label}: ${total_cost:.2f}"
    with open(cost_data, 'a') as file:
        file.write(cost_info + '\n')
    print(cost_info)

# Calculates total profit on a specific date by subtracting the total cost of items bought from the total revenue earned from sales on that date.
def calculate_profit_by_date(date):
    try:
        sold_items = get_sold_items()
        bought_items = get_bought_items()

        total_cost = sum(float(item['total_cost']) for item in bought_items
                         if item['expiration_date'] == date)
        total_revenue = sum(float(item['total_earnings']) for item in sold_items
                            if item['sell_date'] == date)

        total_profit = total_revenue - total_cost

        return total_profit
    except FileNotFoundError:
        print("File not found.")
        return 0.0

# Calculates total revenue between specified start and end dates by iterating through sold items' data.
def calculate_revenue_between_dates(start_date, end_date):
    sold_items = get_sold_items()
    total_revenue = 0
    for item in sold_items:
        sell_date = item.get('sell_date')
        if start_date <= sell_date <= end_date:
            total_revenue += float(item.get('total_earnings', 0))
    return total_revenue

# Determines total profit within a date range or on a specific date by subtracting total cost from total revenue, considering both items bought and items sold during that period.
def calculate_profit_between_dates(start_date, end_date=None):
    sold_items = get_sold_items()
    bought_items = get_bought_items()

    if end_date:
        total_revenue = sum(float(item.get('total_earnings', 0))
                            for item in sold_items if start_date <= item.get('sell_date', '') <= end_date)
        total_cost = sum(float(item['total_cost'])
                         for item in bought_items if start_date <= item['purchase_date'] <= end_date)
    else:
        total_revenue = sum(float(item.get('total_earnings', 0))
                            for item in sold_items if item.get('sell_date', '') == start_date)

        total_cost = sum(float(item['total_cost'])
                         for item in bought_items if item['purchase_date'] == start_date)

    total_profit = total_revenue - total_cost
    return total_profit

# Writes total profit information to a file for a specific date range.
def write_profit_to_file(start_date, end_date, total_profit):
    date_label = f" for {start_date}" if not end_date else f" between {start_date} and {end_date}"
    profit_info = f"Total profit{date_label}: ${total_profit:.2f}"
    with open(profit_data, 'a') as file:
        file.write(profit_info + '\n')
    print(profit_info)

if __name__ == "__main__":
    total_cost = calculate_total_cost()
    total_revenue = calculate_total_revenue()

    print(f"Total cost of all items bought: ${total_cost:.2f}")
    print(f"Total revenue from sales: ${total_revenue:.2f}")

    total_profit = calculate_total_profit()
    print(f"Total profit: ${total_profit:.2f}")


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Nov 24 12:30:33 2020

@author: Ashmita
#check loaction of user at every second and then
"""
import numpy as np
import variables
import math
import random

'''
function to convert a linear value to dB
'''
def linearToDb(linearVal):
    # factor is usually 1 but can change depending on situation
    dBvalue = 10*np.log10(linearVal)
    return dBvalue

'''
function to calculate the propagation loss using the Okamura-Hata model
'''
def propagationLoss(sector, currLocation):
    #initialising value of f according to prop
    if sector == 'Alpha':
        f = variables.frequencies[0]
    elif sector == 'Beta':
        f = variables.frequencies[1]
    #we divide the distane calculated from the basestation with 1000 to get the distance in kms
    distance = mobileBasestationDist(currLocation)/1000
    #propagation loss caused due to the mobile height
    mobileLoss = (1.1 * np.log10(f) - 0.7)*variables.mobileHeight - (1.56*np.log10(f) - 0.8)

    #total propagation loss at transmitter
    pL = 69.55 + 26.16*np.log10(f) - 13.82*np.log10(variables.baseHeight) + (44.9 - 6.55*np.log10(variables.baseHeight))*np.log10(distance) - mobileLoss

    return pL

'''
function to calculate the shadowing which is same for all sectors and has a
log-normal distribution with a zero mean and sigma = 2 dB
'''
def shadowing_init():
    # zero mean
    size = int((variables.roadLength*1000/10)) #we are told to calculte shadowing at every 10m
    mean = 0
    # standard deviation is 2 dB
    sigma = 2 #in dB

    #using np.random.normal to calcalte the log normal distribution of shadowing
    sample = np.random.normal(mean, sigma, size)

    return sample
'''
function to return the particular shadowing value based on the current Location of the User
'''
def shadowingValue(currLocation, sample):
    #the currentLocation is the relative location to the basetstation, therefore to find corresponding shadowing value we have to find it's location on the road
    relLoc = (variables.roadLength*1000/2) - currLocation

    #currLocation provided to us in meters so when we divide with 10 it should give us the index of the right shadowing value
    index = int(relLoc/10)
    #special case when the user is at the southmost bound
    if(relLoc == variables.roadLength*1000):
        index = int(relLoc/10) - 1

    return sample[index]

'''
function to calculate fading using a Rayleigh distribution with zero mean and
unit variance
It will be different for the two different sectors
'''
def fading():
    num_samples = 10
    variance = 1
    #using the built in function rayleigh distribute 10 samples
    mag = np.random.rayleigh(variance,num_samples)

    linear_z = []
    for i in range(num_samples):
        linear_z.append(linearToDb(mag[i]**2))

    #sorting the array of Rayleigh Samples generated in ascending order to get deepest fades
    linear_z.sort()

    #Taking the second deepest fade, so throwing away the first deepest fade and returning its value in dB
    return linear_z
'''
function to calculate the EIRP from the basestation to any particular point on
the antenna
'''
def EIRP(currLocation, sector):
    #calculate EIRP at boresight which is directly in front of antenna
    EIRPatBore = variables.P_Tx - variables.lineLoss + variables.antennaGain

    #Calculate the distance of the mobile from the basestation based on current location
    distanceFromMobile = mobileBasestationDist(currLocation)

    baseLocation_y = currLocation
    #creating a vector for the distance betwen a
    vectorV = [variables.baseLocation_x,baseLocation_y]

    #creating a unit vector in the direction the antenna is pointing based on which sector we are in
    if sector == 'Alpha':
        vectorU = [0,1]
    elif sector == 'Beta':
        vectorU = [math.sqrt(3)/2, -1/2]

    # calculate the magnitude of the unit vector
    unitMag = math.sqrt(vectorU[0]**2 + vectorU[1]**2)

    #calculate the angle off of boresight or the angle between the two vectors in radians
    theta_rad = np.arccos((vectorU[0]*vectorV[0] + vectorU[1]*vectorV[1])/(distanceFromMobile*unitMag))

    #converting thetha i radians to theta in degrees
    theta_deg = int(np.round(np.degrees(theta_rad)))

    anteDiscrim = antennaDiscrimination(str(theta_deg))
    finalEIRP = EIRPatBore - float(anteDiscrim)

    return finalEIRP

'''
function to return the antenna discrimination based on the information provided in
antenna_pattern.txt, according to the angle provided theta
'''
def antennaDiscrimination(theta):
    #using open file method to read all the line in the file antenna_pattern.txt
    file = open("antenna_pattern.txt").readlines()

    #iterarting through each line in the file to find a match for theta
    for line in file:
        if theta in line:
            val = line.split('\t')
            break

    #return the antenna discrimination value for matching theta
    return val[1].rstrip()

'''
function  to calculate the distance between the mobile and the basestation based
upon the current location of the car
'''
def mobileBasestationDist(currLocation):
    #currentLocation is provided in meters so we subtract 300m (location of the basestation)
    #and take its absolute value to get the distance between the mobile and basestation on the road

    #to calculate the diagonal distance between the basestation and the mobile we use Pythagoras Theorem
    distMobileBase = math.sqrt(currLocation**2 + variables.baseLocation_x**2)

    return distMobileBase

'''
function to calculate the received signal level at the mobile
'''
def RSL(sector, currentLocation, shadowSample):
    # the total path loss

    #calculate total propagation loss using the Okamura Hata model
    propLoss = propagationLoss(sector, currentLocation)

    #get the shadowing value according to the current location
    shadow = shadowingValue(currentLocation, shadowSample)

    #fading values for the alpha and beta sector
    linearVal = fading()
    if sector == 'Alpha':
        fade = linearVal[1]
    else:
        fade = linearVal[2]

    #EIRP values for the alpha and beta sectors
    EIRPval = EIRP(currentLocation,sector)

    #print("EIRP: ",EIRPval,"prop loss: ", propLoss, "shadow: ", shadow, "fade: ", fade,"loc: ", currentLocation)
    pathLoss = propLoss - shadow - fade

    # the total recieved signal level
    RSL = EIRPval - pathLoss

    return RSL
'''
function to determine if each user who does not have an active call is going
to make a call
'''
def makeCall():
    totalSeconds = 60*60
    #the probability of making a call every hour
    num = random.randint(1,totalSeconds)
    if (num <= variables.callRate):
        return True
    else:
        return False

'''
function to determine the direction the user is travelling in: there is a 50/50 chance that the user is travelling either
North direction or the South direction
'''
def getDirection():
    dir = random.randrange(-1, 2, 2)

    return dir # -1 for South and 1 for North

'''
function to get the initial location of each user. We will use np.random.uniform to generate initial location values that are
uniformly distributed between 0 and 6000 m
'''
def getInitialLocation():
    loc = np.random.uniform(0, variables.roadLength*1000)

    #The location relative to the basestation which is considered to be the origin
    location =  (variables.roadLength * 1000)/2 - loc
    return location

'''
function to determine the length of a call. Call lengths will be exponentially distributed so I am using the np.
'''
def lengthCall():
    #finding the call duration in seconds
    callDurSec = variables.callDuration *60

    return np.random.exponential(callDurSec)

'''
function to update the user's current ocation given the speed of travel as well as the time step
'''
def getCurrentLocation(initialLocation, direction):
    #calculating the distance travelled in the given time step
    distTravelled = variables.userSpeed * variables.timeStep * direction

    #updating location
    currentLocation = initialLocation + distTravelled

    return currentLocation

'''
function to update the time left of a call according to time step. When the timer runs out it marks the successful completion of a call
'''
def getCallTime(timeLeft):
    #return the timeLeft minus the timestep given to us
    return timeLeft - variables.timeStep


# Owen McKenney
# Photointerrupter
# This code counts the number of interruptions on a photointerurper
# And prints the total interruptions every 4 seconds

import board
import digitalio
import time
import adafruit_bus_device

# Pin setup for the photointerrupter
photoPin = digitalio.DigitalInOut(board.D8)
photoPin.direction = digitalio.Direction.INPUT
photoPin.pull = digitalio.Pull.UP

interrupts = -1 # This sets the inital interrupts at -1
initial = time.monotonic() # This sets the initial time to time.monotonic()
fread = True
lread = True

while True:
    now = time.monotonic()
    if now - initial == 4: # This if statement prints out the number of interruptions every 4 seconds
        print("Number of interruptions: " + str(interrupts))
        initial = time.monotonic()

    if photoPin.value: # This sees if the photointerrupter is being interrupted
        lread = True # If it is interrupter, lread is true

    elif fread == lread: # if both the booleans are true, then the interrupts increases
        interrupts +=1
        lread = not lread


import  datetime
from subprocess import call

#datos del usuario
archivo1 = open("datos_usuario.txt","r")
datos = archivo1.readlines()
lista1 = []
for j in datos:
    fix = j.strip().split(":")
    lista1.append(fix)
print("\nDatos personales del usuario en forma lista: ",lista1)
#convertiendo a diccionario
diccionario = dict(lista1)
print("\nDatos personales del usuario en forma diccionario: ",diccionario)

#lista de compras
archivo2 = open("compras.txt","r")
boleta = archivo2.readlines()
lista2 = []
for i in boleta:
    arreglo = i.strip().split(":")
    lista2.append(arreglo)
print("\nLista de su boleta de compras de productos con su precio: ",lista2)

#hora del registro
tiempo = datetime.datetime.now()
#boleta
boleta = open("boleta.txt","w",encoding="utf8")
#titulo
boleta.write(("Boleta de Tu Opcion Saludable").center(60,"="))
#hora del registro
boleta.write(tiempo.strftime("\nFecha: %y-%m-%d \nHora: %H:%M\n"))
#datos en tipo diccionario
boleta.write("\nDatos del usuario: "+str(diccionario)+"\n")
#tabla de lista de canciones con format
boleta.write("\n"+"-"*50+"\n")
cont = 0
suma = 0
boleta.write("{2:>7}{0:^25}{2}{1:^15}{2}\n".format("PRODUCTO","IMPORTE","|"))
boleta.write("-"*50+"\n")
for j in lista2:
    cont += 1
    suma += float(j[1])
    boleta.write("{3}{0:^5}{3:<2}{1:<25}{3:<2}{2:>10,.2f}{3:>4}\n".format(cont,j[0],float(j[1]),"|"))
    boleta.write("-"*50+"\n")
boleta.write("{0:>19}{2:>15}{1:>10,.2f}\n".format("TOTAL",suma,"|"))
boleta.write("-"*50+"\n")

boleta.close()


import re
import json
pattern = re.compile("(http:\/\/www\.youtube\.com\/channel\/)[A-Za-z0-9_-]+")
id = 'M-TsGnRdj8vzI'
clean = set()
for i, line in enumerate(open(id)):
    for match in re.finditer(pattern, line):
        clean.add(match.group())
        #print (f'Found on line %s: %s' % (i+1, match.group()))

with open(id + "clean", "a") as ff:
            json.dump(list(clean), ff)


'''
This file contains all the objects in the game
'''
from random import choice as rand
import os
import menu
import game
import sys
#random NPC speak--------------------------------------------------------------------------------
quotes = ['Before the war, this nation was a peaceful place...', 'I like shorts. They are comfortable and easy to wear!',
'May you die with a sword in your hand.', 'I am weary of all of this fighting...', 'If these bastards want a war, we will give them one they will never forget!',
'I miss the peaceful days...', 'At this rate the nobles are going to tax the air we breathe...',
"Tavern's running a great deal on the house mead. It's sweet as honey yet filling as a night's supper.",
"I'm worried about the oncoming winter... The frost from last year destroyed most of our crops, and they say this year will be worse. What are we to do..."]
giftQuotes = ['It is dangerous to go alone. Here take this.', 'I found this on the ground earlier, I think you can make good use of it.',
'I found this earlier. It could be useful for combat, but I am tired of all the fighting so here, you can have it.',
'You will need this if you want to survive...', 'Take this...', "I got a new one of these, so you can have my old one.",
"Here, I have more of these than I know what to do with, take it.", "Listen, I don't want this thing but I don't want to just throw it away, you can have it.",
"I don't know what this thing is, you can have it."]
battleQuotes = ['Gimmie all your gold!', "When I'm through with you, you'll have more holes than a pincushion!",
"Hey! You're not supposed to be here!", 'You there! Spar with me!', "I'm going to send you to the depths of hell!",
"Say your prayers now, and God may accept you into heaven after I send you to his doorstep.", "Put the coin pouch on the ground and no one gets hurt!",
"How dare you enter our territory!", "The voices... I can't stop the voices...", "My sword will be sated by your blood!",
"GET OFF MY LAND!"]
bossQuotes = ["Lets get this over with, I have a date tonight.", "Uh when I crack open your head fruit what color juice comes out?",
"Do you know the definition of insanity...... me.", "There is only enough room for one of us in this world!",
"This is going to hurt!", "This is not your grave, but you are welcome to it.", "Pick a God and pray to it.",
"Your pathetic little adventure ends here, traveller!", "You have caught my attention traveller, but not my respect!",
"Where do you want to be buried?", "Don't you worry, I will make this quick!", "What fun is destruction if no 'precious' lives are lost?"]
finalBossQuotes = ["""I know who you are. You have caused me a lot of grief over the past few weeks. It is nice to finally put a face
to the one who has killed many of my loyal followers. The previous monarchy is dead, you need to let go of the past and join the new age.
Deep down you know I am not the villain! Why should a kingdom be passed along a 'royal' family instead of given to the smartest, strongest
people so it can thrive! The previous king saw this, which is why he never named an heir. The price for freedom is high, it always has been,
and not everyone has the guts to see that and act accordingly. I know you think what I am doing is wrong, but after
I am done ridding this kingdom of its weaknesses we will be stronger than ever. I gave you many chances to join me! I have had my
opportunities to take you out of the equation completely, but I wanted you to join me. You made a mistake coming here with your weapons drawn.
 You exist because I allowed it, and you will end because I demand it!"""]
questNPCQuotes = ["is causing everyone grief. Please take care of him!", "has caused me too many sleepless nights.",
"robbed me! Please help!", "stole my money, kill him!", "stole my goat, please get him back!", "is the one who took my chickens.",
"is a bad man!! He has a man hostage in the town square!", "can't be trusted...", "is trying to escape with our son!!",
"is sketchy, I think he has my coin sack.", "doesn't like dogs, he is not a man worth befriending.","will try to kill you.",
"knows who you are, be careful around him!", "is strange, there is something off about him.","has anger problems!"]
finalquestNPCQuotes = ["""I know who you are, and so do they! They know you are coming for them, so make sure that you are prepared when you
find the new ruler. I am not sure what you should expect, but I know they are very dangerous. I tried putting poison in the water, but got
caught doing so. I barely made it out alive. If they find me they will kill me!"""]
#random names------------------------------------------------------------------------------------
names = ["Saege", "Clafa", "Nathye", "Cuthfre", "Exard Salte", "Aelsith", "Ealwyn", "Waltin", "Breda", "Gyleon", "Sige",
"Gralphye", "Hearda", "Narder", "Conbern", "Ewis", "Folke Arrot", "Gerey", "Daedhug", "Richye Reyne", "Edmugh",
"Ealwanc", "Mesym Pyley", "Athyer Borne", "Ecgrert", "Aewan", "Berter Drove", "Lewis Mason", "Aldrer", "Ames", "George",
"Wine", "Iged", "Liamart", "Hughye Neray", "Edward Illiard", "Helhelmh", "Cyne", "Cirhelm", "Gerey Corby", "Michelle",
"Eril Pycey", "Ellel", "Burhe", "Eadwith", "Sida", "Frictiue", "Wenberg", "Arior", "Cilia Lyne", "Elen",
"Helia", "Waerburg", "Wynna", "Wychtlu", "Sunne", "Beatry Geddaye", "Cyna", "Burhe", "Eanswild", "Beornwe",
"Burgiue", "Ehith", "Hrichtra", "Efrin", "Evel", "Wigswe", "Cily Boley", "Gythiue", "Engen", "Thrakilm",
"Shari", "Orin", "Bari", "Gimli", "Dainarv", "Throri", "Arral", "Nanain", "Atur", "Gedu",
"Fari", "Frimah", "Gili", "Zigil", "Frainan", "Ziri", "Bali", "Khatelch", "Muli", "Zuri",
"Zaghim", "Orin", "Thori", "Thrazur", "Urur", "Grinarv", "Thainarv", "Gwali", "Grakun", "Thrinarv",
"Thundu", "Zigam", "Thrinan", "Roda", "Kilmin", "Khakurd", "Gamil", "Khundu", "Bifar", "Thori",
"Zigil", "Ukat", "Gabi", "Bori", "Grinain", "Kada", "Threri", "Udlat", "Dwali", "Muli",
"Kali", "Umras", "Ukad", "Umur", "Bori", "Kurdu", "Dwoinan", "Ugmaz", "Umund", "Finore",
"Finethald", "Gwionerdhil", "Quennore", "Guiladan", "Enelel", "Akin", "Elelmil", "Lodire", "Minerdhor", "Egnoror",
"Maeglomak", "Mionerdhor", "Saerodior", "Aldithin", "Finore", "Imin", "Annael", "Elenlon", "Dilador", "Emmilin",
"Elellan", "Dirohil", "Danore", "Oron", "Alaglor", "Finasaer", "Edramdil", "Ohin", "Inrod", "Minare",
"Saerethon", "Orodrel", "Eler", "Galmabli", "Elron", "Milebre", "Olfindin", "Olarfin", "Golioneth", "Elegos",
"Armil", "Enwendin", "Arfimin", "Finasaer", "Pengoneth", "Athin", "Mothere", "Dorahel", "Amras", "Gonarfin",
"Argophil", "Dirohilb", "Enlon", "Mothingon", "Enelmir", "Ennalgas", "Alan", "Celemmaedhr", "Golungilg", "Ilmimen",
"Nelalwe", "Findiser", "Celaser", "Ealoth", "Nelebrie", "Artanen", "Elwis", "Nimlothien", "Elelyel", "Serianye",
"Celaser", "Nimlaser", "Imel", "Niserie", "Elellas", "Enen", "Nelye", "Nelaser", "Findalye", "Irien",
"Adrierwel", "Alamas", "Celadrie", "Indellas", "Niserie", "Elyenwen", "Eldalwen", "Artaloth", "Arwel", "Elyelel",
"Elenwel", "Elenel", "Atiel", "Imis", "Ilatiel", "Galotie", "Eldas", "Nelladrie", "Arwedhel", "Helry",
"Brobert", "Maco", "Sonod", "Rime", "Gaffo", "Bando Burrubb", "Herog", "Wiso", "Hughye", "Mado",
"Ancold", "Fastob", "Arthur", "Haroc", "James Mylne", "Adoc", "Gery", "Bardo", "Hamso", "Manas",
"Raffolk Vere", "Imas", "Baldo", "Gyles Finchey", "Anthol", "Reder", "Warder Tine", "Fastob Took", "Haric", "Mentha",
"Mela", "Ryllia Owes", "Loba Chilly", "Joyce", "Phera", "Mina", "Hone", "Estel", "Suse", "Ennen",
"Kathon Parre", "Eryn", "Loba", "Aben Mylne", "Lavia Burrubb", "Sane Wake", "Audreyn Bowe", "Camay", "Ennel", "Wene",
"Lavy Tunnell", "Joane", "Druba", "Ilil", "Apphilda", "Mars", "Hone", "Mara Urron", "Elix", ]
townNames = ["Garen's Well", "Swadlincote", "Porthaethwy", "Queenstown", "Galssop", "Bredon", "Deathfall", "Aeston", "Whaelrdrake", "Newsham", "Northwich",
"Wolfwater", "Easthaven", "Farnfoss", "Hampstead", "Blackpool", "Bredon", "Pontybridge", "Carleone", "Woolhope", "Oldham",
"Doncaster", "Blencogo", "Goldcrest", "Caister", "Lingmell", "Tergaron", "Durnatel", "Chester", "Iyesgarth", "Braedon",
"Abingdon", "Bredwardine", "Marren's Eve", "Barkamsted", "Forstford", "Doonatel", "Furness", "Colchester", "Alverton", "Cleethorpes",
"Aquarin", "Coningsby", "Auchendale", "Fanfoss", "Blencathra", "Azmarin", "Aucteraden", "Westray", "Coniston", "Ship's Haven",
"Little Ivywood", "Anghor Wat", "Peatsland", "Bury", "Aethelney", "Arkmunster", "Bellmare", "Moonbright", "Aylesbury", "Padstow",
"Clare View Point", "Bromwich", "Blaenau", "Braedwardith", "Farnworth", "Thorpes", "Helmfirth", "Cromer", "Langdale", "Caerfyrddin",
"Pendle", "Barcombe", "Larton", "Alderdyfi", "City of Fire", "Whiteridge", "Holden", "Briar Glen", "Erith", "Snowmelt",
"Drumnacanvy", "Norbury", "Durmchapel", "Marclesfield", "Three Streams", "Daemarrel", "Norbury", "Colchester", "Glanchester", "Addersfield",
"Wakefield", "Hillfar", "Ramshorn", "Barncombe", "Old Ashton", "Lanercost", "Naporia", "Murlayfield", "Stratford", "Helmfirth",
"Black Hollow", "Far Water", "Swindlincote", "Farnfoss", "Lullin", "Paethsmouth", "Waekefield", "Ruthorham", "Lybster", "Middlesborough",
"Ecrin", "Alderrdeen", "Guthram", "Merton", "Watford", "Swordbreak", "Laenteglos", "Nantgarw", "Sudbury", "Torrine",
"Penshaw", "Haerndean", "Claethorpes", "Anghor Wat", "Begger's Hole", "Tenby", "Pantmawr", "Ilfracombe", "Doveport", "Broken Shield",
"Barnemouth", "Clacton", "Ffestiniog", "Glossop", "Bredon", "Lakeshore", "Penkurth", "Newham", "Berkton", "Panshaw",
"Runswick", "Saxondale", "Tow", "Narthwich", "Ula'ree", "Cewmann", "Astrakane", "Troutbeck", "Murrayfield", "Cromerth",
"Llaneybyder", "Porthcrawl", "Acton", "Garrigill", "Openshaw", "Aucteraden", "Clare View Point", "Solaris", "Tardide", "Graycott",
"Harthwaite", "Bardford", "Drumchapel", "Linemell", "Azmarin", "Matlock", "Harthwaite", "Rochdale", "Aylesbury", "Warrington",
"Elinmylly", "Pirn", "Airedale", "Brickelwhyte", "Hurtlepool", "Willowdale", "Paethsmouth", "Lakeshore", "Carran", "Hempholme",
"Beachmarsh", "Fallholt", "Dewsbury", "Worcester", "Palperroth", "Gillamoor", "Rochdale", "Little Ivywood", "Cesterfield", "Peatsland",
"Poltragow", "Kara's Vale", "Shepshed", "Skystead", "Deathfall", "Anghor Thom", "Sarton", "Aquarine", "Alverton", ]
#weapon names
weaponNames = ['Gauntlet','Dagger','Staff','Spear','Sword']
armourNames = ['Armour','Cloak','Robe','Chainmail','Plate']
charmNames = ['Gem','Fang','Ring','Pendant']
material = ['Infernalbrick', 'Volatile brick', 'Sweet velour', 'Somber hide', 'Demonic bone', 'Gloomy lead',
'Veilresin', 'Enigma linen', 'Stained lace', 'Ancient paper', 'Exuberant fiber', 'Mighty resin', 'Brainvelvet',
'Eternityresin', 'Fortune fleece', 'Marked lace', 'Tranquil tin', 'Long steel', 'Lunargold', 'Great hide', 'Solarresin',
'Dragonnickel', 'Cloudzinc', 'Glamorous fur', 'Exalted paper', 'Bright silver', 'Shady nickel', 'Nether sand', 'Scaletin',
'Omenweave', 'Grand nickel', 'Spell twill', 'Phantomnickel', 'Phasesatin', 'Feigned stone', 'Stark soil', 'Lucky brick',
'Aero resin', 'Depthglass', 'Aegis hide', 'Demonhide', 'Chain copper', 'Wicked lead', 'Odd cotton', 'Frosty knit',
'Infinite titanium', 'Pyrofleece', 'Solar paper', 'Craven twill', 'Bold wood', 'Putrid knit', 'Pitch cobalt',
'Wicked zinc', 'Lightmarble', 'Frost bone', 'Supreme steel', 'Utopian wood', 'Heavy copper', 'Grim fleece',
'Flawless sand', 'Arctic denim', 'Icebark', 'Halfcloth', 'Mild lead', 'Eternity copper', 'Exhausted gold',
'Glamorous lead', 'Corrupt skin', 'Planar lead', 'Moonsilver']
#player------------------------------------------------------------------------------------------
class player:
    def __init__(self, Class, weapon, armour, inventory):
        self.level = 1
        self.xp = 0
        self.xpDenominator = 75

        self.HP = 150
        self.maxHP = 150
        self.energy = 100

        self.strength = 10
        self.dexerity = 10
        self.inteligence = 10
        self.cleaverness = 10

        self.gold = 0
        self.weapon = weapon
        self.armour = armour
        self.charm = None

        self.inventory = inventory

        self.Class = Class

        self.town = None
        self.questLevel = 0

#classes------------------------------------------------------------------------------------------

class default:

    def __init__(self):
        self.thing = 'class'

        self.name = 'Default Class'

        self.HPUp = 10
        self.energyUp = 5
        self.strUp = 5
        self.dexUp = 5
        self.intelUp = 5
        self.clevUp = 5

        self.abilities = ['Punch Harder!','Knockout Blow']
        self.costs = [10,10]
        self.value = 50

    def ability1(self, userDict, enemyDict):
        print('Punched Harder!')

        userDict['fighter'].energy -= self.costs[0]

        userDict['cooldowns'][self.abilities[0]] = 4

        damage = int((userDict['fighter'].strength)*.75)

        return damage - enemyDict['defence']

    def ability2(self, userDict, enemyDict):
        print('Knockout Blow was used!')

        userDict['fighter'].energy -= self.costs[1]

        userDict['cooldowns'][self.abilities[1]] = 5

        if (rand(range(2))):
            enemyDict['status']['stun'] = 1
            print('The target is stunned!')
        else:
            print('Failed to Knockout')

        damage = (userDict['fighter'].strength)//3

        return damage - enemyDict['defence']

class warrior:

    def __init__(self):
        self.thing = 'class'

        self.name = 'Warrior Class'

        self.HPUp = 15
        self.energyUp = 2
        self.strUp = 8
        self.dexUp = 6
        self.intelUp = 1
        self.clevUp = 3

        self.abilities = ['Shield Bash','Stab Harder']
        self.costs = [15,15]
        self.value = 50

    def ability1(self, userDict, enemyDict):
        print('Shield Bash was used!')

        userDict['fighter'].energy -= self.costs[0]

        userDict['cooldowns'][self.abilities[0]] = 5

        enemyDict['status']['stun'] = 1
        print('The target is stunned!')

        damage = (userDict['fighter'].strength)//4

        return damage - enemyDict['defence']

    def ability2(self, userDict, enemyDict):
        print('Stabbed Harder!')

        userDict['fighter'].energy -= self.costs[1]

        userDict['cooldowns'][self.abilities[1]] = 5

        damage = (userDict['fighter'].strength)//2

        return damage - enemyDict['defence']

class mage:

    def __init__(self):
        self.thing = 'class'

        self.name = 'Mage Class'

        self.HPUp = 5
        self.energyUp = 15
        self.strUp = 1
        self.dexUp = 5
        self.intelUp = 10
        self.clevUp = 5

        self.abilities = ['Fireball','Freeze']
        self.costs = [20,40]
        self.value = 50

    def ability1(self, userDict, enemyDict):
        print('Fireball was used!')

        userDict['fighter'].energy -= self.costs[0]

        userDict['cooldowns'][self.abilities[0]] = 2

        enemyDict['status']['burn'] = 2
        print('The target is ablaze!')

        damage = int((userDict['fighter'].inteligence)*.5)

        return damage - enemyDict['defence']

    def ability2(self, userDict, enemyDict):
        print('Freeze was used!')

        userDict['fighter'].energy -= self.costs[1]

        userDict['cooldowns'][self.abilities[1]] = 5

        enemyDict['status']['stun'] = 2
        print('The target is frozen solid!')

        damage = int((userDict['fighter'].inteligence)*.6)

        return damage - enemyDict['defence']

class rogue:

    def __init__(self):
        self.thing = 'class'

        self.name = 'Rogue Class'

        self.HPUp = 10
        self.energyUp = 5
        self.strUp = 5
        self.dexUp = 10
        self.intelUp = 5
        self.clevUp = 5

        self.abilities = ['Crippling Poison','Vantage Strike']
        self.costs = [15,45]
        self.value = 50

    def ability1(self, userDict, enemyDict):
        print('Crippling Poison was used!')

        userDict['fighter'].energy -= self.costs[0]

        userDict['cooldowns'][self.abilities[0]] = 6

        enemyDict['status']['poison'] = 5
        print('The target is poisoned!')

        enemyDict['defence'] -= 1
        print("Target's defence lowered by 1!")

        damage = (userDict['fighter'].dexerity)//2

        return damage - enemyDict['defence']

    def ability2(self, userDict, enemyDict):
        print('Vantage Strike was used!')

        userDict['fighter'].energy -= self.costs[1]

        userDict['cooldowns'][self.abilities[1]] = 8

        bonus = int(0.1*(enemyDict['fighter'].maxHP - enemyDict['fighter'].HP))

        damage = (userDict['fighter'].dexerity) + bonus

        return damage - enemyDict['defence']

listOfNPCClasses = [default, warrior, mage, rogue]
#the world----------------------------------------------------------------------------------------
class world:
    def __init__(self, towns, start):
        self.towns = towns
        self.start = start

#towns--------------------------------------------------------------------------------------------
class townPrototype:

    def __init__(self, name, children, NPCs, Y, X, level):
        self.thing = 'town'

        self.name = name

        self.level = level

        self.y = Y
        self.x = X
        self.children = children
        self.parent = []
        self.left = None
        self.right = None
        self.exits = []

        self.NPCs = NPCs

    def finalize(self):
        if self.children:
            for t in self.children:
                self.exits.append(t)

        if self.parent:
            for t in self.parent:
                self.exits.append(t)

        if self.left:
            self.exits.append(self.left)

        if self.right:
            self.exits.append(self.right)

#NPCs---------------------------------------------------------------------------------------------
class NPCPrototype:

    def __init__(self, ntype, name):
        self.name = name

        self.thing = 'NPC'

        #One of 5 types
        self.type = ntype

    def initializeShop(self, items):
        self.text = 'Hello there! Please have a look at my fine wares.'
        self.inventory = items

    def initializeNone(self, text):
        self.text = text

    def initializeGift(self, text, item):
        self.text = text
        self.item = item

    def initializeBattle(self, stats, text):
        self.text = text

        #needs random weapon
        self.level = stats[0]
        self.xpReward = stats[1]
        self.goldReward = stats[2]
        self.HP = stats[3]
        self.maxHP = self.HP
        self.energy = stats[4]
        self.strength = stats[5]
        self.dexerity = stats[6]
        self.inteligence = stats[7]
        self.cleaverness = stats[8]
        self.Class = stats[9]
        self.weapon = stats[10]
        self.armour = stats[11]

    def interact(self, player, NPClist, index):
        os.system('cls' if os.name == 'nt' else 'clear')
        game.hud(player)
        print(self.text)

        if self.type == 'shop':
            while(True):
                os.system('cls' if os.name == 'nt' else 'clear')
                game.hud(player)
                print(self.text)

                for item in range(len(self.inventory)):
                    if self.inventory[item].thing == 'class':
                        print('(' +  str(item+1) + ')', self.inventory[item].name + '\033[0;33m' + ' (cost: ' + str(self.inventory[item].value) + ')' + '\033[0;m')
                    else:
                        print('(' +  str(item+1) + ')', self.inventory[item].name + ' - lvl: ' + str(self.inventory[item].level) + ' -' + '\033[0;33m' + ' (cost: ' + str(self.inventory[item].value) + ')' + '\033[0;m')
                print('(0) Back')

                choice = menu.safeInput( range(len(self.inventory)+1) )

                if choice == 0:
                    print('Thank you, come again!')
                    return
                else:
                    item = self.inventory[choice-1]

                    # displays an item, comparing it to the one the player is currently wearing
                    os.system('cls' if os.name == 'nt' else 'clear')
                    print(item.name)
                    print('Cost:', item.value)
                    if (item.thing != 'class'):
                        if (item.thing == 'weapon'):
                            print('Damage: %d (%d)' % (item.damage, item.damage - player.weapon.damage))
                            print('Strength: %d (%d)' % (item.strength, item.strength - player.weapon.strength))
                            print('Dexterity: %d (%d)' % (item.dexerity, item.dexerity - player.weapon.dexerity))
                            print('Intelligence: %d (%d)' % (item.inteligence, item.inteligence - player.weapon.inteligence))
                            print('Cleverness: %d (%d)' % (item.cleaverness, item.cleaverness - player.weapon.cleaverness))
                        if (item.thing == 'armour'):
                            print('Defence: %d (%d)' % (item.defence, item.defence - player.armour.defence))
                            print('Strength: %d (%d)' % (item.strength, item.strength - player.armour.strength))
                            print('Dexterity: %d (%d)' % (item.dexerity, item.dexerity - player.armour.dexerity))
                            print('Intelligence: %d (%d)' % (item.inteligence, item.inteligence - player.armour.inteligence))
                            print('Cleverness: %d (%d)' % (item.cleaverness, item.cleaverness - player.armour.cleaverness))
                        if (item.thing == 'charm'):
                            if player.charm:
                                print('Strength: %d (%d)' % (item.strength, item.strength - player.charm.strength))
                                print('Dexterity: %d (%d)' % (item.dexerity, item.dexerity - player.charm.dexerity))
                                print('Intelligence: %d (%d)' % (item.inteligence, item.inteligence - player.charm.inteligence))
                                print('Cleverness: %d (%d)' % (item.cleaverness, item.cleaverness - player.charm.cleaverness))
                            else:
                                print('Strength: %d (%d)' % (item.strength, item.strength))
                                print('Dexterity: %d (%d)' % (item.dexerity, item.dexerity))
                                print('Intelligence: %d (%d)' % (item.inteligence, item.inteligence))
                                print('Cleverness: %d (%d)' % (item.cleaverness, item.cleaverness))
                    print()
                    print('(1) Buy')
                    print('(0) Back')

                    # auto-equip option
                    choice = menu.safeInput(range(2))
                    if choice == 0:
                        pass
                    elif choice == 1 and player.gold >= item.value:
                        player.inventory.append(item)
                        player.gold -= item.value
                        print(item.name, 'was bought!')
                        input()
                        print()
                        print('Would you like to equip ' + item.name + '?')
                        print('(1) Equip')
                        print('(0) Back')

                        choice = menu.safeInput(range(2))
                        if choice == 0:
                            pass
                        elif choice == 1:
                            if item.thing == 'weapon':
                                player.weapon = item
                            elif item.thing == 'armour':
                                player.armour = item
                            elif item.thing == 'charm':
                                player.charm = item
                            elif item.thing == 'Class':
                                player.Class = item
                            print(item.name, 'equipped!')
                            input()
                        else:
                            print('You cannot afford this item!');
                            input()

        elif self.type == 'none':
            input()
            del NPClist[index]

        elif self.type == 'gift':
            player.inventory.append(self.item)
            print('You obtained', self.item.name+'!')
            input()
            del NPClist[index]

        elif self.type == 'battle':
            input()
            if game.battle(self, player):
                del NPClist[index]

    #define NPC abilities

class questNPC:
    def __init__(self, name, boss, bossName, text):
        self.name = name

        self.thing = 'NPC'

        self.type = 'quest'

        self.text = text

        #area boss you need to kill in order to advance
        self.quest = boss
        self.bossName = bossName

    def interact(self, player, NPClist, index):
        os.system('cls' if os.name == 'nt' else 'clear')
        game.hud(player)
        if self.quest.HP > 0:
            print(self.bossName + ' ' + self.text) #temp
        else:
            print('Thank you for killing ' + self.bossName + ', the world is a better place without them!') #temp
            player.questLevel += 1
            del NPClist[index]
            # would like to get rid of the hard-coded number here (mapSize - 1) - this is for mapSize = 7
            if self.quest.level >= 6:
                input("Press enter to continue: ")
                os.system('cls' if os.name == 'nt' else 'clear')
                sys.stdout.write("Congratulations! You have killed the ruler and will now be crowned as the new ruler of the kingdom. ")
                sys.stdout.write("Many saw the ruler as tyrranical, and others as progressive. ")
                sys.stdout.write("Everything comes at a cost, and only you can determine if it is worth paying for. \n\n\n\n\n")
                print("Thank you for playing corruption!")
                input("Press enter to continue: ")
                os.system('cls' if os.name == 'nt' else 'clear')
                print("You may continue exploring this world, however you have completed the main quest line.")
                input("Press enter to continue")

        input()

class bossNPC:
    def __init__(self, stats, name, text):
        #self.name = 'BOSS'
        self.name = name

        self.thing = 'NPC'

        self.type = 'battle'

        self.text = text

        self.level = stats[0]
        self.xpReward = stats[1]
        self.goldReward = stats[2]
        self.HP = stats[3]
        self.maxHP = self.HP
        self.energy = stats[4]
        self.strength = stats[5]
        self.dexerity = stats[6]
        self.inteligence = stats[7]
        self.cleaverness = stats[8]
        self.Class = stats[9]
        self.weapon = stats[10]
        self.armour = stats[11]

    def interact(self, player, NPClist, index):
        os.system('cls' if os.name == 'nt' else 'clear')
        game.hud(player)
        print(self.text)

        input()
        if game.battle(self, player):
            del NPClist[index]

#weapons------------------------------------------------------------------------------------------
class weaponPrototype:

    def __init__(self, name, thing, damage, strength, dexerity, inteligence, cleaverness, value, level):
        self.name = name

        self.thing = thing

        self.damage = damage

        self.strength = strength
        self.dexerity = dexerity
        self.inteligence = inteligence
        self.cleaverness = cleaverness

        self.value = value
        self.level = level

#armours------------------------------------------------------------------------------------------
class armourPrototype:

    def __init__(self, name, thing, defence, strength, dexerity, inteligence, cleaverness, value, level):
        self.name = name

        self.thing = thing

        self.defence = defence

        self.strength = strength
        self.dexerity = dexerity
        self.inteligence = inteligence
        self.cleaverness = cleaverness

        self.value = value
        self.level = level

#charms-------------------------------------------------------------------------------------------
class charmPrototype:

    def __init__(self, name, thing, strength, dexerity, inteligence, cleaverness, value, level):
        self.name = name

        self.thing = thing

        self.strength = strength
        self.dexerity = dexerity
        self.inteligence = inteligence
        self.cleaverness = cleaverness

        self.value = value
        self.level = level

#random generation functions----------------------------------------------------------------------
def randomItem(level, itype):
    choices = []
    if itype == 3:
        for i in listOfNPCClasses:
            choices.append(i)
        return rand(choices)()
    else:
        return proceduralItem(level, itype)

def proceduralItem(level, itype):

    statTotal = level*10
    numberOfStats = 5
    if itype == 2:
        numberOfStats = 4
    remainder = statTotal%numberOfStats
    upperBound = statTotal//numberOfStats+1

    stats = []
    for stat in range(numberOfStats):
        stats.append(rand(range(upperBound)))

    remainder += statTotal-sum(stats)

    stat1 = rand(range(numberOfStats))
    stat2 = rand(range(numberOfStats))

    subType = stat1

    stats[stat1] += (remainder//3)*2
    remainder -= (remainder//3)*2
    stats[stat2] += remainder

    if itype == 1:
        stats[4] = (stats[4]*level)-3
    elif itype == 0:
        stats[4] = int(stats[4]*1.25)+3

    if itype == 0:
        return weaponPrototype(rand(material)+' '+weaponNames[subType], 'weapon', stats[4], stats[0], stats[1], stats[2], stats[3], statTotal, level)
    elif itype == 1:
        return armourPrototype(rand(material)+' '+armourNames[subType], 'armour', stats[4], stats[0], stats[1], stats[2], stats[3], statTotal, level)
    else:
        return charmPrototype(rand(material)+' '+charmNames[subType], 'charm', stats[0], stats[1], stats[2], stats[3], statTotal, level)

#-------------------------------------------------------------------------------------------------


#采用lame命令，将wav文件转为MP3文件

import os
import subprocess

def traversePath(path):
    for dict , subDict , files in os.walk(path):
        for file in files:
            if str(file).endswith(".wav"):
                inputFile = os.path.join(dict , file)
                print(inputFile)
                #转换
                # wav2mp3(inputFile)
                #删除旧的wav文件
                os.remove(inputFile)

# wav2mp3
def wav2mp3(inputFile):
    name = str(inputFile).split('.')[0]
    cmd = ['lame','-h',inputFile,'%s.mp3' % name]
    subprocess.call(cmd)

if __name__ == "__main__":
    traversePath("/Users/WB/Desktop/上打Demo/originSourceMP3")


from src.shared_libs.guid import Guid
from src.shared_libs.TicTacToe.player import Player

class Board:
    def __init__(self):
        self.id = Guid()
        self.board = [[' ', ' ', ' '],
                      [' ', ' ', ' '],
                      [' ', ' ', ' ']]
        self.history = []
        self.winner = False
        self.draw = False
        self.play_count = 0
        self.remaining_moves = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        self.winning_states = [[(0, 0), (0, 1), (0, 2)],
                               [(0, 0), (1, 1), (2, 2)],
                               [(1, 0), (1, 1), (1, 2)],
                               [(2, 0), (2, 1), (2, 2)],
                               [(0, 0), (1, 0), (2, 0)],
                               [(0, 1), (1, 1), (2, 1)],
                               [(0, 2), (1, 2), (2, 2)],
                               [(2, 0), (1, 1), (0, 2)]]

    def __repr__(self):
        return f'<TicTacToe Board id="{self.id}">'

    def __str__(self):
        return '┌───┬───┬───┐\n' \
               '│ {0[0][0]} │ {0[0][1]} │ {0[0][2]} │\n' \
               '├───┼───┼───┤\n' \
               '│ {0[1][0]} │ {0[1][1]} │ {0[1][2]} │\n' \
               '├───┼───┼───┤\n' \
               '│ {0[2][0]} │ {0[2][1]} │ {0[2][2]} │\n' \
               '└───┴───┴───┘\n'.format(self.board)

    def make_play(self, player: Player, position: int):
        assert 1 <= position <= 9
        assert isinstance(player, Player)
        move = ((position - 1) // 3, (position - 1) % 3)
        if not self.board[move[0]][move[1]] == ' ':
            raise Warning("That cell is already taken. Please try again.")
        self.history.append(self.board)
        self.board[move[0]][move[1]] = player
        self.play_count += 1
        self.winner = self.check_winner()
        self.draw = self.check_draw()
        self.remaining_moves.remove(position)

    def check_winner(self):
        for state in self.winning_states:
            if (self.board[state[0][0]][state[0][1]] ==
                    self.board[state[1][0]][state[1][1]] ==
                    self.board[state[2][0]][state[2][1]]) and \
                    self.board[state[0][0]][state[0][1]] != ' ':
                return self.board[state[0][0]][state[0][1]]
        return False

    def check_draw(self):
        for row in self.board:
            for cell in row:
                if cell == ' ':
                    return False
        else:
            return True

    def clear(self):
        self.board = [[' ', ' ', ' '],
                      [' ', ' ', ' '],
                      [' ', ' ', ' ']]
        self.history = []
        self.winner = False
        self.play_count = 0


"""
1. Higher lower game: user given random data
-> def get_random_account(), def format_account(acc)
2. User guesses who has higher Instagram followers
-> def check_answer
3. Get 1 pt/correct guess, exit if wrong guess (show final score)
-> def game()
4. Each new guess, A becomes B, B gets assigned a new person. Clear screen after every round.
-> def clear
"""

import art
from game_data import data
import os
import random

# function to clear the console
def clear():
    os.system('cls' if os.name == 'nt' else 'clear')

def get_random_account():
    return random.choice(data)

def format_acc(acc):
    name = acc['name']
    description = acc['description']
    country = acc['country']
    return f"{name}, a {description}, from {country}"

def check_answer(user_guess, a_followers, b_followers):
    if a_followers > b_followers:
        return user_guess == 'a'
    else:
        return user_guess == 'b'

def game():
    print(art.logo)
    score = 0
    game_should_continue = True
    acc_a = get_random_account()
    acc_b = get_random_account()

    while game_should_continue:
        acc_a = acc_b
        acc_b = get_random_account()

        while acc_a == acc_b:
            acc_b = get_random_account()

        print(f"Compare A: {format_acc(acc_a)}.\n{art.versus}\nCompare B: {format_acc(acc_b)}.")
        user_guess = input("Who has more followers on Instagram? Type 'A' or 'B': ").lower()
        a_follow_ct = acc_a["follower_count"]
        b_follow_ct = acc_b["follower_count"]
        is_correct = check_answer(user_guess, a_follow_ct, b_follow_ct)

        clear()
        print(art.logo)
        if is_correct:
            score += 1
            print(f"You're right! Current scoal: {score}.")
        else:
            game_should_continue = False
            print(f"Sorry, you're wrong! Final score: {score}.")

game()


# -*- coding: utf-8 -*-
"""
Created on Tue Oct  1 21:45:55 2019

@author: ARAVIND A
"""

import numpy as np
import matplotlib.pyplot as plt

from scipy.ndimage import gaussian_filter
from skimage import data
from skimage import img_as_float
from skimage.morphology import reconstruction

# Convert to float: Important for subtraction else it won't work while using unsigned int
image = img_as_float(data.coins())
image = gaussian_filter(image, 1)

seed = np.copy(image)
seed[1:-1, 1:-1] = image.min()
mask = image
dilated = reconstruction(seed, mask, method='dilation')

#subtracting the original image from dilated image
fig, (ax0, ax1, ax2) = plt.subplots(nrows=1,
                                    ncols=3,
                                    figsize=(8, 2.5),
                                    sharex=True,
                                    sharey=True)

ax0.imshow(image, cmap='gray')
ax0.set_title('original image')
ax0.axis('off')

ax1.imshow(dilated, vmin=image.min(), vmax=image.max(), cmap='gray')
ax1.set_title('dilated')
ax1.axis('off')

ax2.imshow(image - dilated, cmap='gray')
ax2.set_title('image - dilated')
ax2.axis('off')

fig.tight_layout()

#reconstruction
h = 0.4
seed = image - h
dilated = reconstruction(seed, mask, method='dilation')
hdome = image - dilated

#plotting the process that I have mentioned above
fig, (ax0, ax1, ax2) = plt.subplots(nrows=1, ncols=3, figsize=(8, 2.5))
yslice = 197

ax0.plot(mask[yslice], '0.5', label='mask')
ax0.plot(seed[yslice], 'k', label='seed')
ax0.plot(dilated[yslice], 'r', label='dilated')
ax0.set_ylim(-0.2, 2)
ax0.set_title('image slice')
ax0.set_xticks([])
ax0.legend()

ax1.imshow(dilated, vmin=image.min(), vmax=image.max(), cmap='gray')
ax1.axhline(yslice, color='r', alpha=0.4)
ax1.set_title('dilated')
ax1.axis('off')

ax2.imshow(hdome, cmap='gray')
ax2.axhline(yslice, color='r', alpha=0.4)
ax2.set_title('image - dilated')
ax2.axis('off')

fig.tight_layout()
plt.show()


"""
Script que ejecuta el simulador.
"""

import sys
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import QApplication
from matplotlib import pyplot as plt
from MainWindow import MainWindow
from SenalesClasicas import SenalesClasicas
from SenalesNoConvencionales import SenalesNoConvencionales

#Parametros globales de la simulación
fSample = 3000
nTotalSimb = 10000

#Se obtienen las dimensiones de la pantalla
app = QApplication(sys.argv)
screen = app.primaryScreen()
size = screen.size()
rect = screen.availableGeometry()
sizeHeight = rect.height()
frameSizeWidth = int(rect.width()*0.85)
frameSizeHeight = int(rect.height()*0.85)
availableWidth = rect.width()
availableHeight = rect.height()

#Se inicializan las ventanas
widget = QtWidgets.QStackedWidget()
mainwindow = MainWindow(widget,availableWidth, availableHeight)
senalesClasicas = SenalesClasicas(widget, frameSizeWidth, frameSizeHeight, fSample, nTotalSimb, sizeHeight)
senalesNC = SenalesNoConvencionales(widget,frameSizeWidth, frameSizeHeight, fSample, nTotalSimb, sizeHeight)
plt.close('all')

nroSimb = senalesNC.cbNumSimb.currentText()
senalesNC.numeroSimbolos(nroSimb)

widget.show()
widget.setWindowState(QtCore.Qt.WindowMaximized)
widget.setWindowTitle("Simulador de Señales Digitales")

try:
    sys.exit(app.exec_())
except:
    print("Exiting")


import torch
import torch.nn.utils.prune
import numpy as np

def save_checkpoint(model, optimizer, checkpoint, epoch):
    """
    Save the model checkpoint along with the optimizer state and current epoch.

    Args:
        model (torch.nn.Module): The model to be saved.
        optimizer (torch.optim.Optimizer): The optimizer associated with the model.
        checkpoint (str): Path to save the checkpoint.
        epoch (int): Current epoch.

    """
    checkpoint_dict = {
        'epoch': epoch,
        'model_state_dict': model.state_dict(),
        'optimizer_state_dict': optimizer.state_dict()
    }
    torch.save(checkpoint_dict, checkpoint)

def load_checkpoint(model, optimizer, checkpoint, device):
    """
    Load the model checkpoint and optimizer state from the saved checkpoint file.

    Args:
        model (torch.nn.Module): The model to load the state into.
        optimizer (torch.optim.Optimizer): The optimizer to load the state into.
        checkpoint (str): Path to the checkpoint file.

    Returns:
        Tuple[torch.nn.Module, torch.optim.Optimizer, int]: The loaded model, optimizer, and the epoch from which to resume training.

    """
    checkpoint = torch.load(checkpoint, map_location=device)
    model.load_state_dict(checkpoint['model_state_dict'])
    optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
    epoch = checkpoint['epoch']
    return model, optimizer, epoch

def reduce_model_size(model, amount):
    """
    Reduce the size of the model by applying pruning techniques to its parameters.
    Here, we use torch.nn.utils.prune module to prune the model

    Args:
        model (torch.nn.Module): The model to be pruned.
        amount (float): The amount of pruning to be applied.

    Returns:
        torch.nn.Module: The pruned model.

    """

    for module in model.modules():
        if isinstance(module, torch.nn.Conv2d) or isinstance(module, torch.nn.Linear):
            torch.nn.utils.prune.l1_unstructured(module, name='weight', amount=amount)

    return model

def get_model_size(model):
    """
    Calculate the total number of trainable parameters in the model.

    Args:
        model (torch.nn.Module): The model to calculate the size.

    Returns:
        int: Total number of trainable parameters in the model.

    """
    return sum(p.numel() for p in model.parameters() if p.requires_grad)