# Emoji library (for demojization)
import emoji
emojis = list(emoji.EMOJI_DATA.keys())

# Language Detection
import spacy
import spacy_fastlang # is used
from spacy_langdetect import LanguageDetector

# Stopwords to remove
from nltk.corpus import stopwords as sw

import string
import copy
import nltk
import re

class text_cleaner:
    def __init__(self):
        pass

    def __handle_emojis(lst):
        res = []
        for sentence in lst:
            words = sentence.split(' ')
            new_words = []
            for word in words:
                for char in word:
                    if char in emojis:
                        word.replace(char, "")
                new_words.append(word)
            sentence = ' '.join(new_words)
            res.append(sentence)
        return res

    def __clean_sentences(lst):
        ''' Cleans up a list of tweets.
        Removes: Links, tags, retweets, emojis'''

        res = []
        stopwords = sw.words('English')
        stopwords.remove('not')

        for sentence in lst:
            sentence = sentence.lower()     # lower-cases sentence

            words = sentence.split(' ')
            new_words = copy.deepcopy(words)

            for word in words: # Iterates through each word in the tweet
                if len(word) == 0:
                    new_words.remove(word)
                elif word[:4] == "http":    # Removes links
                    new_words.remove(word)
                elif word[0] == "@":        # Removes tags
                    new_words.remove(word)
                elif word in stopwords:     # Removes stopwords
                    new_words.remove(word)
                elif word[:2] == "rt":      # Removes retweets
                    new_words.remove(word)
                elif word[:2] == "\n":      # Removes line breaks
                    new_words.remove(word)

            sentence = " ".join(new_words)
            # sentence = re.sub(string.punctuation, '', sentence) # Removes punctuation
            for chr in string.punctuation:
                sentence = sentence.replace(chr, "")

            res.append(sentence)
        return res

    def __clean_words(lst):
        ''' Removes: empty spaces'''
        res = []
        for sentence in lst:
            words = sentence.split(' ')
            new_words = []

            for word in words:
                for char in word: # iterates through each character in the tweet
                    if char == " ":
                        word.replace(char, "")
                new_words.append(word)

            sentence = " ".join(new_words)
            res.append(sentence)
        return res

    def remove_non_english(lst):
        ''' Removes all content that is NOT english from a list of tweets'''
        langs = []
        res = copy.deepcopy(lst)

        nlp = spacy.load("en_core_web_sm")
        nlp.add_pipe("language_detector")

        for item in lst: # iterates through each sentence
            doc = nlp(item)
            lang = doc._.language
            if lang != 'en':
                res.remove(item)        # removes non-english sentences
            langs.append(lang)
        # lang_labels['language'] = langs # secondary side-effect
        return res

    def __stem(lst):
        '''Stems words to use basic stem word (e.g turn instead of turning)'''
        ps = nltk.stem.PorterStemmer()
        res = []
        for sentence in lst:
            new_sentence = []
            for word in sentence.split():
                new_word = ps.stem(word)
                new_sentence.append(new_word)
            new_sentence = " ".join(new_sentence)
            res.append(new_sentence)
        return res

    def clean(df):
        ''' Static method to do cleaning'''

        df = text_cleaner.__handle_emojis(df)
        df = text_cleaner.__clean_sentences(df)
        # df = text_cleaner.remove_non_english(df)
        df = text_cleaner.__stem(df)
        return df


from argparse import ArgumentParser
import torch
import torch.nn as nn
from datahandler.data_loader import btvDataLoader
import logging
from tools import LOGFILE_LEVEL, CONSOLE_LEVEL
from tools import OPTIONS, optionStruct

def build_config():
    parser = ArgumentParser()
    parser.add_argument("--mode", dest="mode", metavar="MODE", default="train",
                        help="Choose Mode : train, evaluate, generate")
    parser.add_argument("--movie_path", dest="movie_path", default='data/NEW_MOVIES.csv')
    parser.add_argument("--view_path", dest="view_path", default='data/SKB_DLP_VIEWS.csv')
    parser.add_argument("--question_path", dest="question_path", default='data/SKB_DLP_QUESTION.csv')
    parser.add_argument("--batch_size", dest="batch_size", default="32")
    parser.add_argument("--window_size", dest="window_size", default="10")
    parser.add_argument("--device", dest="device", default="gpu")
    parser.add_argument("--test_portion", dest="test_portion", default="0.05")
    parser.add_argument("--model", dest="model", default="SeqModel3")
    parser.add_argument("--hidden_size", dest="hidden_size", default=256)
    parser.add_argument("--word_vec_dim", dest="word_vec_dim", default=256)
    parser.add_argument("--lr", dest="lr", default=1.0)
    parser.add_argument("--n_epochs", dest="n_epochs", default=18)
    parser.add_argument("--early_stop", dest="early_stop", default=-1)
    parser.add_argument("--target", dest="target", default="target")

    config = parser.parse_args()
    return config

if __name__ == '__main__':
    config = build_config()

    ## gpu사용할 것인지 cpu사용할 것인지 확인.
    config.device = torch.device("cuda" if torch.cuda.is_available() and (config.device == 'gpu' or config.device == 'cuda') else "cpu")

    def _print_config(config):
        import pprint
        pp = pprint.PrettyPrinter(indent=4)
        pp.pprint(vars(config))
    _print_config(config)

    if not logging.getLogger() == None:
        for handler in logging.getLogger().handlers[:]:  # make a copy of the list
            logging.getLogger().removeHandler(handler)

    logging.basicConfig(filename='train_log', level=LOGFILE_LEVEL)  # logging의 config 변경
    console = logging.StreamHandler()  # logging을 콘솔화면에 출력
    console.setLevel(CONSOLE_LEVEL)  # log level 설정
    logging.getLogger().addHandler(console)  # logger 인스턴스에 콘솔창의 결과를 핸들러에 추가한다.

    options = optionStruct(**OPTIONS)

    # Load training and validation data set.
    loader = btvDataLoader(movie_path=config.movie_path,
                           view_path=config.view_path,
                           question_path=config.question_path,
                           batch_size=config.batch_size,
                           window_size=config.window_size,
                           device=config.device,
                           test_portion=config.test_portion,
                           options = options
                           )
    train, valid = loader.load_train_data()

    options.set_movie_size(loader.get_movie_size())
    options.set_nation_size(loader.get_nation_size())
    options.set_genre_size(loader.get_genre_size())

    if config.model == 'SeqModel':
        from model.model import SeqModel
        from trainer import Trainer

        model = SeqModel(
            input_size=options.get_input_size(),
            hidden_size=config.hidden_size,
            output_size=options.get_movie_size(),
            n_layers=4,
            device=config.device
        ).to(config.device)

        crits = nn.NLLLoss()
        trainer = Trainer(model, crits, config, options)
    elif config.model == 'SeqModel3':
        from model.model import SeqModel3
        from trainer.sequence_trainer import seq_Trainer
        model = SeqModel3(
            input_size=options.get_movie_size(),
            word_vec_dim=config.word_vec_dim,
            hidden_size=config.hidden_size,
            output_size=options.get_movie_size(),
            device='cpu'
        ).to(config.device)

        crits = nn.NLLLoss()
        trainer = seq_Trainer(model, crits, config, options)

    trainer.train(train, valid)


import os
import json

cwd = os.path.dirname(os.path.realpath(__file__))

entity_to_type_map = {}
type_to_entity_map = {}

mapped_schemas = {
    "IFC2X3": "entity_to_type_map_2x3.json",
    "IFC4": "entity_to_type_map_4.json",
    "IFC4X3": "entity_to_type_map_4x3.json",
}
for schema in mapped_schemas:
    # load entity maps from json
    schema_path = os.path.join(cwd, mapped_schemas[schema])
    with open(schema_path) as f:
        entity_to_type_map[schema] = json.load(f)

    # create type_to_entity map
    type_to_entity_map[schema] = {}
    for element, element_types in entity_to_type_map[schema].items():
        for element_type in element_types:
            type_to_entity_map[schema].setdefault(element_type, []).append(element)

    if schema == "IFC2X3":
        # There is no official mapping for IFC2X3 but this method gets us something that looks correct
        for element_type, elements in type_to_entity_map[schema].items():
            # need to take both Type (4 symbols) and Style (5 symbols) into account
            guessed_element = element_type[:-5] if element_type.endswith("Style") else element_type[:-4]
            if guessed_element in elements:
                type_to_entity_map[schema][element_type] = [e for e in elements if guessed_element in e]

def get_applicable_types(ifc_class, schema="IFC4"):
    return entity_to_type_map[schema.upper()].get(ifc_class, [])

def get_applicable_entities(ifc_type_class, schema="IFC4"):
    return type_to_entity_map[schema.upper()].get(ifc_type_class, [])


# Baekjoon_7569 토마토

# Solution by wYuYw

from collections import deque
import sys
input = lambda: sys.stdin.readline().strip()

def bfs():
    while q:
        z, r, c = q.popleft()
        for i in range(6):
            nr, nc, nz = r + dr[i], c + dc[i], z + dz[i]
            if 0 <= nr < n and 0 <= nc < m and 0 <= nz < h and graph[nz][nr][nc] == 0:
                graph[nz][nr][nc] = graph[z][r][c] + 1
                q.append((nz, nr, nc))

m, n, h = map(int, input().split())
graph = [[list(map(int, input().split())) for _ in range(n)] for _ in range(h)]
q = deque()
for z in range(h):
    for r in range(n):
        for c in range(m):
            if graph[z][r][c] == 1:
                q.append((z, r, c))

# up, right, down, left, top, bottom
dr, dc, dz = [-1, 0, 1, 0, 0, 0], [0, 1, 0, -1, 0, 0], [0, 0, 0, 0, -1, 1]
flag = True
res = -1
bfs()

for i in graph:
    for j in i:
        for k in j:
            if k == 0:
                flag = False
            res = max(res, k)

if not flag: # not finished
    print(-1)
elif res == 1: # already finished
    print(0)
else:
    print(res - 1)


class Solution:
    def reverseVowels(self, s):
        """
        :type s: str
        :rtype: str
        """
        vowels = set(['a', 'u', 'e', 'i', 'o', 'A', 'U', 'E', 'I', 'O'])
        p = [i for i in s if i in vowels]
        return ''.join([i if i not in vowels else p.pop() for i in s])

if __name__ == "__main__":
    s = "hello"
    print(Solution().reverseVowels(s))


import sys
from collections import defaultdict
from unittest import TestCase
from hamcrest import assert_that, equal_to

from lazytest.helpers import MockTofSensor, MockBuzzer, MockLed
from lazydoro.pi.lazy_oo import Clock, Schedule, PomodoroTimer, Display

DURATION = 10
BREAK = 5
GRACE = 2
TIMEOUT = 3

class MockClock(Clock):
    def __init__(self, limit=31*60):
        Clock.__init__(self)
        self.limit = limit
        self.last_event_at = 0
        self.assertions = defaultdict(list)
        self.descriptions = {}
        self._failures = False
        self._running = True

    def tick(self):
        Clock.tick(self)
        if self._ticks in self.assertions:
            for assertion in self.assertions[self._ticks]:
                try:
                    assertion() # run the relevant function
                except Exception as e:
                    print('at time %d assertion %s failed' % (self.ticks(), self.descriptions[self._ticks]), file=sys.stderr)
                    self._failures = True
                    continue
            print(self.ticks(), self.descriptions[self._ticks], 'OK')

    def running(self):
        return self.ticks() <= self.limit and self._running

    def after(self, seconds: int, description: str, *fns):
        next_event_at = (seconds * self.TICKS_PER_SECOND) + self.last_event_at
        self.assertions[next_event_at]+=fns
        self.descriptions[next_event_at] = description
        self.last_event_at = next_event_at

    def check(self):
        if self._failures:
            raise Exception('tests failed')

    def stop(self):
        self._running = False

class LazydoroTest(TestCase):
    def setUp(self):
        self.tof_sensor = MockTofSensor()
        self.buzzer = MockBuzzer()
        self.led = MockLed()
        schedule = Schedule(DURATION, BREAK, GRACE, TIMEOUT)
        self.clock = MockClock()
        self.pom = PomodoroTimer(self.clock, self.tof_sensor, self.buzzer, self.led, schedule)

    def test_can_run_a_single_pomodoro(self):
        self.after(1, 'initial state', self.buzzer_is_quiet, self.led_is_blue)
        self.after(1, 'I sit down', self.person_comes)
        self.after(1, 'Pomodoro timer has started', self.buzzer_is_quiet, self.led_is_green)
        self.after(DURATION-1, 'still running', self.buzzer_is_quiet, self.led_is_green)
        self.after(1, 'timer has completed', self.buzzer_is_buzzing, self.led_is_red)
        self.after(1, 'I get up for a break', self.person_leaves)
        self.after(1, 'starting a break', self.buzzer_is_quiet, self.led_is_yellow)
        self.after(BREAK-3, 'still on a break', self.buzzer_is_quiet, self.led_is_yellow)
        self.after(3, 'break timer has completed', self.buzzer_is_buzzing, self.led_is_red)
        self.after(1, 'I sit down again', self.person_comes)
        self.after(3, 'next Pomodoro starts', self.led_is_green)
        self.after(1, 'stopping', self.stop)
        self.pom.run()
        self.clock.check()

    def test_pomodoro_stops_if_I_get_up_early(self):
        self.after(1, 'initial state', self.buzzer_is_quiet, self.led_is_blue)
        self.after(1, 'I sit down at my desk', self.person_comes)
        self.after(1, 'Pomodoro timer has started', self.led_is_green)
        self.after(DURATION-5, 'still running', self.buzzer_is_quiet, self.led_is_green)
        self.after(1,'I get up early',  self.person_leaves)
        self.after(3, 'waiting', self.buzzer_is_quiet, self.led_is_blue)
        self.after(1, 'stopping', self.stop)
        self.pom.run()
        self.clock.stop()
        self.clock.check()

    def after(self, time: int, *fns):
        self.clock.after(time, *fns)

    def buzzer_is_quiet(self):
        assert_that(not self.buzzer.buzzing,'buzzer is buzzing but should be quiet')

    def buzzer_is_buzzing(self):
        assert_that(self.buzzer.buzzing,'buzzer is quiet but should be buzzing')

    def led_is_blue(self):
        assert_that(self.led.color(), equal_to(Display.BLUE))

    def led_is_red(self):
        assert_that(self.led.color(), equal_to(Display.RED))

    def led_is_green(self):
        assert_that(self.led.color(), equal_to(Display.GREEN))

    def led_is_yellow(self):
        assert_that(self.led.color(), equal_to(Display.YELLOW))

    def person_comes(self):
        self.tof_sensor.person_comes()

    def person_leaves(self):
        self.tof_sensor.person_leaves()

    def stop(self):
        self.clock.stop()


import os
from re import A
import time
import subprocess

# running terminal command in python
# stream = os.popen('ls -l')
# output = stream.read()
# print(output)

# os.system('rcssserver3d')
# time.sleep(5)
# print("stopping")
# os.system('^C')

def run_server():
    subproces = subprocess.Popen(['gnome-terminal', '-e', 'rcssserver3d'], stdout=subprocess.PIPE)
    output, error = subproces.communicate()
    time.sleep(2)
    subproces.terminate()
    # print(output)
    return output

def kill_server(output):
    target_process = "python"
    for line in output.splitlines():
        if target_process in str(line):
            pid = int(line.split(None, 1)[0])
            print(pid)
            os.kill(pid, 9)

a = run_server()
print(a)
time.sleep(4)
kill_server(a)
# os.system("gnome-terminal -e 'rcssserver3d'")
# time.sleep(3)
# os.system("gnome-terminal -e '^C'")
# os.system("gnome-terminal -e 'exit'")


import os
from asyncio import run

from ipv8.community import Community
from ipv8.configuration import ConfigBuilder, Strategy, WalkerDefinition, default_bootstrap_defs
from ipv8.peerdiscovery.network import PeerObserver
from ipv8.types import Peer
from ipv8.util import run_forever
from ipv8_service import IPv8

class MyCommunity(Community, PeerObserver):
    community_id = os.urandom(20)

    def on_peer_added(self, peer: Peer) -> None:
        print("I am:", self.my_peer, "I found:", peer)

    def on_peer_removed(self, peer: Peer) -> None:
        pass

    def started(self) -> None:
        self.network.add_peer_observer(self)

async def start_communities() -> None:
    for i in [1, 2]:
        builder = ConfigBuilder().clear_keys().clear_overlays()
        builder.add_key("my peer", "medium", f"ec{i}.pem")
        # We provide the 'started' function to the 'on_start'.
        # We will call the overlay's 'started' function without any
        # arguments once IPv8 is initialized.
        builder.add_overlay("MyCommunity", "my peer",
                            [WalkerDefinition(Strategy.RandomWalk,
                                              10, {'timeout': 3.0})],
                            default_bootstrap_defs, {}, [('started',)])
        await IPv8(builder.finalize(),
                   extra_communities={'MyCommunity': MyCommunity}).start()
    await run_forever()

run(start_communities())


"""
A counter is really important to keep track of the domain and the subdomains. Using that, I can easily append
the number of counts.
"""

from collections import Counter

class Solution:
    def subdomainVisits(self, cpdomains: List[str]) -> List[str]:
        def get_subdomains(domain):
            subdomains = []

            components = domain.split('.')
            count = 0
            for i in range(len(components)):
                string = ""
                for j in range(count, len(components)):
                    string += components[j]
                    string += "."
                string = string.rstrip(".")
                subdomains.append(string)
                count += 1

            return subdomains

        subdomain_count = Counter()
        for cpdomain in cpdomains:
            [count, domain] = cpdomain.split(" ")
            subdomains = get_subdomains(domain)

            for subdomain in subdomains:
                subdomain_count.update({subdomain: int(count)})

        res = []
        for key in subdomain_count.keys():
            res.append(str(subdomain_count[key]) + " " + key)

        return res


from django.urls import path
from . import views
urlpatterns = [
    path('admindash/', views.admindash, name="admindash"),
    path('datatables/', views.datatables, name="datatables"),

    path('addcategory/', views.addcategory, name="addcategory"),
    path('updatecategory/<int:id>/', views.updatecategory, name="updatecategory"),
    path('deletecategory/<int:id>/', views.deletecategory, name="deletecategory"),

    path('addsubcategory/', views.addsubcategory, name="addsubcategory"),
    path('updatesubcategory/<int:id>/',views.updatesubcategory, name="updatesubcategory"),
    path('deletesubcategory/<int:id>/',
         views.deletesubcategory, name="deletesubcategory"),

    path('addarticle/', views.addarticle, name="addarticle"),
    path('updatearticle/<int:id>/<str:path>/', views.updatearticle, name="updatearticle"),
    path('deletearticle/<int:id>/',
         views.deletearticle, name="deletearticle"),

    path('category/', views.category, name="category"),
    path('subcategory/', views.subcategory, name="subcategory"),
    path('article/', views.article, name="article"),
    path('usersettings', views.usersettings, name="usersettings"),
]


"This module is used as a database for KoL quest information."

import kol.Error as Error
from kol.data import Quests
from kol.manager import FilterManager
from kol.util import Report

__isInitialized = False
__questsByName = {}
__councilQuestsByLevel = {}

def init():
    """
    Initializes the QkillDatabase. This method should be called before the
    database is ever accessed as it ensures that the database is populated
    with all of the data it needs.
    """
    global __isInitialized
    if __isInitialized == True:
        return

    Report.trace("questdatabase", "Initializing the quest database.")
    returnCode = FilterManager.executeFiltersForEvent("preInitializeQuestDatabase")
    if returnCode == FilterManager.FINISHED:
        Report.trace("questdatabase", "Quest database initialized.")
        __isInitialized = True
        return

    for quest in Quests.quests:
        addQuest(quest)

    FilterManager.executeFiltersForEvent("postInitializeQuestDatabase")
    __isInitialized = True
    Report.trace("questdatabase", "Quest database initialized.")

"Adds a quest to the database."
def addQuest(quest):
    __questsByName[quest["name"]] = quest
    if quest["source"] == "Council":
        __councilQuestsByLevel[quest["levelAvailable"]] = quest

"Returns information about a quest given its name."
def getQuestFromName(questName, session=None):
    if not __isInitialized:
        init()

    try:
        return __questsByName[questName].copy()
    except KeyError:
        cxt = {}
        FilterManager.executeFiltersForEvent("couldNotFindQuest", cxt, session=session, questName=questName)
        if "quest" in cxt:
            quest = cxt["quest"]
            addQuest(quest)
            return quest.copy()
        raise Error.Error("The quest '%s' is unknown." % questName, Error.QUEST_NOT_FOUND)

def getCouncilQuestFromLevel(questLevel, session=None):
    "Returns information about a quest given its name."
    if not __isInitialized:
        init()

    #print "quest map: " + str(__councilQuestsByLevel)

    try:
        return __councilQuestsByLevel[questLevel].copy()
    except KeyError:
        cxt = {}
        FilterManager.executeFiltersForEvent("couldNotFindQuest", cxt, session=session, questLevel=questLevel)
        if "quest" in cxt:
            quest = cxt["quest"]
            addQuest(quest)
            return quest.copy()
        raise Error.Error("The guild quest for level '%s' is unknown." % questLevel, Error.QUEST_NOT_FOUND)


import re
import os
import time
import nltk
import json
import pandas as pd
import pandas as pd
from tqdm import tqdm
from rouge import Rouge
from typing import List
from spacy.lang.en import English
from haystack import Document
from haystack.reader import TransformersReader
from haystack.pipeline import ExtractiveQAPipeline
from haystack.retriever.dense import DensePassageRetriever
from haystack.document_store.faiss import FAISSDocumentStore
from nltk.translate.bleu_score import sentence_bleu, SmoothingFunction

nlp = English()
nlp.add_pipe("sentencizer")

class report_generator():
    def __init__(self,
                 retriever_top_ks: list,
                 reader_top_ks: list,
                 embed_titles: list,
                 reader_models: list,
                 context_window_sizes: list,
                 text_datasets: list,
                 qa_datasets: list,
                 max_seq_len_passages: list,
                 max_seq_len_queries: list,
                 doc_strides: list,
                 max_seq_lens: list,
                 report_out_dir: str,
                 sample_out_dir: str):

        self.retriever_top_ks = retriever_top_ks
        self.reader_top_ks = reader_top_ks
        self.embed_titles = embed_titles
        self.doc_strides = doc_strides
        self.reader_models = reader_models
        self.context_window_sizes = context_window_sizes
        self.text_datasets = text_datasets
        self.qa_datasets = qa_datasets
        self.max_seq_len_passages = max_seq_len_passages
        self.max_seq_len_queries = max_seq_len_queries
        self.max_seq_lens = max_seq_lens
        self.report_out_dir = report_out_dir
        self.sample_out_dir = sample_out_dir
        self.columns = ['QA model', 'Dataset', 'embed_title', 'context_window_size',
                        'max_seq_len', 'doc_stride', 'max_seq_len_passage', 'max_seq_len_query',
                        'Retriever top-k', 'QA top-k', 'Rouge-1',
                        'Rouge-2', 'Rouge-l', 'Bleu',
                        'Answers percent in retrieved documents', 'VRAM',
                        'document embedding time', 'inference time'
                        ]

    def __load_dataset(self, qa_dataset, text_dataset):
        with open(qa_dataset, "r") as f:
            self.qa = json.loads(f.read())['data']
            df = pd.read_csv(text_dataset, index_col=0)
            df = df.reset_index()

        titles = list(df["title"].values)
        texts = list(df["text"].values)
        self.documents: List[Document] = []

        for title, text in zip(titles, texts):
            self.documents.append(
                Document(
                    text=text,
                    meta={
                        "name": title or ""
                    }
                )
            )

    def __init_doc_store(self, similarity="dot_product"):
        self.document_store = FAISSDocumentStore(similarity=similarity,
                                                 faiss_index_factory_str="Flat",
                                                 return_embedding=True
                                                 )

    def __init_retriever(self, embed_title,
                         query_embedding_model="facebook/dpr-question_encoder-single-nq-base",
                         passage_embedding_model="facebook/dpr-ctx_encoder-single-nq-base"):

        self.retriever = DensePassageRetriever(document_store=self.document_store,
                                               query_embedding_model=query_embedding_model,
                                               passage_embedding_model=passage_embedding_model,
                                               use_gpu=True,
                                               embed_title=embed_title
                                               )

    def __update_embedding(self):
        self.document_store.delete_documents()
        self.document_store.write_documents(self.documents)
        self.document_store.update_embeddings(
            retriever=self.retriever
        )

    def __init_reader(self, model_name, window_size, seq_len, stride):
        self.reader = TransformersReader(model_name_or_path=model_name,
                                         context_window_size=window_size,
                                         max_seq_len=seq_len,
                                         doc_stride=stride,
                                         use_gpu=0
                                         )

    def __compute_metrics(self, reader, retriever, qa, retriever_top_k, reader_top_k):
        bleu_scores = []
        rouge1_scores = []
        rouge2_scores = []
        rougel_scores = []
        context_accuracy = []

        rouge = Rouge()
        smoothie = SmoothingFunction().method4

        for data in tqdm(qa):
            true_context = data['paragraphs'][0]['context']
            # true_context = true_context.replace('\n', ' ')

            for q_a in data['paragraphs'][0]['qas']:
                question = q_a['question']
                reference_list = set([answer['text']
                                     for answer in q_a['answers']])

                reference_list = set([entry_j for i, entry_i in enumerate(
                    reference_list) for entry_j in reference_list if entry_i in entry_j])

                reference = " ".join(reference_list)
                reference_sents = nlp(reference)
                reference_sents = list(reference_sents.sents)
                reference_sents = [sent.text.lstrip().rstrip()
                                   for sent in reference_sents]

                pipe = ExtractiveQAPipeline(reader, retriever)

                preds = pipe.run(
                    query=question,
                    params={"Retriever": {"top_k": retriever_top_k},
                            "Reader": {"top_k": reader_top_k}}
                )

                candidate_sent_list = []

                for pred in preds['answers']:
                    pred_answer = pred['answer']

                    if pred_answer is not None:
                        offset_start = pred['offset_start']
                        offset_end = pred['offset_end']
                        meta_name = pred['meta']['vector_id']

                        pred_all_context_sents = []

                        for pred in preds['documents']:
                            pred_all_context_sents += list(
                                nlp(pred.to_dict()['text']).sents)

                            if pred.to_dict()['meta']['vector_id'] == meta_name:
                                pred_context = pred.to_dict()['text']
                                pred_context_sents = nlp(pred_context)
                                pred_context_sents = list(
                                    pred_context_sents.sents)
                                pred_context_sents = [
                                    sent.text for sent in pred_context_sents]
                                # pred_context = " ".join(pred_context_sents)

                        pred_all_context_sents = [
                            re.sub(r'\n+', ' ', sent.text).strip() for sent in pred_all_context_sents]

                        doc = nlp(pred_answer)
                        pred_answer_sents = list(doc.sents)
                        pred_answer_sents = [
                            sent.text for sent in pred_answer_sents]

                        for pred_context_sent in pred_context_sents:
                            start_index = 0
                            end_index = len(pred_answer)

                            for pred_answer_sent in pred_answer_sents:
                                right_reduction = len(
                                    pred_answer_sent) - len(pred_answer_sent.rstrip())
                                left_reduction = len(
                                    pred_answer_sent) - len(pred_answer_sent.lstrip())
                                end_index -= len(pred_answer_sent) + \
                                    0 if pred_context_sents[-1] == pred_answer_sent else 1

                                context_offset_start = pred_context.find(
                                    pred_context_sent)
                                context_offset_end = pred_context.find(
                                    pred_context_sent) + len(pred_context_sent)

                                if context_offset_start - left_reduction <= offset_start + start_index and context_offset_end + right_reduction >= offset_end - end_index:
                                    candidate_sent_list.append(
                                        pred_context_sent)

                                start_index += len(pred_answer_sent) + \
                                    0 if pred_context_sents[-1] == pred_answer_sent else 1

                        for reference_sent in reference_sents:
                            context_truth = 0

                            if reference_sent in pred_all_context_sents:
                                context_truth = 1

                            context_accuracy.append(context_truth)

                candidate_sent_set = set(candidate_sent_list)
                candidate = " ".join(candidate_sent_set)
                token_reference = nltk.word_tokenize(reference)
                token_candidate = nltk.word_tokenize(candidate)

                bleu_score = sentence_bleu(token_reference,
                                           token_candidate,
                                           smoothing_function=smoothie,
                                           weights=(1, 0, 0, 0))
                rouge_score = rouge.get_scores(candidate, reference)

                bleu_scores.append(bleu_score)
                rouge1_scores.append(rouge_score[0]['rouge-1']['f'])
                rouge2_scores.append(rouge_score[0]['rouge-2']['f'])
                rougel_scores.append(rouge_score[0]['rouge-l']['f'])

        ctx_acc = context_accuracy.count(1)/len(context_accuracy)
        bleu_ave = sum(bleu_scores)/len(bleu_scores)
        rouge1_ave = sum(rouge1_scores)/len(rouge1_scores)
        rouge2_ave = sum(rouge2_scores)/len(rouge2_scores)
        rougel_ave = sum(rougel_scores)/len(rougel_scores)
        # Pick the last question in dataset as a sample
        return bleu_ave, rouge1_ave, rouge2_ave, rougel_ave, ctx_acc, question, reference_list, true_context, candidate_sent_set, pred_all_context_sents

    def __serialize_sets(self, obj):
        if isinstance(obj, set):
            return list(obj)

        return obj

    def get_report(self):
        logs = []
        metric = []

        self.__init_doc_store()

        for qa_dataset in self.qa_datasets:
            for text_dataset in self.text_datasets:
                self.__load_dataset(qa_dataset, text_dataset)

                for embed_title in self.embed_titles:
                    self.__init_retriever(embed_title)
                    tic = time.time()
                    self.__update_embedding()
                    toc = time.time()
                    document_embedding_time = toc - tic

                    for reader_model in self.reader_models:
                        for context_window_size in self.context_window_sizes:
                            for doc_stride in self.doc_strides:
                                for max_seq_len in self.max_seq_lens:
                                    self.__init_reader(
                                        reader_model, context_window_size, max_seq_len, doc_stride)

                                    for retriever_top_k in self.retriever_top_ks:
                                        for reader_top_k in self.reader_top_ks:
                                            for max_seq_len_passage in self.max_seq_len_passages:
                                                for max_seq_len_query in self.max_seq_len_queries:
                                                    tic = time.time()
                                                    bleu_ave, rouge1_ave, rouge2_ave, rougel_ave, ctx_acc, question, reference_list, true_context, candidate_sent_set, pred_all_context_sents = self.__compute_metrics(
                                                        self.reader, self.retriever, self.qa, retriever_top_k, reader_top_k)
                                                    toc = time.time()
                                                    inference_time = toc - tic

                                                    cmd = "nvidia-smi -q -x | grep \<fb_memory_usage\> -A 3 | grep used | sed -n 's:.*<used>\(.*\)</used>.*:\1:p'"
                                                    vram = os.system(cmd)

                                                    metric.append([reader_model, text_dataset, embed_title, context_window_size, max_seq_len, doc_stride,
                                                                   max_seq_len_passage, max_seq_len_query, retriever_top_k, reader_top_k, rouge1_ave,
                                                                   rouge2_ave, rougel_ave, bleu_ave, ctx_acc, vram, document_embedding_time, inference_time])

                                                    log = {'Question': question,
                                                           'Reference answers': reference_list,
                                                           'Reference context': true_context,
                                                           'Predicted answers': candidate_sent_set,
                                                           'Retrieved context': pred_all_context_sents
                                                           }

                                                    logs.append(log)

                    df = pd.DataFrame(metric, columns=self.columns)
                    df.to_csv(self.report_out_dir, index=False)

                    with open(self.sample_out_dir, 'w') as f:
                        json.dump(logs, f, default=self.__serialize_sets)

        return df, logs


quantity = int(input("Enter the quantity of items bought: "))

unit_cost = 100
amount_needed = quantity * unit_cost

if amount_needed > 1000:
    discount = (10 / 100) * amount_needed
    amount_to_be_paid = amount_needed - discount
    print(f"After your 10% discount you'll be paying {amount_to_be_paid:.2f}")
else:
    print("You're not eligible for this discount.")


# -*- coding: utf8 -*-

from scapy.all import sniff, sendp
from scapy.all import Packet
from scapy.all import ShortField, IntField, LongField, BitField
from scapy.all import Ether, IP, ICMP
from mininet.log import info

import time

import sys
import fire
import json
import random
def stringToList(s):
    if s == '':
        return []
    s = s[1:len(s)-1]
    s = s.replace(' ', '')#是否要删除
    print(s)
    return [str(i) for i in s.split(',')]
'''
为了适应时间线的功能现在每次发送一个编码之后的数据包
'''
def send(src, iface, dsts='', index = 0, pow = 5, send_pkt=[]):
    dsts = stringToList(dsts)
    num = len(dsts) #确定广播目标
    for i in range(0,num):
        print("dest%d:"% i,dsts[i])
    #由于send函数只能一对一发送，因此只能采取1对1模拟，每次广播一个数据包
    filename1 = '/home/shlled/mininet-project-duan/TimeSchedule/Log/msg.txt'#读取文件内容，只读取一次，以免开销过大
    f1=open(filename1,'r')
    buffer=f1.readlines()
    lenth=len(buffer)
    total=lenth
    for i in range(0,num):
        #只发送一次
        time.sleep(1)
        dst = dsts[i]
        now = time.time()
        alpha=buffer[index] #读取文本对应位置内容
        msg = "send_time: " + "%.6f" % float(now)  + "total:%d" % total + "index:%d" % index + "data:" + alpha
        send_pkt.append(msg)
        print(msg) #此处打印出发送的内容
        p = Ether() / IP(src=src, dst=dst) / ICMP() / msg

        sendp(p, iface = iface)#组装好数据包之后发送数据

    f1.close()
    #重传部分，先不考虑，后面再考虑重传数据包"

    #AP只考虑广播，并不考虑能量和收益"
fire.Fire(send)


class Solution:
    def XXX(self, nums: List[int]) -> List[List[int]]:
        res = []
        for n in range(1 << len(nums)):
            tmp = []
            for i in range(len(nums)):
                if n & 1: tmp.append(nums[i])
                n = n >> 1
                if n == 0: break
            res.append(tmp)
        return res


# coding: utf-8

# - Reference : https://www.kaggle.com/jannesklaas/a-simple-seq2seq-translator/notebook
# -             https://blog.keras.io/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras.html
# - 그림출처 : https://towardsdatascience.com/neural-machine-translation-using-seq2seq-with-keras-c23540453c74

# # Keras English to French translator 만들기
# - 우리가 구성할 모델은 seqeunce-2-sequence 모듈을 이용하여 영어 문장을 프랑스어 문장으로 바꿔주는 기계 번역기를 만드는 것입니다.
# - 본 실습에서는 기본적인 seq2seq 모듈과 attention 방식을 적용한 2가지 발전된 seq2seq모듈을 구현해보고자 합니다.

# In[4]:

# keras를 비롯하여 필요한 모듈들을 불러옵니다.
from keras.models import Model, load_model
from keras.layers import Input, LSTM, Dense
from keras.callbacks import ModelCheckpoint, EarlyStopping
import numpy as np
import pandas as pd
import os
from numpy.random import seed
seed(1)
import matplotlib.pyplot as plt
from tensorflow import set_random_seed
set_random_seed(2)

# In[ ]:

batch_size = 64   # Batch size for training.
epochs = 25       # Number of epochs to train for.
latent_dim = 256  # Latent dimensionality of the encoding space.
num_samples = 10000  # Number of samples to train on.
# Path to the data txt file on disk.
data_path = './fra-eng/fra.txt'

# ### 데이터셋 예시
# - 아래 표는 model training에 사용될 문구들의 예시입니다.

# In[2]:

df = pd.read_csv(data_path,delimiter='\t')
df.head(20)

# In[3]:

del df # Save memory

# ### 데이터셋 가져오기

# In[5]:

input_texts = []
target_texts = []
input_characters = set()
target_characters = set()

lines = open(data_path, 'rt', encoding='UTF8').read().split('\n')
# 모든 pair 중 앞의 10000쌍 만 골라서 학습에 사용하도록 하겠습니다.
for line in lines[: min(num_samples, len(lines) - 1)]:
    # Input (English)과 target (French)을 분리합니다.
    input_text, target_text = line.split('\t')

    # Target text에서 "tab"을 "start sequence" character로, "\n" as "end sequence" character로 둡니다.
    target_text = '\t' + target_text + '\n'
    input_texts.append(input_text)
    target_texts.append(target_text)

    # input, output 문장들을 구성하는 token들의 집합
    for char in input_text:
        if char not in input_characters:
            input_characters.add(char)

    for char in target_text:
        if char not in target_characters:
            target_characters.add(char)

print('Number of samples:', len(input_texts))

# ### 문자의 벡터화
# - 모델을 트레이닝 하기 위해서 입력된 문자들을 벡터 형태로 바꿔주는 것이 필요합니다.
# - 문자를 해당하는 벡터로 바꾸는 방식은 여러 가지 방법이 있지만, 여기서는 하나의 위치만 1을 나타내고 나머지는 0인 one-hot vector로 encoding하겠습니다.

# In[7]:

# Input과 target 문자들을 순서대로 정렬해줍니다.
input_characters = sorted(list(input_characters))
target_characters = sorted(list(target_characters))
num_encoder_tokens = len(input_characters)  # aka size of the english alphabet + numbers, signs, etc.
num_decoder_tokens = len(target_characters) # aka size of the french alphabet + numbers, signs, etc.

# one-hot encoding으로 생성한 vector의 dimension이 됩니다.
# 즉 여기서는 input (알파벳 및 문장부호)의 경우 71 dimension의 vector, output (프랑스어 알파벳 및 문장부호)은 93 vector dimension의 vector로 바꿀 것입니다.
print('Number of unique input tokens:', num_encoder_tokens)
print('Number of unique output tokens:', num_decoder_tokens)

# In[8]:

# 각 token에 대응하는 숫자를 생성합니다.
input_token_index = {char: i for i, char in enumerate(input_characters)}
target_token_index = {char: i for i, char in enumerate(target_characters)}
for c in 'the cat sits on the mat':
    print(input_token_index[c], end = ' ')

# In[9]:

# 사용할 데이터 중 가장 긴 문구의 길이(글자수)를 가져옵니다.
max_encoder_seq_length = max([len(txt) for txt in input_texts])
max_decoder_seq_length = max([len(txt) for txt in target_texts])

print('Max sequence length for inputs:', max_encoder_seq_length)
print('Max sequence length for outputs:', max_decoder_seq_length)

# In[10]:

# encoder_input_data는 (num_pairs, max_english_sentence_length, num_english_characters) 형태의 3D array
# 즉 영어문장의 one-hot vector들로 구성됩니다.

encoder_input_data = np.zeros(
    (len(input_texts), max_encoder_seq_length, num_encoder_tokens),
    dtype='float32')

# decoder_input_data 역시 (num_pairs, max_french_sentence_length, num_french_characters) 형태의 3D array
# 프랑스어 문장의 one-hot vector들로 구성됩니다.

decoder_input_data = np.zeros(
    (len(input_texts), max_decoder_seq_length, num_decoder_tokens),
    dtype='float32')

# decoder_target_data는 input과 형태는 같지만 input에서 한 time step 뒤의 값을 가집니다.
# 예를 들어 'abc'라는 decoder input sequence가 있다면, target data는 기존 값에서 모델을 통해 예측된 문자 'd'를 덧붙인 'abcd'가 될 것입니다.

decoder_target_data = np.zeros(
    (len(input_texts), max_decoder_seq_length, num_decoder_tokens),
    dtype='float32')

# In[11]:

# 문장 내 각 token에 대응하는 One-hot 벡터를 만드는 과정입니다.
for i, (input_text, target_text) in enumerate(zip(input_texts, target_texts)):
    for t, char in enumerate(input_text):
        encoder_input_data[i, t, input_token_index[char]] = 1.
    for t, char in enumerate(target_text):
        decoder_input_data[i, t, target_token_index[char]] = 1.
        if t > 0:
            # decoder_target_data는
            decoder_target_data[i, t - 1, target_token_index[char]] = 1.

# ### 모델 구성하기
#
# - 아래 코드에 training을 위한 모델을 소개하였습니다.
# - 성능을 높이기 위해 decoder 단에서 입력된 target 값에서 한 time step 씩 뒤의 값들을 decoder target 값으로 사용합니다. 즉 decoder input/output에서 모두 labeled 된 값을 사용합니다.
# ![seq2seq_training](./seq2seq_training.png)

# In[12]:

def seq2seq_train(num_encoder_tokens, num_decoder_tokens, latent_dim):
    # Encoder
    # return_state argument를 True로 설정하여 LSTN layer의 마지막 time step의 내부 state들을 얻습니다.
    encoder_inputs = Input(shape=(None, num_encoder_tokens),
                           name = 'encoder_inputs')
    encoder = LSTM(latent_dim,
                        return_state=True,
                        name = 'encoder')

    encoder_outputs, state_h, state_c = encoder(encoder_inputs)
    encoder_states = [state_h, state_c]

    # Decoder
    # encoder_states를 decoder 단의 lstm에 초기 state로 이용합니다.
    decoder_inputs = Input(shape=(None, num_decoder_tokens),
                           name = 'decoder_inputs')

    decoder_lstm = LSTM(latent_dim,
                             return_sequences=True,
                             return_state=True,
                             name = 'decoder_lstm')

    decoder_outputs, _, _ = decoder_lstm(decoder_inputs,
                                         initial_state=encoder_states)

    decoder_dense = Dense(num_decoder_tokens,
                          activation='softmax',
                          name = 'decoder_dense')
    decoder_outputs = decoder_dense(decoder_outputs)

    model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
    return encoder_inputs, encoder_states, decoder_inputs, decoder_lstm, decoder_dense, model
[encoder_inputs, encoder_states, decoder_inputs, decoder_lstm, decoder_dense, model] = seq2seq_train(num_encoder_tokens, num_decoder_tokens, latent_dim)

# In[13]:

# 저장된 모델을 불러오는 부분입니다.
project_path = './model/'

if not os.path.exists(project_path):
    os.mkdir(project_path)

model_path = project_path + 's2s.hdf5'

checkpoint = ModelCheckpoint(filepath=model_path, monitor='val_loss', save_best_only=True)
early_stopping = EarlyStopping(monitor='val_loss', patience=10)

# In[14]:

# 모델 학습하기 (시간상 넘어가도록 하겠습니다.)
model.compile(optimizer='rmsprop', loss='categorical_crossentropy')
history = model.fit([encoder_input_data, decoder_input_data],
                    decoder_target_data,
                    batch_size=batch_size,
                    epochs=epochs,
                    validation_split=0.2,
                    callbacks=[checkpoint])
# 학습한 모델 저장하기
model.save(model_path)

# In[14]:

# Training curve를 그리는 코드입니다. 모델이 트레이닝 될 경우에만 그려주므로 넘어가도록 합니다.
plt.figure(figsize=(10,7))
a, = plt.plot(history.history['loss'],label='Training Loss')
b, = plt.plot(history.history['val_loss'],label='Validation Loss')
plt.legend(handles=[a,b])
plt.show()

# ![Curve](./seq2seq_training_curve.png)

# ## Inference (sampling) model 만들기
# - 실제 우리가 사용할 모델은 decoder단에서 예측한 문자가 다시 lstm의 input으로 들어가 다음 글자를 예측하는 과정이 반복되는 방식을 사용합니다.
# ![seq2seq_inference](./seq2seq_inference.png)

# In[15]:

model = load_model(model_path)
def seq2seq_inference(latent_dim, encoder_inputs, encoder_states, decoder_inputs, decoder_lstm, decoder_dense):
    '''Encoder model'''
    encoder_model = Model(encoder_inputs, encoder_states)

    '''Decoder model'''
    # Decoder의 input
    decoder_state_input_h = Input(shape=(latent_dim,))
    decoder_state_input_c = Input(shape=(latent_dim,))
    decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]

    # Decoder output 및 state
    decoder_outputs, state_h, state_c = decoder_lstm(
        decoder_inputs, initial_state=decoder_states_inputs)
    decoder_states = [state_h, state_c]

    # 다음 문자 예측
    decoder_outputs = decoder_dense(decoder_outputs)

    # Decoder 모델
    decoder_model = Model(
        [decoder_inputs] + decoder_states_inputs,
        [decoder_outputs] + decoder_states)
    return [encoder_model, decoder_model]
[encoder_model, decoder_model] = seq2seq_inference(latent_dim, encoder_inputs, encoder_states, decoder_inputs, decoder_lstm, decoder_dense)
# [encoder_model, decoder_model] = seq2seq(num_encoder_tokens, num_decoder_tokens, latent_dim).model_inference(encoder_inputs, encoder_states, decoder_inputs, decoder_lstm, decoder_dense)

# In[16]:

# decode된 각 숫자에 대응하는 token입니다.
reverse_input_char_index = {i: char
                            for char, i in input_token_index.items()}
reverse_target_char_index = {i: char
                             for char, i in target_token_index.items()}
print(reverse_input_char_index)
print(reverse_target_char_index)

# ### 문자 decoding
# 이제 학습한 모델을 이용해 영어문장을 프랑스어 문장으로 바꿔봅시다.

# In[17]:

def decode_sequence(input_seq):
    # Input을 state vector들로 encode 합니다.
    states_value = encoder_model.predict(input_seq)

    # Decoder input sequence의 첫 부분을 start character로 초기화합니다.
    target_seq = np.zeros((1, 1, num_decoder_tokens))
    target_seq[0, 0, target_token_index['\t']] = 1.

    stop_condition = False
    decoded_sentence = ''

    # stop sign이 나오기 전까지 문장을 예측합니다.
    while not stop_condition:
        # Decoder의 이전 output, internal states를 이용해 다음 값을 예측합니다.
        output_tokens, h, c = decoder_model.predict(
            [target_seq] + states_value)

        # 가장 높은 확률로 예측되는 token을 sampling합니다.
        sampled_token_index = np.argmax(output_tokens[0, -1, :])
        # 예측한 token에 해당하는 문자를 찾습니다.
        sampled_char = reverse_target_char_index[sampled_token_index]
        # decoded된 문장에 예측 문자를 덧붙여 문장을 예측해갑니다.
        decoded_sentence += sampled_char

        # decoded된 문장이 최대 길이를 초과하거나 'stop' character를 만나게 될 때 예측을 멈춥니다.
        if (sampled_char == '\n' or
           len(decoded_sentence) > max_decoder_seq_length):
            stop_condition = True

        # Target sequence를 update합니다.
        target_seq = np.zeros((1, 1, num_decoder_tokens))
        target_seq[0, 0, sampled_token_index] = 1.

        # 다음 문자를 예측하기 위해 state 값을 update합니다.
        states_value = [h, c]

    return decoded_sentence

# In[18]:

my_text = 'Run!'
placeholder = np.zeros((1,len(my_text)+10,num_encoder_tokens))

# In[19]:

for i, char in enumerate(my_text):
    print(i,char, input_token_index[char])
    placeholder[0,i,input_token_index[char]] = 1

# In[20]:

decode_sequence(placeholder)

# In[22]:

for seq_index in range(10):
    input_seq = encoder_input_data[seq_index: seq_index + 1]
    decoded_sentence = decode_sequence(input_seq)
    print('-')
    print('Input sentence:', input_texts[seq_index])
    print('Decoded sentence:', decoded_sentence)


from flask import Flask, render_template, request
from datetime import datetime
import pandas as pd
import json

app = Flask(__name__)
# 資料是寫死固定的，可寫在全域端
books = {1: "Python book", 2: "Java book", 3: "Flask book"}
ascending = True

# 首頁
@app.route("/")
@app.route("/index")
def index():
    today = datetime.now()
    print(today)
    # 傳遞資料至靜態網頁(template的index)
    return render_template("index.html", today=today)
    # return f"
Hello world!{today}
"

# 書的首頁
@app.route("/books")
def get_all_books():
    today = datetime.now()
    books = {
        1: {
            "name": "Python book",
            "price": 299,
            "image_url": "https://im2.book.com.tw/image/getImage?i=https://www.books.com.tw/img/CN1/136/11/CN11361197.jpg&v=58096f9ck&w=348&h=348",
        },
        2: {
            "name": "Java book",
            "price": 399,
            "image_url": "https://im1.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/087/31/0010873110.jpg&v=5f7c475bk&w=348&h=348",
        },
        3: {
            "name": "C# book",
            "price": 499,
            "image_url": "https://im1.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/036/04/0010360466.jpg&v=62d695bak&w=348&h=348",
        },
    }
    for id in books:
        print(id, books[id]["name"], books[id]["price"], books[id]["image_url"])

    # return render_template("books.html", **locals())
    return render_template("books.html", books=books, today=today)
    # return books

# 書的分頁
@app.route("/books/id=<int:id>", methods=["GET"])
def get_books(id):
    try:
        return f"
{books[id]}
"
    except Exception as e:
        print(e)
    return "
書籍編號錯誤!
"

@app.route("/bmi/name=<n>&weight=<w>&height=<h>")
def get_bmi(n, w, h):
    bmi = round(eval(w) / (eval(h) / 100) ** 2, 2)
    return {"name": n, "weight": w, "height": h, "bmi": bmi}

@app.route("/pm25-chart")
def pm25_chart():
    return render_template("pm25-chart.html")

@app.route("/pm25-json")
def get_pm25_json():
    url = "https://data.moenv.gov.tw/api/v2/aqx_p_02?api_key=e8dd42e6-9b8b-43f8-991e-b3dee723a52d&limit=1000&sort=datacreationdate%20desc&format=CSV"
    df = pd.read_csv(url).dropna()

    json_data = {
        "title": "PM2.5數據",
        "xData": df["site"].tolist(),
        "yData": df["pm25"].tolist(),
    }
    return json.dumps(json_data, ensure_ascii=False)

@app.route("/pm25", methods=["GET", "POST"])
def get_pm25():
    global ascending
    url = "https://data.moenv.gov.tw/api/v2/aqx_p_02?api_key=e8dd42e6-9b8b-43f8-991e-b3dee723a52d&limit=1000&sort=datacreationdate%20desc&format=CSV"
    now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    sort = False
    if request.method == "POST":
        print(request.form)
        if request.form.get("sort"):
            sort = True
    try:
        df = pd.read_csv(url).dropna()
        # 製作升降序功能
        if sort:
            df = df.sort_values("pm25", ascending=ascending)
            ascending = not ascending
        else:
            # 回復原本狀態
            ascending = True

        columns = df.columns.tolist()
        values = df.values.tolist()
        # 取出 values的最高與最低值
        lowest = df.sort_values("pm25").iloc[0][["site", "pm25"]].values
        highest = df.sort_values("pm25").iloc[-1][["site", "pm25"]].values

        message = "取得資料成功"

    except Exception as e:
        print(e)
        message = "取得資料失敗，請稍後再試"

    return render_template("pm25.html", **locals())

##邏輯引用不重複出現
if __name__ == "__main__":
    app.run(debug=True)


import unittest
import pytest
from time import gmtime

from web_interface.filter import replace_underscore_filter, byte_number_filter, get_all_uids_in_string, nice_list, uids_to_link, \
    list_to_line_break_string, nice_unix_time, nice_number_filter, sort_chart_list_by_value, \
    sort_chart_list_by_name, text_highlighter, generic_nice_representation, list_to_line_break_string_no_sort,\
    encode_base64_filter, render_tags

class TestWebInterfaceFilter(unittest.TestCase):

    def test_get_all_uids_in_string(self):
        test_string = '{\'d41c0f1431b39b9db565b4e32a5437c61c77762a3f4401bac3bafa4887164117_24\', \'f7c927fb0c209035c7e6939bdd00eabdaada429f2ee9aeca41290412c8c79759_25\' , \'deaa23651f0a9cc247a20d0e0a78041a8e40b144e21b82081ecb519dd548eecf_24494080\'}'
        result = get_all_uids_in_string(test_string)
        self.assertEqual(len(result), 3, 'not all uids found')
        self.assertIn('d41c0f1431b39b9db565b4e32a5437c61c77762a3f4401bac3bafa4887164117_24', result, 'first uid not found')
        self.assertIn('f7c927fb0c209035c7e6939bdd00eabdaada429f2ee9aeca41290412c8c79759_25', result, 'second uid not found')
        self.assertIn('deaa23651f0a9cc247a20d0e0a78041a8e40b144e21b82081ecb519dd548eecf_24494080', result, 'third uid not found')

    def test_handle_uids(self):
        test_string = 'foo d41c0f1431b39b9db565b4e32a5437c61c77762a3f4401bac3bafa4887164117_24 bar'
        result = uids_to_link(test_string)
        self.assertEqual(result, 'foo d41c0f1431b39b9db565b4e32a5437c61c77762a3f4401bac3bafa4887164117_24 bar', 'output not correct')

    def check_nice_list_output(self, input_data):
        result = nice_list(input_data)
        self.assertEqual(result, '
\n\t
a
\n\t
b
\n
\n', 'output not correct')

    def test_nice_list_set(self):
        self.check_nice_list_output(set('ab'))

    def test_nice_list_list(self):
        self.check_nice_list_output(['a', 'b'])

    def test_list_to_line_break_string(self):
        input_data = set('ab')
        self.assertEqual(list_to_line_break_string(input_data), 'a\nb\n')

    def test_list_to_line_break_string_no_sort(self):
        input_data = ['b', 'a']
        self.assertEqual(list_to_line_break_string_no_sort(input_data), 'b\na\n')

    def test_nice_unix_time_stamp(self):
        input_data = 1459427460
        self.assertEqual(nice_unix_time(input_data), '2016-03-31 14:31:00', 'output not correct (int)')
        input_data = 1459427460.4
        self.assertEqual(nice_unix_time(input_data), '2016-03-31 14:31:00', 'output not correct (float)')
        self.assertEqual(nice_unix_time('test'), 'test')

    def test_sort_chart_list_by_value(self):
        test_list = [['a', 1], ['b', 2]]
        result = sort_chart_list_by_value(test_list)
        self.assertEqual(result, [['b', 2], ['a', 1]])

    def test_sort_chart_list_by_name(self):
        test_list = [['b', 2], ['a', 1]]
        result = sort_chart_list_by_name(test_list)
        self.assertEqual(result, [['a', 1], ['b', 2]])

    def test_text_highliter(self):
        self.assertEqual(text_highlighter('online'), 'online')
        self.assertEqual(text_highlighter('offline'), 'offline')
        self.assertEqual(text_highlighter('foo'), 'foo')
        self.assertEqual(text_highlighter('foo', green=['*']), 'foo')
        self.assertEqual(text_highlighter('foo', red=['*']), 'foo')

def test_replace_underscore():
    assert replace_underscore_filter('a_b') == 'a b'

def test_base64_filter():
    assert encode_base64_filter(b'test') == 'dGVzdA=='

@pytest.mark.parametrize('input_data, verbose, expected', [
    (1000, False, '1000.00 Byte'),
    (1024, False, '1.00 KiB'),
    (1024 * 1024, False, '1.00 MiB'),
    (1234.1234, False, '1.21 KiB'),
    (1000, True, '1000.00 Byte (1,000 bytes)'),
    (b'abc', False, 'not available'),
    (None, False, 'not available')
])
def test_byte_number_filter(input_data, verbose, expected):
    assert byte_number_filter(input_data, verbose) == expected

@pytest.mark.parametrize('input_data, expected', [
    (b'abc', b'abc'),
    (123, '123'),
    (1234, '1,234'),
    (1234.1234, '1,234.12'),
    (None, 'not available')
])
def test_nice_number(input_data, expected):
    assert nice_number_filter(input_data) == expected

@pytest.mark.parametrize('input_data, expected', [
    (b'abc', 'abc'),
    (1234, '1,234'),
    ([1, 3], '
\n\t
1
\n\t
3
\n
\n'),
    ({'a': 1}, 'a: 1
'),
    (gmtime(0), '1970-01-01 - 00:00:00'),
    ('a_b', 'a b'),
    (gmtime, gmtime)
])
def test_generic_nice_representation(input_data, expected):
    assert generic_nice_representation(input_data) == expected

@pytest.mark.parametrize('tag_dict, output', [
    ({'a': 'danger'}, 'a\n'),
    ({'a': 'danger', 'b': 'default'}, 'a\nb\n'),
    (None, '')
])
def test_render_tags(tag_dict, output):
    assert render_tags(tag_dict) == output


import os
import unittest
from pathlib import Path
from typing import List

from binaryrts.parser.sourcecode import CSourceCodeParser, FunctionDefinition

RESOURCES_DIR: Path = Path(os.path.dirname(__file__)) / "resources"
SOURCE_FILE: Path = RESOURCES_DIR / "main.cpp"
HEADER_FILE: Path = RESOURCES_DIR / "lib.h"
COMPLEX_FILE: Path = RESOURCES_DIR / "complex.cpp"

class SourceCodeParserTestCase(unittest.TestCase):
    def test_get_functions(self):
        parser: CSourceCodeParser = CSourceCodeParser()
        actual: List[FunctionDefinition] = parser.get_functions(file=SOURCE_FILE)
        expected: List[FunctionDefinition] = [
            FunctionDefinition(
                file=SOURCE_FILE,
                signature="CustomPair(T,T)",
                start_line=19,
                end_line=22,
                namespace="templates",
                class_name="CustomPair<class T>",
                properties=None,
            ),
            FunctionDefinition(
                file=SOURCE_FILE,
                signature="GetMax()",
                start_line=25,
                end_line=28,
                namespace="templates",
                class_name="CustomPair<class T>",
                properties=None,
            ),
            FunctionDefinition(
                file=SOURCE_FILE,
                signature="GetMax<typename T>(T,T)",
                start_line=33,
                end_line=35,
                namespace="templates",
                properties=None,
            ),
            FunctionDefinition(
                file=SOURCE_FILE,
                signature="bar(int)",
                start_line=54,
                end_line=55,
                namespace=None,
                class_name="C",
                properties=None,
            ),
            FunctionDefinition(
                file=SOURCE_FILE,
                signature="baz()",
                start_line=57,
                end_line=59,
                class_name="C",
                properties=None,
            ),
            FunctionDefinition(
                file=SOURCE_FILE,
                signature="foo()",
                start_line=41,
                end_line=43,
                class_name="A",
                properties="virtual",
            ),
            FunctionDefinition(
                file=SOURCE_FILE,
                signature="foo()",
                start_line=50,
                end_line=52,
                class_name="C",
                properties="override,virtual",
            ),
            FunctionDefinition(
                file=SOURCE_FILE,
                signature="main()",
                start_line=82,
                end_line=92,
            ),
            FunctionDefinition(
                file=SOURCE_FILE,
                signature="weird_add(int,int)",
                start_line=8,
                end_line=11,
            ),
            FunctionDefinition(
                file=SOURCE_FILE,
                signature="foo()",
                start_line=69,
                end_line=69,
                class_name="Foo<typename X,typename Y>",
                namespace="Base"
            ),
            FunctionDefinition(
                file=SOURCE_FILE,
                signature="bar()",
                start_line=75,
                end_line=75,
                class_name="Bar<typename Z,typename W>",
                namespace="Base"
            ),
            FunctionDefinition(
                file=SOURCE_FILE,
                signature="foo<>()",
                start_line=79,
                end_line=79,
                class_name="Foo",
                namespace="Base"
            ),
        ]
        self.assertSetEqual(set(expected), set(actual))

    def test_get_functions_complex(self):
        parser: CSourceCodeParser = CSourceCodeParser()
        actual: List[FunctionDefinition] = parser.get_functions(file=COMPLEX_FILE)
        expected: List[FunctionDefinition] = [
            FunctionDefinition(
                file=COMPLEX_FILE,
                signature="foo()",
                start_line=13,
                end_line=15,
                namespace="bar",
                class_name="X<><int>",
                properties=None,
            ),
            FunctionDefinition(
                file=COMPLEX_FILE,
                signature="bar()",
                start_line=20,
                end_line=22,
                namespace="bar::baz",
                class_name="Z",
                properties='static'
            ),
            FunctionDefinition(
                file=COMPLEX_FILE,
                signature="foo()",
                start_line=26,
                end_line=29,
                namespace="bar",
                class_name=None,
                properties=None,
            ),
            FunctionDefinition(
                file=COMPLEX_FILE,
                signature="f(T)",
                start_line=37,
                end_line=37,
                namespace="foo",
                class_name="A<typename T>",
                properties=None,
            ),
            FunctionDefinition(
                file=COMPLEX_FILE,
                signature="g<typename T>(T)",
                start_line=48,
                end_line=48,
                namespace="foo",
                class_name="A",
                properties='scopespecialization,specialization'
            ),
            FunctionDefinition(
                file=COMPLEX_FILE,
                signature="f(int)",
                start_line=56,
                end_line=56,
                namespace="foo",
                class_name="A",
                properties='scopespecialization,specialization',
            ),
            FunctionDefinition(
                file=COMPLEX_FILE,
                signature="f()",
                start_line=64,
                end_line=64,
                namespace="foo::A",
                class_name="B",
                properties='scopespecialization,specialization',
            ),
            FunctionDefinition(
                file=COMPLEX_FILE,
                signature="g()",
                start_line=71,
                end_line=73,
                namespace="foo::A",
                class_name="C<class U><char>",
                properties=None,
            ),
            FunctionDefinition(
                file=COMPLEX_FILE,
                signature="f<class U>()",
                start_line=79,
                end_line=79,
                namespace="foo::A",
                class_name="C",
                properties='scopespecialization,specialization'
            ),
            FunctionDefinition(
                file=COMPLEX_FILE,
                signature="main()",
                start_line=82,
                end_line=97,
                namespace=None,
                class_name=None,
                properties=None,
            ),
        ]
        self.assertSetEqual(set(expected), set(actual))

    def test_get_functions_header(self):
        parser: CSourceCodeParser = CSourceCodeParser()
        actual: List[FunctionDefinition] = parser.get_functions(file=HEADER_FILE)
        expected: List[FunctionDefinition] = [
            FunctionDefinition(
                file=HEADER_FILE,
                signature="weird_add(int,int)",
                start_line=1,
                end_line=4,
            ),
        ]
        self.assertSetEqual(set(expected), set(actual))

    def test_strip_comments(self):
        self.assertEqual(
            """ \nint main() {\n\treturn 0;  \n}""",
            CSourceCodeParser.strip_comments(
                """// some line comment\nint main() {\n\treturn 0; // more lines\n}""".strip()
            ),
        )
        self.assertEqual(
            """ \nint main() {\n\treturn 0;  \n}""",
            CSourceCodeParser.strip_comments(
                """/* some line comment */\nint main() {\n\treturn 0; /* more lines */\n}""".strip()
            ),
        )
        self.assertEqual(
            """int main() {\n\treturn 0;  \n}""",
            CSourceCodeParser.strip_comments(
                """/* some line \n * comment \n * and more */\nint main() {\n\treturn 0; /* more lines */\n}""".strip()
            ).strip(),
        )

    def test_strip_whitespaces(self):
        self.assertEqual(
            """intmain(){return0;}""",
            CSourceCodeParser.strip_whitespaces("""int main() {\n\treturn 0;  \n}"""),
        )

    def test_strip_comments_and_whitespaces(self):
        self.assertEqual(
            """intmain(){return0;}""",
            CSourceCodeParser.strip_whitespaces(
                CSourceCodeParser.strip_comments(
                    """/* some line \n * comment \n * and more */\nint main() {\n\treturn 0; /* more lines */\n}"""
                )
            ),
        )

    def test_extract_raw_signature(self):
        self.assertEqual(
            """(finalint*,std::string,const&int,char**,char[]*,double&)""",
            CSourceCodeParser.extract_raw_signature(
                """(final int *a, std::string o, const &int b, char** c, char[]* diGGa,double &x)"""
            ),
        )
        self.assertEqual(
            """(FooSuite,Max)""",
            CSourceCodeParser.extract_raw_signature(
                """(FooSuite,Max)"""
            ),
        )

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


from electionguard.decrypt_with_secrets import (
    decrypt_selection_with_secret,
    decrypt_selection_with_nonce,
    decrypt_contest_with_secret,
    decrypt_contest_with_nonce,
    decrypt_ballot_with_nonce,
    decrypt_ballot_with_secret,
)
from electionguard.elgamal import ElGamalKeyPair, ElGamalCiphertext
from electionguard.group import (
    ElementModQ,
    TWO_MOD_P,
    ONE_MOD_Q,
    mult_p,
    g_pow_p,
)
from electionguard.election import (
    CiphertextElectionContext,
    make_ciphertext_election_context,
)
from electionguard.manifest import InternalManifest
from electionguard.logs import log_warning, log_info
import electionguard_tools.factories.ballot_factory as BallotFactory
import electionguard_tools.factories.election_factory as ElectionFactory
import os

election_factory = ElectionFactory.ElectionFactory()
ballot_factory = BallotFactory.BallotFactory()

keypair = ElGamalKeyPair(TWO_MOD_P, g_pow_p(TWO_MOD_P))
encypted_file_dir = os.path.join(os.path.dirname(os.getcwd()), "encrypted_data")
generated_file_dir = os.path.join(os.path.dirname(os.getcwd()), "generated_data")

if not os.path.exists(os.path.join(encypted_file_dir)):
    os.makedirs(encypted_file_dir)
    exit()

for ballotNum in os.listdir(encypted_file_dir):
    if ballotNum == '.DS_Store':
        continue
    encypted_file_dir_with_ballotNum = os.path.join(encypted_file_dir, ballotNum)
    generated_data_dir_with_ballotNum = os.path.join(generated_file_dir, ballotNum)
    for ballot_filename in os.listdir(encypted_file_dir_with_ballotNum):
        subject = ballot_factory.get_ciphertext_ballot_from_file(
            encypted_file_dir_with_ballotNum, ballot_filename
        )
        manifest = (
            election_factory.get_simple_manifest_from_file_self_defined_directory(
                generated_data_dir_with_ballotNum, "manifest.json"
            )
        )
        internal_manifest = InternalManifest(manifest)
        context = make_ciphertext_election_context(
            number_of_guardians=1,
            quorum=1,
            elgamal_public_key=keypair.public_key,
            commitment_hash=ElementModQ(2),
            manifest_hash=manifest.crypto_hash(),
        )
        result_from_key = decrypt_ballot_with_secret(
            subject,
            internal_manifest,
            context.crypto_extended_base_hash,
            keypair.public_key,
            keypair.secret_key,
            remove_placeholders=False,
        )

        result_from_nonce = decrypt_ballot_with_nonce(
            subject,
            internal_manifest,
            context.crypto_extended_base_hash,
            keypair.public_key,
            remove_placeholders=False,
        )
        result_from_nonce_seed = decrypt_ballot_with_nonce(
            subject,
            internal_manifest,
            context.crypto_extended_base_hash,
            keypair.public_key,
            subject.nonce,
            remove_placeholders=False,
        )
        if (
            result_from_key == None
            or result_from_nonce == None
            or result_from_nonce_seed == None
        ):
            log_warning(f"Unable To Decrypt for Manifest: {ballotNum}")
        print(
            "------------------------ Successfully Decrypt: "
            + ballot_filename
            + " ---------------------------"
        )
        print(result_from_key)


import random

def check_yours(S):
    # 檢查輸入 1.長度位數 2. 是否重複
    if len(S) != 4:
        return False
    l = [i for i in S]
    if len(l) == len(set(l)):
        return True
    return False

def give_ans():
    # 生成答案
    num = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    random.shuffle(num)
    ans = ''.join(num[0:4])
    return ans

def compare(a, y):
    # 生成幾A幾B
    A = 0
    B = 0
    for i in range(len(y)):
        if y[i] == a[i]:
            A += 1
        elif y[i] in a:
            B += 1
    if A == len(a):
        return True
    return f'{A}A{B}B，繼續：'

# 生成答案
A = give_ans()

# 輸入你的答案
you = str(input('請輸入四位數字：'))

while True:
    if check_yours(you):
        if compare(A, you) == True:
            print('答對了，恭喜你！')
            break
        else:
            you = str(input(compare(A, you)))
    else:
        you = str(input('好好給，謝謝：'))


#-----------------------------------------------------------------------------
# This file is part of the 'axi-soc-ultra-plus-core'. It is subject to
# the license terms in the LICENSE.txt file found in the top-level directory
# of this distribution and at:
#    https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
# No part of the 'axi-soc-ultra-plus-core', including this file, may be
# copied, modified, propagated, or distributed except according to the terms
# contained in the LICENSE.txt file.
#-----------------------------------------------------------------------------

import pyrogue as pr

import surf.devices.ti as ti
import surf.xilinx     as xil

class Hardware(pr.Device):
    def __init__(self,hidden=True,**kwargs):
        # Force Offset 0x0
        super().__init__(offset=0x0,hidden=hidden,**kwargs)

        # Create default lists
        mioConfig   = [dict(name = f'MIO_{x}', enable = False) for x in range(78)]

        # Customize the GPIO names
        mioConfig[7]  = dict(name = 'LMK_RST', enable = True)
        mioConfig[8]  = dict(name = 'LMK_CLK_IN_SEL0', enable = True)
        mioConfig[12] = dict(name = 'LMK_CLK_IN_SEL1', enable = True)
        mioConfig[17] = dict(name = 'PS_LED1', enable = True)
        mioConfig[20] = dict(name = 'PS_LED0', enable = True)

        # Add Zynq PS GPIO
        self.add(xil.GpioPs(
            offset    = 0x00FF0A0000,
            mioConfig = mioConfig,
            # expand    = True,
        ))

        # Add SPI Bridge for the Zynq PS SPI0
        self.add(xil.SpiPs(
            name   = 'SpiBridge',
            offset = 0x00FF040000,
        ))

        # Add LMK device
        virtualOffset  = ( 0 << 48) # SPI_Device_Index  = 0
        virtualOffset |= ( 2 << 44) # SPI_Address_Bytes = 2
        virtualOffset |= ( 1 << 40) # SPI_Data_Bytes    = 1
        self.add(ti.Lmk04828(
            name            = 'Lmk',
            offset          = virtualOffset,
            memBase         = self.SpiBridge.proxy,
            allowHexFileRst = False,
            enabled         = False, # Do not access until after SPI bridge configured
            hidden          = True,
        ))

        # Add LMX device
        for i in range(2):
            virtualOffset  = ( i+1 << 48) # SPI_Device_Index  = 0
            virtualOffset |= ( 1   << 44) # SPI_Address_Bytes = 1
            virtualOffset |= ( 2   << 40) # SPI_Data_Bytes    = 2
            self.add(ti.Lmx2594(
                name    = f'Lmx[{i}]',
                offset  = virtualOffset,
                memBase = self.SpiBridge.proxy,
                enabled = False, # Do not access until after SPI bridge configured
                hidden  = True,
            ))

    def _start(self):
        super()._start()

        # Configure the PS GPIO DIR
        self.GpioPs.LMK_CLK_IN_SEL1_DIR.set(1)
        self.GpioPs.LMK_CLK_IN_SEL0_DIR.set(1)
        self.GpioPs.LMK_RST_DIR.set(1)
        self.GpioPs.PS_LED1_DIR.set(1)
        self.GpioPs.PS_LED0_DIR.set(1)

        # Configure the PS GPIO OEN
        self.GpioPs.LMK_CLK_IN_SEL1_OEN.set(1)
        self.GpioPs.LMK_CLK_IN_SEL0_OEN.set(1)
        self.GpioPs.LMK_RST_OEN.set(1)
        self.GpioPs.PS_LED1_OEN.set(1)
        self.GpioPs.PS_LED0_OEN.set(1)

        # Configure the PS GPIO OUT
        self.GpioPs.LMK_CLK_IN_SEL1_OUT.set(0)
        # self.GpioPs.LMK_CLK_IN_SEL0_OUT.set(0) # External reference
        self.GpioPs.LMK_CLK_IN_SEL0_OUT.set(1) # Local 10 MHz reference
        self.GpioPs.LMK_RST_OUT.set(0)
        self.GpioPs.PS_LED1_OUT.set(1)
        self.GpioPs.PS_LED0_OUT.set(0)

        # Initialize the SPI bridge
        self.SpiBridge.Regs.BAUD_RATE_DIV.setDisp('div256')
        self.SpiBridge.Init()

    def InitClock(self, lmkConfig=None, lmxConfig=[None]):

        # Check if same LMX configuration for both devices
        if len(lmxConfig) == 1:
            lmxCfg = [lmxConfig[0] for i in range(2)]
        else:
            lmxCfg = lmxConfig

        # Seems like 1st time after power up that need to load twice
        for x in range(2):

            # Configure the LMK for 4-wire SPI
            self.Lmk.enable.set(True)
            self.Lmk.LmkReg_0x0000.set(value=0x90,verify=False) # 4-wire SPI + RESET
            self.Lmk.LmkReg_0x0000.set(value=0x10,verify=False) # 4-wire SPI
            self.Lmk.LmkReg_0x014A.set(value=0x06,verify=False) # RESET/GPO as open drain
            self.Lmk.LmkReg_0x016E.set(value=0x3B,verify=False) # STATUS_LD2 = SPI readback

            # Load the LMK configuration from the TICS Pro software HEX export
            self.Lmk.PwrDwnLmkChip()
            self.Lmk.PwrUpLmkChip()
            self.Lmk.LoadCodeLoaderHexFile(lmkConfig)
            self.Lmk.Init()
            self.Lmk.LmkReg_0x016E.set(value=0x13,verify=False) # STATUS_LD2 = PLL2 DLD
            self.Lmk.enable.set(False)

            # Load the LMX configuration from the TICS Pro software HEX export
            for i in range(2):
                self.Lmx[i].enable.set(True)
                self.Lmx[i].DataBlock.set(value=0x002410,index=0, write=True) # MUXOUT_LD_SEL=readback
                self.Lmx[i].LoadCodeLoaderHexFile(lmxCfg[i])
                self.Lmx[i].DataBlock.set(value=0x002414,index=0, write=True, verify=False) # MUXOUT_LD_SEL=LockDetect (change without verifying)
                self.Lmx[i].enable.set(False)


#  Dipesh Bhattarai
#  Student id = 2357842

# ⬇Defining the welcome function
# def welcome():
#     print("Welcome to the Caesar Cipher")
#     print("This program encrypts and decrypts text using Caesar Cipher.")

# using __doc__
def welcome():
    '''Welcome to the Caesar Cipher.
This program encrypts and decrypts text using Caesar Cipher.'''

# ⬇Defining the enter_message function to get input from the user
def enter_message():
    while True:
        # Asking the user for their user_choice to encrypt or decrypt
        mode = input("Would you like to encrypt (e) or decrypt (d): ").lower()
        if mode == 'e' or mode == 'd':
            break
        else:
            print("Invalid mode")

# Definig the global variable
    file_source = None
    message = None
    filename = None
    shift = 0

 # This line starts a loop that will continue to run until
 # either the message or filename variable is not empty.
    while not (message or filename):
        file_source = input(
            "Would you like to read from a file (f) or the console (c)? ").lower()

        if file_source == 'f':

            # This line starts a loop that will continue to run until a valid filename is entered.
            while not filename:
                filename = input("Enter a filename: ")
                # This line checks if the entered filename is a valid file.
                if not is_file(filename):
                    # If the filename is not valid,
                    # this line prints an error message and sets the filename variable to None.
                    print("Invalid Filename")
                    filename = None
                else:
                    # This line starts an inner loop that will continue to run until
                    # a valid shift number is entered.
                    while True:
                        try:
                            shift = int(input("What is the shift number: "))
                            break
                        # If the valid shift integer is not entered
                        # then the error message Invalid shift will be printed
                        except:
                            print("Invalid Shift")

        elif file_source == 'c':
            while True:
                try:
                    if mode == "e":
                        message = input(
                            "What message would you like to encrypt: ").upper()
                    elif mode == "d":
                        message = input(
                            "What message would you like to decrypt: ").upper()
                    shift = int(input("What is the shift number: "))
                    break
                except:
                    print("Invalid Shift")
        else:
            # If the user did not enter a valid input for file_source,
            # this line prints an error message.
            print("Invalid input")
    # Once the loop has been exited,
    # this line returns the values of mode, message, filename, and shift.
    return mode, message, filename, shift

# Defining a encrypt function that takes two parameters, message and shift.
def encrypt(message, shift):
    # This line initializes an empty string called encrypted_text,
    # which will be used to store the encrypted message.
    encrypted_text = ''
    # This line starts a loop that iterates over each character
    # in the message parameter.
    for char in message:
        # This line checks if the current character is an alphabetic character.
        if char.isalpha():
            # Calculates the new character by shifting it by the specified shift amount
            # The ord() function converts the character to its ASCII code
            # The ASCII code for 'A' is 65, so we subtract 65 from the ASCII code to get the letter's position in the alphabet (0-25)
            # We add the shift amount to this position, then take the result modulo 26 to ensure it stays within the range 0-25
            # Finally, we add 65 to the result to convert it back to ASCII code for the shifted letter
            char = chr((ord(char) - 65 + shift) % 26 + 65)
         # Adds the current character to the encrypted_text string
        encrypted_text = encrypted_text + char
    # This line returns the final encrypted message.
    return encrypted_text

# ⬇ By using -shift direct decryption function
# # Defining a decrypt decrypt that takes two parameters, message and shift.
# def decrypt(message, shift):
#     # The reason this works is that encrypting the message with a positive shift
#     # and then decrypting it with the negative of that shift will
#     # undo the encryption and return the original message.
#     return encrypt(message, -shift)

# ⬇Manual type decryption function
def decrypt(message, shift):
    decrypted_text = ''
    for char in message:
        if char.isalpha():
            char = chr((ord(char) - 65 - shift) % 26 + 65)
        decrypted_text += char
    return decrypted_text

# This line defines a function called is_file that takes a filename as a parameter.
def is_file(filename):
    # This function tries to open the file with the given filename for reading.
    try:
        open(filename, 'r')
    # If the file exists and can be opened, it returns True.
        return True
    except:
        # Otherwise, it returns False.
        return False

# This funtion writes strings to a file called results.txt, with each item taking up a single line.
def write_messages(messages):
    with open("results.txt", "w") as file:
        # This code writes each string in the messages list to the file,
        # followed by a newline character.
        # This ensures that each string is on a separate line.
        for message in messages:
            file.write(message + "\n")

# This funtion process the lines in the file one by one, returning a list of encrypted/decrypted messages.
def process_file(filename, mode, shift):
    # Initializing an empty list called messages,
    # then opens the file with the given filename for reading.
    messages = []
    with open(filename, "r") as file:
        for line in file:
            #! .strip() is used to Remove spaces at the beginning and at the end of the string
            message = line.strip().upper()
            if mode == 'e':
                # This code encrypts the message,
                # depending on the value of mode, and appends the result to the messages list.
                messages.append(encrypt(message, shift))
            else:
                # This code decrypts the message,
                # depending on the value of mode, and appends the result to the messages list.
                messages.append(decrypt(message, shift))
    return messages

# This code defines a function called message_or_file.
def message_or_file():
    # This line calls the enter_message() function
    # to get the values of mode, message, filename, and shift.
    mode, message, filename, shift = enter_message()
    # This code returns the values of mode, message, filename, and shift as a tuple.
    return mode, message, filename, shift

# Define the main function to run the program
def main():
    # Calling welcome function
    # welcome()
    # ⬇This welcome is for using __doc__
    print(welcome.__doc__)
    # Set the conditional variable to True to start the while loop
    conditional = True
    # While loop to keep the program running until the user chooses to quit
    while conditional == True:
        # Call the message_or_file function to get the user's choice of message or file
        mode, message, filename, shift = message_or_file()
        # If the user chose to use a file, process the file and write the results to a new file
        if filename:
            messages = process_file(filename, mode, shift)
            write_messages(messages)

            #! this is for file
            # Ask the user if they want to encrypt or decrypt another message
            user_choice = input(
                "Would you like to encrypt or decrypt another message? (y/n)").lower()
            if (user_choice) == "n":
                conditional = False
                print("Thanks for using the program, goodbye!")

#
        # If the user chose to enter a message directly,
        # encrypt or decrypt the message and ask if they want to encrypt or decrypt another message
        else:
            # Encrypting the message based on the user's user_choice
            if mode == 'e':
                print("Encrypted Message:", encrypt(message, shift))

             # Decrypting the message based on the user's user_choice
            if mode == "d":
                print("Decrypted Message:", decrypt(message, shift))

          # Ask the user if they want to encrypt or decrypt another message
            #! this is for console message
            while True:
                user_user_choice = input(
                    "Would you like to encrypt or decrypt another message? (y/n): ").lower()
                if user_user_choice == "y":
                    break
                elif user_user_choice == "n":
                    print("Thanks for using the program, goodbye!")
                    return
                else:
                    print("Invalid Input")

main()


# -*- coding: utf-8 -*-
"""
Day 17 of Advent of Code 2020

Tom Kite - 17/12/2020
"""

from aoc_tools.advent_timer import Advent_Timer
from itertools import product

def readfile(filename):
    with open(filename, 'r') as file:
        lines = [line.strip() for line in file]
    return lines

def get_iteration_ranges(cube_locs):
    ranges = []
    for elem in cube_locs:
        break
    for i in range(len(elem)):
        ranges.append(range(min(cube_locs, key=lambda c: c[i])[i]-1,
                            max(cube_locs, key=lambda c: c[i])[i]+2))
    return ranges

def process_initial_layer(layer, dimensions):
    cube_locs = set()
    counts_dict = {}
    for j, row in enumerate(layer):
        for i, col in enumerate(row):
            if col == '#':
                coord = tuple([i, j] + [0]*(dimensions-2))
                cube_locs.add(coord)
                counts_dict = add_to_counts_dict(coord, counts_dict)
    return cube_locs, counts_dict

def add_to_counts_dict(coords_in, counts_dict):
    for coord in product(*get_iteration_ranges([coords_in])):
        if coords_in == coord:
            continue
        if coord not in counts_dict.keys():
            counts_dict[coord] = 1
        else:
            counts_dict[coord] += 1
    return counts_dict

def evolve_pocket_dim(cube_locs, counts_dict):
    new_cube_locs = set()
    new_counts_dict = {}
    ranges = get_iteration_ranges(cube_locs)

    for coord in product(*ranges):
        if coord in counts_dict.keys():
            count = counts_dict[coord]
        else:
            count = 0
        if coord in cube_locs:
            if count == 2 or count == 3:
                new_cube_locs.add(coord)
                new_counts_dict = \
                    add_to_counts_dict(coord, new_counts_dict)
        elif count == 3:
            new_cube_locs.add(coord)
            new_counts_dict = \
                add_to_counts_dict(coord, new_counts_dict)
    return new_cube_locs, new_counts_dict

def part1(filename):
    data = readfile(filename)
    cube_locs, counts_dict = process_initial_layer(data, 3)
    for _ in range(6):
        cube_locs, counts_dict = evolve_pocket_dim(cube_locs, counts_dict)
    print("After 6 cycles there are {} active cubes."
          .format(len(cube_locs)))
    return

def part2(filename):
    data = readfile(filename)
    cube_locs, counts_dict = process_initial_layer(data, 4)
    for i in range(6):
        cube_locs, counts_dict = evolve_pocket_dim(cube_locs, counts_dict)
    print("After 6 cycles there are {} active cubes."
          .format(len(cube_locs)))
    return

if __name__ == "__main__":
    timer = Advent_Timer()

    print("Part 1:")
    part1("../../data/day17.dat")
    timer.checkpoint_hit()

    print("\nPart 2:")
    part2("../../data/day17.dat")
    timer.checkpoint_hit()

    timer.end_hit()