import ldap
import ldif
import sys
import os
from lib389._constants import DIRSRV_STATE_ONLINE, DSRC_CONTAINER

MAJOR, MINOR, _, _, _ = sys.version_info

if MAJOR >= 3:
    import configparser
else:
    import ConfigParser as configparser

# Read the paths from default.inf

# Create a lazy eval class for paths. When we first access, we re-read
# the inf. This way, if we never request a path, we never need to read
# this file. IE remote installs, we shouldn't need to read this.

# Could this actually become a defaults module, and merge with instance/options?
# Would it handle the versioning requirements and diff we need?

DEFAULTS_PATH = [
    '/usr/share/dirsrv/inf/defaults.inf',
    '/usr/local/share/dirsrv/inf/defaults.inf',
    '/opt/dirsrv/share/dirsrv/inf/defaults.inf',
    '/opt/local/share/dirsrv/inf/defaults.inf',
    '/opt/share/dirsrv/inf/defaults.inf',
]

MUST = [
    'product',
    'version',
    'user',
    'group',
    'root_dn',
    'prefix',
    'bin_dir',
    'sbin_dir',
    'lib_dir',
    'data_dir',
    'tmp_dir',
    'sysconf_dir',
    'config_dir',
    'schema_dir',
    'cert_dir',
    'local_state_dir',
    'run_dir',
    'lock_dir',
    'log_dir',
    'inst_dir',
    'db_dir',
    'db_home_dir',
    'backup_dir',
    'ldif_dir',
    'initconfig_dir',
    'tmpfiles_d',
]

# will need to add the access, error, audit log later.

# This maps a config to (entry, attr).
# This can be used online, or while the server is offline and we can parse dse.ldif

CONFIG_MAP = {
    'user' : ('cn=config', 'nsslapd-localuser'),
    'group' : ('cn=config','nsslapd-localuser'), # Is this correct?
    'schema_dir' : ('cn=config','nsslapd-schemadir'),
    'cert_dir' : ('cn=config','nsslapd-certdir'),
    'lock_dir' : ('cn=config','nsslapd-lockdir'),
    'inst_dir' : ('cn=config','nsslapd-instancedir'),
    'db_dir' : ('cn=config,cn=ldbm database,cn=plugins,cn=config', 'nsslapd-directory'),
    'db_home_dir' : ('cn=bdb,cn=config,cn=ldbm database,cn=plugins,cn=config', 'nsslapd-db-home-directory'),
    'backup_dir': ('cn=config','nsslapd-bakdir'),
    'ldif_dir': ('cn=config','nsslapd-ldifdir'),
    'error_log' : ('cn=config', 'nsslapd-errorlog'),
    'access_log' : ('cn=config', 'nsslapd-accesslog'),
    'audit_log' : ('cn=config', 'nsslapd-auditlog'),
    'security_log' : ('cn=config', 'nsslapd-securitylog'),
    'ldapi': ('cn=config', 'nsslapd-ldapifilepath'),
    'version': ('', 'vendorVersion'),
}

#Alternate map if attribute is not found in CONFIG_MAP

CONFIG_MAP2 = {
    'db_home_dir' : ('cn=config,cn=ldbm database,cn=plugins,cn=config', 'nsslapd-db-home-directory'),
}

DSE_MAP = {
    'nsslapd-bakdir': 'backup_dir',
    'nsslapd-schemadir': 'schema_dir',
    'nsslapd-certdir': 'cert_dir',
    'nsslapd-lockdir': 'lock_dir',
    'nsslapd-ldifdir': 'ldif_dir',
    'nsslapd-bakdir': 'backup_dir',
    'nsslapd-errorlog': 'error_log',
    'nsslapd-accesslog': 'access_log',
    'nsslapd-auditlog': 'audit_log',
    'nsslapd-securitylog': 'security_log',
    'nsslapd-ldapifilepath': 'ldapi',
    'nsslapd-instancedir': 'inst_dir',
}

SECTION = 'slapd'

class Paths(object):
    def __init__(self, serverid=None, instance=None, local=True):
        """
        Parses and uses a set of default paths from wellknown locations. The list
        of keys available is from the MUST attribute in this module.

        To use this module:

        p = Paths()
        p.bindir

        If the defaults.inf is NOT in a wellknown path, this will throw IOError
        on the first attribute access. If this does not have a value defaults.inf
        it will raise KeyError that the defaults.inf is not capable of supporting
        this tool.

        This is lazy evaluated, so the file is read at the "last minute" then
        the contents are cached. This means that remote tools that don't need
        to know about paths, shouldn't need to have a copy of 389-ds-base
        installed to remotely admin a server.
        """
        self._is_container = os.path.exists(DSRC_CONTAINER)
        self._defaults_cached = False
        self._config = None
        self._serverid = serverid
        self._instance = instance
        self._islocal = local

    def _get_defaults_loc(self, search_paths):
        ## THIS IS HOW WE HANDLE A PREFIX INSTALL
        prefix = os.getenv('PREFIX')
        # When we run 389-ds in Ansible, its processing sets PREFIX to "", so we should check for both - None and ""
        if prefix:
            spath = os.path.join(prefix, 'share/dirsrv/inf/defaults.inf')
            if os.path.isfile(spath):
                return spath
            else:
                raise IOError('defaults.inf not found in prefixed location %s' % spath)
        for spath in search_paths:
            if os.path.isfile(spath):
                return spath
        raise IOError('defaults.inf not found in any well known location!')

    def _read_defaults(self):
        spath = self._get_defaults_loc(DEFAULTS_PATH)
        self._config = configparser.ConfigParser()
        self._config.read([spath])
        if self._is_container:
            # Load some values over the top that are container specific
            self._config.set(SECTION, "pid_file", "/data/run/slapd-localhost.pid")
            self._config.set(SECTION, "ldapi", "/data/run/slapd-localhost.socket")
        self._defaults_cached = True

        # Now check the dse.ldif (if present) to see if custom paths were set
        if self._serverid:
            # Get the dse.ldif from the instance name
            prefix = os.environ.get('PREFIX', ""),
            if self._serverid.startswith("slapd-"):
                self._serverid = self._serverid.replace("slapd-", "", 1)
            dsepath = "{}/etc/dirsrv/slapd-{}/dse.ldif".format(prefix[0], self._serverid)
        elif self._instance is not None:
            ds_paths = Paths(self._instance.serverid, None)
            dsepath = os.path.join(ds_paths.config_dir, 'dse.ldif')
        else:
            # Nothing else to do but return
            return

        try:
            from lib389.utils import ensure_str  # prevents circular import errors
            with open(dsepath, 'r') as file_dse:
                dse_parser = ldif.LDIFRecordList(file_dse, max_entries=2)
                if dse_parser is None:
                    return
                dse_parser.parse()
                if dse_parser.all_records is None:
                    return
                # We have the config, start processing the DSE_MAP
                config = dse_parser.all_records[1]  # cn=config
                attrs = config[1]
                for attr in DSE_MAP.keys():
                    if attr in attrs.keys():
                        self._config.set(SECTION, DSE_MAP[attr], ensure_str(attrs[attr][0]))
        except:
            # No dse.ldif or can't read it, no problem just skip it
            pass

    def _validate_defaults(self):
        if self._defaults_cached is False:
            return False
        for k in MUST:
            if self._config.has_option(SECTION, k) is False:
                raise KeyError('Invalid defaults.inf, missing key %s' % k)
        return True

    def _pretty_exception(self, err, msg):
        # Remap LDAPError exceptions to get a nicer stack than python-ldap one
        # Lets grab the data from the exception (a bit painfull but I did not find any better way)
        result = None
        desc = None
        info = None
        for e in err.args:
            if "result" in e:
                result = e["result"]
            if "desc" in e:
                desc = e["desc"]
            if "info" in e:
                info = e["info"]
        if result is None or desc is None:
            # keep original exception in unusual cases
            return (err)
        # Lets create a new exception (with same class) to have current stack without the python-ldap internal stack
        # And to provide more relevant info that are useful for debug
        info = f"{msg}.\nAdditionnal info is: {info}"
        return (err.__class__({ "result":result, "desc":desc, "info":info}))

    def __getattr__(self, name):
        from lib389.utils import ensure_str
        if self._defaults_cached is False and self._islocal:
            self._read_defaults()
            self._validate_defaults()
        # Are we online? Is our key in the config map?
        while name in CONFIG_MAP and self._instance is not None and self._instance.state == DIRSRV_STATE_ONLINE:
            # Get the online value.
            err = None
            try:
                (dn, attr) = CONFIG_MAP[name]
                ent = self._instance.getEntry(dn, attrlist=[attr,])
            except ldap.LDAPError as e:
                err = e
            if isinstance(err, ldap.NO_SUCH_OBJECT) and name in CONFIG_MAP2:
                try:
                    (dn, attr) = CONFIG_MAP2[name]
                    ent = self._instance.getEntry(dn, attrlist=[attr,])
                    err = None
                except ldap.LDAPError as e:
                    err = e
            if isinstance(err, ldap.SERVER_DOWN):
                # Search in config.
                break
            if err is not None:
                raise self._pretty_exception(err, f"while searching attribute {attr} in entry {dn} on server {self.serverid}")
            # If the server doesn't have it, fall back to our configuration.
            if attr is not None:
                v = ensure_str(ent.getValue(attr))
            else:
                v = None
            # Do we need to post-process the value?
            if name == 'version' and v is not None:
                # We need to post process this - it's 389-Directory/1.4.2.2.20191031git8166d8345 B2019.304.19
                # but we need a string like: 1.4.2.2.20191031git8166d8345
                v = v.split('/')[1].split()[0]
            return v
        # Else get from the config
        if self._config:
            if self._serverid is not None:
                return ensure_str(self._config.get(SECTION, name).format(instance_name=self._serverid))
            else:
                return ensure_str(self._config.get(SECTION, name))
        else:
            raise LookupError("""Invalid state
No paths config (defaults.inf) could be found.
This may be because the remote instance is offline, or your /etc/hosts is misconfigured for a local instance
""")

    @property
    def asan_enabled(self):
        if self._defaults_cached is False and self._islocal:
            self._read_defaults()
            self._validate_defaults()
        if self._config and self._config.has_option(SECTION, 'asan_enabled'):
            if self._config.get(SECTION, 'asan_enabled') == '1':
                return True
        return False

    @property
    def with_systemd(self):
        if self._defaults_cached is False and self._islocal:
            self._read_defaults()
            self._validate_defaults()
        if self._is_container:
            # We never have systemd in a container, so check the marker.
            return False
        if self._config and self._config.has_option(SECTION, 'with_systemd'):
            if self._config.get(SECTION, 'with_systemd') == '1':
                return True
        return False

    @property
    def rust_enabled(self):
        if self._defaults_cached is False:
            self._read_defaults()
            self._validate_defaults()
        if self._config and self._config.has_option(SECTION, 'enable_rust'):
            if self._config.get(SECTION, 'enable_rust') == 'no':
                return False
        return True


# -*-encoding:utf-8-*-
__author__ = 'Max'

import threading
import time
import datetime
import logging
import os
import sys
import json
import sched
import random

from simhash import Simhash
from py4j.java_gateway import JavaGateway
from classify import Classifier
from push import Pusher
import utils

reload(sys)
sys.setdefaultencoding('utf-8')

class Controller(threading.Thread):
    def __init__(self, thread_name, event):
        super(Controller, self).__init__()
        self.name = thread_name
        self.threadEvent = event
        self.logger_info = utils.initlog('Console', 'Console.log')
        self.schedule = sched.scheduler(time.time, time.sleep)

        self.profiles_name, profiles = utils.load_profiles('profiles')
        self.related_tweets = [[] for _ in range(len(profiles))]    # 当天相关推文记录，存储共离线分析
        self.pushed_tweets = [[] for _ in range(len(profiles))]
        self.pushed_tweets_ids = set([])
        self.related_tweets_hash = set([])

        self.classifier = Classifier()
        self.ranker = self.load_ranker()
        self.pusher = Pusher()

    def load_ranker(self):
        self.logger_info.info('loading ranker...')
        gateway = JavaGateway()
        ranker = gateway.entry_point
        self.logger_info.info('ranker loaded!')
        return ranker

    def run(self):
        self.logger_info.info('%s is starting...' % self.name)
        self.threadEvent.wait()
        self.logger_info.info('%s is running...' % self.name)
        # self.schedule.enter(0, 0, self.dump_schedule, ())
        # self.schedule.run()
        self.process()

    def process(self):
        data_file_path = sys.argv[1]
        files = os.listdir(data_file_path)
        files.sort()
        for f in files:
            filename = os.path.join(data_file_path, f)
            logging.info(filename)
            count = 0
            for line in open(filename, 'rb'):
                start = time.clock()
                tweet_text, tid_origin, tid_retweet, timestamp, tweet_json = utils.extract_text(line)
                simhash_value = Simhash(tweet_text).value
                if simhash_value in self.related_tweets_hash or tid_origin in self.pushed_tweets_ids or tid_retweet in self.pushed_tweets_ids:
                    continue

                topic_id, similarity = self.classifier.classify(tweet_text)
                if topic_id == '':
                    continue

                count += 1
                if count % 10000 == 0:  logging.info('%d' % count)

                tweet_json['similarity'] = similarity
                evaluate_score = self.ranker.predict(json.dumps(tweet_json))
                total_score = (evaluate_score ** 0.5) * similarity
                # if total_score < 0.15:
                #     continue

                timestruct = time.gmtime(int(timestamp[:-3]))
                is_pushed = self.pusher.push(total_score, topic_id, timestruct)
                if is_pushed:
                    delivery_time = float(timestamp) / 1000.0 + (time.clock() - start)
                    self.pushed_tweets[topic_id].append([tid_origin, str(delivery_time)[:10], similarity, total_score, tweet_text])

                utc_time = time.strftime('%Y%m%d', timestruct)
                self.related_tweets[topic_id].append([utc_time, tid_origin, total_score, tid_retweet, timestamp[:-3], tweet_text])

                self.related_tweets_hash.add(simhash_value)
                self.pushed_tweets_ids.add(tid_retweet)
            self.dump_result(f)
            self.pusher = Pusher()
        self.logger_info.info('\n=======finished!=======\n')

    def dump_result(self, file_name):
        self.logger_info.info('saving result...')
        with open('submit/task-b/b_submit', 'a') as fw:
            with open('submit/task-b/b_review/B_candidateday_' + file_name[-2:], 'w') as fw_review:
                for index, records in enumerate(self.related_tweets):
                    pid = str(index+226)
                    sorted_records = sorted(records, key=lambda item: -item[2])
                    for rank, record in enumerate(sorted_records):
                        if rank >= 100:
                            break
                        fw.write('%s\tMB%s\tQ0\t%s\t%d\t%f\t%s\n' % (record[0], pid, record[1], rank+1, record[2], 'CSSNA'))
                        fw_review.write('%s\tMB%s\tQ0\t%s\t%f\tSNACS\t%s\t%s\t%s\n' % (record[0], pid, record[1], record[2], record[3], record[4], record[5]))

        with open('submit/task-a/a_submit', 'a') as fw:
            with open('submit/task-a/a_review', 'a') as fw_review:
                for index, records in enumerate(self.pushed_tweets):
                    pid = str(index+226)
                    for record in records:
                        fw.write('MB%s\t%s\t%s\tCSSNA\n' % (pid, record[0], record[1]))
                        fw_review.write('MB%s\t%s\t%s\tCSSNA\t%s\t%s\t%s\n' % (pid, record[0], record[1], record[2], record[3], record[4]))

        self.related_tweets = [[] for _ in range(225)]    # 清空前天相关推文记录
        self.pushed_tweets = [[] for _ in range(225)]

    def dump_schedule(self):
        self.logger_info.info('saving result...')
        utc_time = time.strftime('%Y%m%d', time.gmtime())
        for index, records in self.related_tweets:
            pid = str(index+226)
            with open('profile_MB' + pid, 'w') as fw:
                for record in records:
                    fw.write(utc_time + '\t' + pid + '\tQ0\t' + record + '\n')
        self.related_tweets = [[] for _ in range(226)]    # 清空前天相关推文记录
        self.schedule.enter(24*60*60, 0, self.dump_schedule, ())

    def detect_tweet_stream(self, year, month, d, h, m, s, ms):
        start = datetime.datetime(year, month, d, h, m, s, ms)
        delta = (start - datetime.datetime.now()).seconds
        self.logger_info.info('waiting secondes: ' + str(delta))
        time.sleep(delta)
        self.logger_info.info('tweet stream is ready')
        is_ready = True
        return is_ready

def test():
    signal = threading.Event()
    controller = Controller("online-task", signal)
    controller.start()
    # is_ready = detect_tweet_stream(2015, 7, 28, 20, 0, 0, 0)
    is_ready = True
    if is_ready:
        signal.set()

if __name__ == '__main__':
    '''
    parser = optparse.OptionParser()
    parser.add_option("-m", dest="model", help="word2vec model")
    parser.add_option("-p", dest="profiles", help="user profiles")

    (options, args) = parser.parse_args()
    if not options.model: parser.error("need word2vec models (-m)")
    '''
    test()


#!/usr/bin/env python3

import gertbot as gb
import time
import sys

board = 0

def loco_speed(address=0, speed=0, emergency_stop=False, forward=True, lights=False):
    ret = 0x40 | (forward << 5) | (lights << 4)
    if emergency_stop:
        ret |= 0x01
        return [address, ret]
    if speed == 0:
        return [address, ret]
    elif speed <= 14:
        ret = ret+speed+1
        return [address, ret]
    else:
        return [address, ret]

def loco_functions_1(address=0, lights=False, f1=False, f2=False, f3=False, f4=False):
    ret = 0x80 | (lights << 4) | (f4 << 3) | (f3 << 2) | (f2 << 1) | (f1)
    return [address, ret]

def loco_functions_2(address=0, f5=False, f6=False, f7=False, f8=False):
    ret = 0xB0 | (f8 << 3) | (f7 << 2) | (f6 << 1) | (f5)
    return [address, ret]

def loco_functions_3(address=0, f9=False, f10=False, f11=False, f12=False):
    ret = 0xA0 | (f12 << 3) | (f11 << 2) | (f10 << 1) | (f9)
    return [address, ret]

def loco_functions_4(address=0, f13=False, f14=False, f15=False, f16=False, f17=False, f18=False, f19=False, f20=False):
    ret1 = 0xDE
    ret2 = (f20 << 7) | (f19 << 6) | (f18 << 5) | (f17 << 4) | (f16 << 3) | (f15 << 2) | (f14 << 1) | (f13)
    return [address, ret1, ret2]

gb.open_uart(0)
#gb.set_mode(board, channel, mode)
gb.set_mode(board, 0, gb.MODE_DCC)

gb.send_dcc_mess(board, 0xF, loco_speed(address=47))
gb.send_dcc_mess(board, 0xF, loco_functions_1(address=47, lights=True, f1=True))
time.sleep(15)
gb.send_dcc_mess(board, 0xF, loco_functions_1(address=47, lights=True, f1=True, f2=True))
gb.send_dcc_mess(board, 0xF, loco_functions_1(address=47, lights=True, f1=True))
time.sleep(5)
for i in range(0,9):
    gb.send_dcc_mess(board, 0xF, loco_speed(address=47, speed=i, lights=True))
    time.sleep(1)
time.sleep(5)
for i in range(0,9):
    gb.send_dcc_mess(board, 0xF, loco_speed(address=47, speed=8-i, lights=True))
    time.sleep(1)
time.sleep(3)
gb.send_dcc_mess(board, 0xF, loco_speed(address=47, speed=7, forward=False, lights=True))
time.sleep(15)
gb.send_dcc_mess(board, 0xF, loco_speed(address=47, speed=0, forward=False, lights=True))
time.sleep(12)
gb.send_dcc_mess(board, 0xF, loco_functions_1(address=47, lights=True))
time.sleep(3)
gb.send_dcc_mess(board, 0xF, loco_functions_1(address=47))


# classifier.py
#
# This module contains code to support the classifier notebook

import numpy as np
import pylab as plt

def p_correct_given_pos(sens, fpr, b):
    """ Returns a simple Bayesian probability for the probability
        that a prediction is correct, given that the prediction
        was positive, given the prevailing sensitivity (sens),
        false positive rate (fpr) and base rate of positive
        examples.
    """
    assert 0 <= sens <= 1, "Sensitivity must be in range [0,1]"
    assert 0 <= fpr <= 1, "FPR must be in range [0,1]"
    return sens * b / (sens * b + fpr * (1 - b))

def plot_prob_effector(sens=0.85, fpr=0.17, baserate=0.1, xmax=1):
    """ Plots a line graph of P(effector|positive test) against
        the baserate of effectors in the input set to the classifier.

        The baserate argument draws an annotation arrow
        indicating P(pos|+ve) at that baserate
    """
    assert 0.1 <= xmax <= 1, "Max x axis value must be in range [0,1]"
    assert 0.01 <= baserate <= 1, "Baserate annotation must be in range [0,1]"
    baserates = np.arange(0, 1.05,
                          xmax * 0.005)  # Range of +ve example base rate
    probs = [p_correct_given_pos(sens, fpr, b) for b in baserates]
    plt.figure(figsize=(10, 6))
    plt.plot(baserates, probs, 'r')
    plt.title("P(eff|pos) vs baserate; sens: %.2f, fpr: %.2f" % (sens, fpr))
    plt.ylabel("P(effector|positive)")
    plt.xlabel("effector baserate")
    plt.xlim(0, xmax)
    plt.ylim(0, 1)
    # Add annotation arrow
    xpos, ypos = (baserate, p_correct_given_pos(sens, fpr, baserate))
    if baserate < xmax:
        if xpos > 0.7 * xmax:
            xtextpos = 0.05 * xmax
        else:
            xtextpos = xpos + (xmax-xpos)/5.
        if ypos > 0.5:
            ytextpos = ypos - 0.05
        else:
            ytextpos = ypos + 0.05
        plt.annotate('baserate: %.2f, P(pos|+ve): %.3f' % (xpos, ypos),
                     xy=(xpos, ypos),
                     xytext=(xtextpos, ytextpos),
                     arrowprops=dict(facecolor='black', shrink=0.05))
    else:
        plt.text(0.05 * xmax, 0.95, 'baserate: %.2f, P(pos|+ve): %.3f' %
                 (xpos, ypos))
    plt.show()


"""
    You are provided with a list of names. Write a program to  rearrange them so that persons with the same surname are adjacent. Each item in the list will contain first name, middle name(optional), and surname, separated by space, the last word will be the surname.

    Example:
    "input": ["Pratik Thapa", "Hari Kumar Karki", "Shyam Govind Sharma", "Wilson Karki", "Baladev Thapa"]
    "output": ["Pratik Thapa", "Baladev Thapa", "Hari kumar Karki", "Gopal Karki", "Shyam Govind Sharma"]

"""

import unittest

"""
    The given list
"""
list = ["Pratik Thapa", "Hari Kumar Karki", "Shyam Govind Sharma", "Wilson Karki", "Baladev Thapa"]

print("The given list is:\n",list)

"""
    Divide the string names into list names and sort the array
"""
def divide_sort(list):
    value_list = []
    def sort_key(name):
        return name[len(name)-1]
    for i in list:
        value = i.lower().split()
        value_list.append(value)

    value_list.sort(key=sort_key,reverse=True)
    return value_list
"""
    Combine the array names into string after sorting
"""
def combine_name(value_list):
    return [' '.join(i).title() for i in value_list]

sorted_list = combine_name(divide_sort(list))
print("The output is:\n",sorted_list)

"""
    Testing
"""
class LearnTest(unittest.TestCase):
    def test_main_function(self):
        list = ["Pratik Thapa", "Hari Kumar Karki", "Shyam Govind Sharma", "Wilson Karki", "Baladev Thapa"]
        self.assertEqual(combine_name(divide_sort(list)),['Pratik Thapa', 'Baladev Thapa', 'Shyam Govind Sharma', 'Hari Kumar Karki', 'Wilson Karki'])
if __name__ == "__main__":
    unittest.main()


from transformers import BertTokenizer
from transformers import BertModel
from torch.nn import Softmax
import torch
import matplotlib.pyplot as plt

# 设计思想, 高计算量操作尽量减少, 对齐问题解决思路要清晰
# 一次句子分析, 多个函数共享
# 统一用torch.tensor表征所有容器

tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertModel.from_pretrained('bert-base-uncased')

class sent_analyzer:
	def __init__(self, sent):
		self.raw_text = sent.strip() # str
		self.space_tokenization = sent.split(sep=' ')  # [str, str]
		self.raw_text_lower = self.raw_text.lower() # str
		self.space_tokenization_lower = [i.lower() for i in self.space_tokenization] # [str, str]
		self.bert_tokenization_obj = tokenizer(self.raw_text_lower, return_tensors='pt') # {key:tensor, key:tensor}
		self.bert_tokenization_ids = self.bert_tokenization_obj['input_ids'][0].tolist() # [int, int]
		self.bert_tokenization_wordpieces = tokenizer.convert_ids_to_tokens(self.bert_tokenization_ids)  # [str,str]
		self.bert_tokenization_wordpieces_nosep = self.bert_tokenization_wordpieces[1:-1] # [str, str]
		self.bert_tokenization_ids_nosep = self.bert_tokenization_ids[1:-1] # [int, int]
		self.bert_model_return = model(**self.bert_tokenization_obj, output_hidden_states=True, output_attentions=True) # (tensor, tensor, tuple, typle) # (last_hidden_state, pooler_output, hidden_states, attentions)
		self.bert_last_hidden_state = self.bert_model_return[0].squeeze() # tensor
		self.bert_hidden_states = torch.stack(self.bert_model_return[2][1:],axis=0).squeeze() # tensor
		self.bert_attentions = torch.stack(self.bert_model_return[3],axis=0).squeeze() # tensor
		self.bert_attentions_nosep = self.bert_attentions[:,:,1:-1,1:-1] # tensor
		self.bert_attentions_nosep_linscale = self.bert_attentions_nosep/self.bert_attentions_nosep.sum(axis=-1).unsqueeze(-1) # tensor
		self.bert_attentions_nosep_softmaxscale = Softmax(dim=-1)(self.bert_attentions_nosep) # tensor
		self.space_wordpiece_posmap = self.wordpiece_mapping(self.space_tokenization_lower) # {int:[int,int], int:[int,int]}
		self.reduced_attention = self.reduced_attention_nosep_linscale(self.space_tokenization_lower) # tensor

	def wordpiece_mapping(self,target_tokens):
		'''[int,int]'''
		ud_sent = target_tokens
		wp_sent = self.bert_tokenization_wordpieces_nosep
		ud_cnt = 0
		wp_cnt = 0
		wp_buffer = []
		idmap_list = []
		while True:
			try:
				ud_pop = ud_sent[ud_cnt]
				wp_pop = wp_sent[wp_cnt]
				if ud_pop == wp_pop:
					idmap_list.append(ud_cnt)
					ud_cnt += 1
					wp_cnt += 1
				else:
					wp_buffer.append(wp_pop.replace('##',''))
					idmap_list.append(ud_cnt)
					if ''.join(wp_buffer) != ud_pop:
						wp_cnt += 1
					else:
						wp_cnt += 1
						ud_cnt += 1
						wp_buffer = []
			except IndexError:
				break
		idmap_dict = dict()
		for i in range(max(idmap_list)+1):
			idmap_dict[i] = [idx for idx,j in enumerate(idmap_list) if j==i]
		return idmap_dict

	def reduced_attention_nosep_linscale(self,target_tokens):
		posmap = self.wordpiece_mapping(self.space_tokenization_lower)
		num_rows = len(posmap.keys())
		num_cols = sum([len(posmap[x]) for x in posmap if isinstance(posmap[x], list)])
		row_reduced_attention = torch.empty(12,12,num_rows,num_cols)
		row_col_reduced_attention = torch.empty(12,12,num_rows,num_rows)
		for lay in range(12):
			for head in range(12):
				for pair in posmap.items():
					row_reduced_attention[lay][head][pair[0]] = (torch.index_select(self.bert_attentions_nosep_linscale[lay][head], -2, torch.tensor(pair[1])).sum(axis=-2))/len(pair[1])
		for lay in range(12):
			for head in range(12):
				for pair in posmap.items():
					row_col_reduced_attention[lay][head][:,pair[0]] = torch.index_select(row_reduced_attention[lay][head], -1, torch.tensor(pair[1])).sum(axis=-1)
		return row_col_reduced_attention

	def viz_bert_attentions(self,lay,head):
		fig = plt.figure()
		ax = fig.subplots()
		data = self.bert_attentions[lay][head].detach().numpy()
		gcf = ax.matshow(data,cmap='Greens')
		ax.set_xticks(range(data.shape[0]))
		ax.set_yticks(range(data.shape[1]))
		xticklabels = [str(i)+' '+j for i,j in zip(range(data.shape[0]), self.bert_tokenization_wordpieces)]
		yticklabels = [j+' '+str(i) for i,j in zip(range(data.shape[0]), self.bert_tokenization_wordpieces)]
		ax.set_xticklabels(xticklabels,rotation=45, ha='left')
		ax.set_yticklabels(yticklabels)
		ax.set_xlabel(f'Layer-{lay+1}, Head-{head+1}')
		bar = plt.gcf().colorbar(gcf)
		plt.show()
		plt.close()
		return

	def viz_bert_attentions_nosep_linscale(self,lay,head):
		fig = plt.figure()
		ax = fig.subplots()
		data = self.bert_attentions_nosep_linscale[lay][head].detach().numpy()
		gcf = ax.matshow(data,cmap='Greens')
		ax.set_xticks(range(data.shape[0]))
		ax.set_yticks(range(data.shape[1]))
		ax.set_xticklabels([str(i)+' '+j for i,j in zip(range(data.shape[0]), self.bert_tokenization_wordpieces_nosep)], rotation=45)
		ax.set_yticklabels([j+' '+str(i) for i,j in zip(range(data.shape[0]), self.bert_tokenization_wordpieces_nosep)])
		bar = plt.gcf().colorbar(gcf)
		plt.show()
		plt.close()
		return

	def viz_bert_attentions_nosep_softmaxscale(self,lay,head):
		fig = plt.figure()
		ax = fig.subplots()
		data = self.bert_attentions_nosep_softmaxscale[lay][head].detach().numpy()
		gcf = ax.matshow(data,cmap='Greens')
		ax.set_xticks(range(data.shape[0]))
		ax.set_yticks(range(data.shape[1]))
		ax.set_xticklabels([str(i)+' '+j for i,j in zip(range(data.shape[0]), self.bert_tokenization_wordpieces_nosep)], rotation=45)
		ax.set_yticklabels([j+' '+str(i) for i,j in zip(range(data.shape[0]), self.bert_tokenization_wordpieces_nosep)])
		bar = plt.gcf().colorbar(gcf)
		plt.show()
		plt.close()
		return

	def viz_bert_attentions_nosep_linscale_reduced(self,lay,head):
		fig = plt.figure()
		ax = fig.subplots()
		data = self.reduced_attention[lay][head].detach().numpy()
		gcf = ax.matshow(data,cmap='Greens')
		ax.set_xticks(range(data.shape[0]))
		ax.set_yticks(range(data.shape[1]))
		ax.set_xticklabels([str(i)+' '+j for i,j in zip(range(data.shape[0]), self.space_tokenization)], rotation=45)
		ax.set_yticklabels([j+' '+str(i) for i,j in zip(range(data.shape[0]), self.space_tokenization)])
		bar = plt.gcf().colorbar(gcf)
		plt.show()
		plt.close()

sent = 'mary had a little lamb, its fleece was white as snow'

sent_obj = sent_analyzer(sent)

print('done')


# !pip3 install dit
# !pip3 install pyinform
# import dask_ml.model_selection as dcv
# from skopt import BayesSearchCV
# from skopt.space import Real, Categorical, Integer
# from hyperopt import hp,fmin,tpe,STATUS_OK,Trials
# import EEGExtract as eeg
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score
from sklearn.decomposition import PCA
from sklearn.feature_selection import chi2
from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
from sklearn.feature_selection import *
from sklearn.model_selection import RandomizedSearchCV
from sklearn.model_selection import GridSearchCV
# from sklearn.ensemble import RandomForestRegressor
# import xgboost as xgb
import sys
import csv
import os
import math
import glob
from scipy import io,signal
import numpy as np
import pandas as pd

import pickle
from sklearn.metrics import mean_squared_error
from sklearn.impute import SimpleImputer

import matplotlib.pyplot as plt
# %matplotlib inline
import seaborn as sns
import copy
from sklearn import feature_selection
# from sklearn.ensemble import RandomForestClassifier
import argparse

# import cuml
# from cuml.svm import SVR
# from cuml.ensemble import RandomForestRegressor
# from cuml.svm import SVC
# from cuml.ensemble import RandomForestClassifier
# from cuml.metrics import  accuracy_score

#Import Machine Learning Algorithms
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from xgboost import XGBRegressor
from sklearn.neighbors import KNeighborsRegressor
from sklearn.svm import SVR
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
from sklearn.model_selection import RepeatedKFold
from sklearn.model_selection import GridSearchCV

# import joblib
# sys.modules['sklearn.externals.joblib'] = joblib

def loadFeaturesDict(dataset):
    featuresDict = {'shannonEntropy': None,
                'ShannonRes_delta':None,
                'ShannonRes_theta':None,
                'ShannonRes_alpha':None,
                'ShannonRes_beta':None,
                'ShannonRes_gamma':None,
                'HjorthComp':None,
                'HjorthMob':None,
                'falseNearestNeighbor':None,
                'medianFreq':None,
                'bandPwr_delta':None,
                'bandPwr_theta':None,
                'bandPwr_alpha':None,
                'bandPwr_beta':None,
                'bandPwr_gamma':None,
                'stdDev':None,
                'diffuseSlowing':None,
                'spikeNum':None,
                'deltaBurstAfterSpike':None,
                'shortSpikeNum':None,
                'numBursts':None,
                'burstLenMean':None,
                'burstLenStd':None,
                'numSuppressions':None,
                'suppLenMean':None,
                'suppLenStd':None,
                'dasm_delta': None,
                'dasm_theta': None,
                'dasm_alpha': None,
                'dasm_beta': None,
                'dasm_gamma': None,
                'rasm_delta': None,
                'rasm_theta': None,
                'rasm_alpha': None,
                'rasm_beta': None,
                'rasm_gamma': None,
                }

    # featurepath = os.getcwd() + '/' + dataset + '/data_extracted/featuresDict/'
    featurepath = os.getcwd() + '/Features/' + dataset + '/' #change

    featuresDict['shannonEntropy'] = np.load(featurepath + "shannonEntropy_1_1.npz", allow_pickle=True)['features']

    featuresDict['ShannonRes_delta'] = np.load(featurepath + "ShannonRes_sub_bands_delta_1_1.npz", allow_pickle=True)['features']

    featuresDict['ShannonRes_theta'] = np.load(featurepath + "ShannonRes_sub_bands_theta_1_1.npz", allow_pickle=True)['features']

    featuresDict['ShannonRes_alpha'] = np.load(featurepath + "ShannonRes_sub_bands_alpha_1_1.npz", allow_pickle=True)['features']

    featuresDict['ShannonRes_beta'] = np.load(featurepath + "ShannonRes_sub_bands_beta_1_1.npz", allow_pickle=True)['features']

    featuresDict['ShannonRes_gamma'] = np.load(featurepath + "ShannonRes_sub_bands_gamma_1_1.npz", allow_pickle=True)['features']

    #lyapunov
    # featuresDict['hFD'] = np.load(featurepath + d/DEAP_hFD.npy",allow_pickle=True)['features']

    featuresDict['HjorthComp'] = np.load(featurepath + "Hjorth_complexity_1_1.npz", allow_pickle=True)['features']

    featuresDict['HjorthMob'] = np.load(featurepath + "Hjorth_mobilty_1_1.npz",allow_pickle=True)['features']

    featuresDict['falseNearestNeighbor'] = np.load(featurepath + "falseNearestNeighbor_1_1.npz",allow_pickle=True)['features']

    featuresDict['medianFreq'] = np.load(featurepath + "medianFreq_1_1.npz",allow_pickle=True)['features']

    featuresDict['bandPwr_delta']=np.load(featurepath+"bandPwr_delta_1_1.npz", allow_pickle = True)['features']

    featuresDict['bandPwr_theta']=np.load(featurepath + "bandPwr_theta_1_1.npz", allow_pickle = True)['features']

    featuresDict['bandPwr_alpha']=np.load(featurepath + "bandPwr_alpha_1_1.npz", allow_pickle = True)['features']

    featuresDict['bandPwr_beta']=np.load(featurepath + "bandPwr_beta_1_1.npz", allow_pickle = True)['features']

    featuresDict['bandPwr_gamma']=np.load(featurepath + "bandPwr_gamma_1_1.npz", allow_pickle = True)['features']

    featuresDict['stdDev'] = np.load(featurepath + "stdDev_1_1.npz",allow_pickle=True)['features']

    # featuresDict['regularity'] = np.load(featurepath + "",allow_pickle=True)['features']

    # featuresDict['volt05'] = np.load(featurepath + "",allow_pickle=True)['features']
    # featuresDict['volt10'] = np.load(featurepath + "",allow_pickle=True)['features']
    # featuresDict['volt20'] = np.load(featurepath + "",allow_pickle=True)['features']

    featuresDict['diffuseSlowing'] = np.load(featurepath + "diffuseSlowing_1_1.npz",allow_pickle=True)['features']

    featuresDict['spikeNum'] = np.load(featurepath + "spikeNum_1_1.npz",allow_pickle=True)['features']

    featuresDict['deltaBurstAfterSpike'] = np.load(featurepath + "deltaBurstAfterSpike_1_1.npz",allow_pickle=True)['features']

    featuresDict['shortSpikeNum'] = np.load(featurepath + "shortSpikeNum_1_1.npz", allow_pickle=True)['features']

    featuresDict['numBursts'] = np.load(featurepath + "numBursts_1_1.npz",allow_pickle=True)['features']

    featuresDict['burstLenMean'] = np.load(featurepath + "burstLen_u_and_sigma_mean_1_1.npz",allow_pickle=True)['features']

    featuresDict['burstLenStd'] = np.load(featurepath + "burstLen_u_and_sigma_std_1_1.npz",allow_pickle=True)['features']

    # featuresDict['burstBandPowers'] = np.load(featurepath + "",allow_pickle=True)['features']

    featuresDict['numSuppressions'] = np.load(featurepath + "numSuppressions_1_1.npz",allow_pickle=True)['features']

    featuresDict['suppLenMean'] = np.load(featurepath + "suppressionLen_u_and_sigma_mean_1_1.npz",allow_pickle=True)['features']

    featuresDict['suppLenStd'] = np.load(featurepath + "suppressionLen_u_and_sigma_std_1_1.npz",allow_pickle=True)['features']

    featuresDict['dasm_delta'] = np.load(featurepath + "dasm_delta_1_1.npz",allow_pickle=True)['features']
    featuresDict['dasm_theta'] = np.load(featurepath + "dasm_theta_1_1.npz",allow_pickle=True)['features']
    featuresDict['dasm_alpha'] = np.load(featurepath + "dasm_alpha_1_1.npz",allow_pickle=True)['features']
    featuresDict['dasm_beta'] = np.load(featurepath + "dasm_beta_1_1.npz",allow_pickle=True)['features']
    featuresDict['dasm_gamma'] = np.load(featurepath + "dasm_gamma_1_1.npz",allow_pickle=True)['features']

    featuresDict['rasm_delta'] = np.load(featurepath + "rasm_delta_1_1.npz",allow_pickle=True)['features']
    featuresDict['rasm_theta'] = np.load(featurepath + "rasm_theta_1_1.npz",allow_pickle=True)['features']
    featuresDict['rasm_alpha'] = np.load(featurepath + "rasm_alpha_1_1.npz",allow_pickle=True)['features']
    featuresDict['rasm_beta'] = np.load(featurepath + "rasm_beta_1_1.npz",allow_pickle=True)['features']
    featuresDict['rasm_gamma'] = np.load(featurepath + "rasm_gamma_1_1.npz",allow_pickle=True)['features']

    return featuresDict

params_dict = {
    str(type(DecisionTreeRegressor()).__name__) : {
           "splitter":["best","random"],
           "max_depth" : [1,3,5,7,9,11,12],
           "min_samples_leaf":[1,2,3,4,5,6,7,8,9,10],
           "min_weight_fraction_leaf":[0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9],
           "max_features":["auto","log2","sqrt",None],
           "max_leaf_nodes":[None,10,20,30,40,50,60,70,80,90] },
    str(type(SVR()).__name__) : {
            'kernel' : ('linear', 'poly', 'rbf', 'sigmoid'),
            'C' : [1,5,10],
            'degree' : [3,8],
            'coef0' : [0.01,10,0.5],
            'gamma' : ('auto','scale')},
    str(type(RandomForestRegressor()).__name__) : {
            'bootstrap': [True],
            'max_depth': [80, 90, 100, 110],
            'max_features': [2, 3],
            'min_samples_leaf': [3, 4, 5],
            'min_samples_split': [8, 10, 12],
            'n_estimators': [100, 200, 300, 1000]
    },
    str(type(XGBRegressor()).__name__) : {
            'learning_rate': [0.01, 0.1],
            'max_depth': [3, 7, 10],
            'min_child_weight': [1, 3, 5],
            'subsample': [0.5, 0.7],
            'colsample_bytree': [0.5, 0.7],
            'n_estimators' : [100, 200, 500],
            'objective': ['reg:squarederror']
    },
    str(type(KNeighborsRegressor()).__name__) : {
            'n_neighbors': [2,3,4,5,6],
            'weights': ['uniform','distance']},

}


from random import randint
from time import time

'''
    JOCUL BULLS AND COWS !
        reguli:
             -Calculatorul va genera un numar de 4 cifre
             -Tu trebuie sa gasesti numarul si vei fi ajutat de urmatoarele 2 indicii
                *daca ai inimerit un numar dar nu si pozitia este bulls
                *daca ai inimerit un numar dar si pozitia este vaca

    posibila greseala!!!

    As far as I could see, none of the solutions are 100% correct.
Reason: if the correct guess is 1211 and the user inputs 2222, he will get 1 cow 3 bulls, but that is obviously not right.
Did someone make a code with that in mind? I couldn't figure a way to make it right

linia 50 pentru verificare !!!!
'''

def guess(guess_number):

    cows = 0
    bulls = 0

    for i in range(0,4):
        if guess_number[i] == input_number[i]:
            cows +=1

        if guess_number[i] in input_number:
            bulls +=1

    print('in your number you have {} cows and  {} bulls\n'.format(cows, bulls))

    return cows,bulls

if __name__=="__main__":
    print("JOCUL BULLS AND COWS ! \n reguli:\n"
          "   -Calculatorul va genera un numar de 4 cifre\n"
          "   -Tu trebuie sa gasesti numarul si vei fi ajutat de urmatoarele 2 indicii:\n"
          "      *daca ai inimerit un numar dar nu si pozitia este bulls\n"
          "      *daca ai inimerit un numar dar si pozitia este vaca")

    guess_number = str(randint(1_000, 10_000))
    print(guess_number)
    tries = 0
    status = True
    t0 = time()
    while(status):
        input_number = input('ghiceste numarul: ')
        cows, bulls = guess(guess_number)
        tries +=1
        if input_number == 'papa':
            break

        if  cows == 4:
            print('bravo ai castigat')
            print('ai avut {} incercari'.format(tries))
            print
            status = False
        if type(input_number) != int:
            print('Esti prost, acesta nu este un numar !!! Malparido ...')
            break

    t1 = time()
    t10 = t1-t0
    print('Ai rezolvat problema in: {} secunde numarul era: {}'.format(t10,guess_number))


from pizza import Pizza
from bebida import Bebida
from entrante import Entrante
from postre import Postre
from combo import Combo
from combo_pareja import ComboPareja
from csv_funciones import *

def solicitar_opcion(mensaje, opciones):
    while True:
        try:
            eleccion = int(input(mensaje))
            if eleccion in opciones:
                return eleccion
            else:
                print("Opción no válida. Por favor, elige una opción válida.")
        except ValueError:
            print("Error: Ingresa un número entero.")

if __name__ == "__main__":
    # Solicitar al usuario que ingrese su nombre
    usuario = input("Introduce tu nombre de usuario: ")
    pedidos_usuario = leer_elementos_csv('pedidos.csv', usuario)

     # Crear instancias de elementos individuales (pizzas, bebidas, entrantes, postres)
    pizza_margarita = Pizza("Margarita", 10.0)
    pizza_pepperoni = Pizza("Pepperoni", 12.0)
    pizza_vegetariana = Pizza("Vegetariana", 11.0)
    pizza_hawaiana = Pizza("Hawaiana", 13.0)
    pizza_cuatros_quesos = Pizza("Cuatro Quesos", 14.0)

    bebida_cola = Bebida("Coca-Cola", 2.0)
    bebida_agua = Bebida("Agua", 1.5)
    bebida_fanta_de_naranja = Bebida("Fanta de Naranja", 2.0)
    bebida_cerveza = Bebida("Cerveza", 3.5)
    bebida_nestea=Bebida("Nestea", 2.0)

    entrante_ensalada = Entrante("Ensalada", 5.0)
    entrante_patatas = Entrante("Patatas", 4.0)
    entrante_alitas = Entrante("Alitas de Pollo", 6.0)
    entrante_nuggets = Entrante("Nuggets", 5.0)
    entrante_nachos = Entrante("Nachos", 5.0)

    postre_tarta_de_queso= Postre("Tarta de queso", 6.0)
    postre_helado = Postre("Helado", 3.0)
    postre_frutas = Postre("Frutas", 4.0)
    postre_natillas = Postre("Natillas", 3.0)
    postre_tarta_de_la_abuela = Postre("Tarta de la abuela", 5.0)

    # Crear combos predefinidos
    combo_1 = Combo("Combo 1")
    combo_1.agregar(entrante_ensalada)
    combo_1.agregar(pizza_margarita)
    combo_1.agregar(bebida_cola)
    combo_1.agregar(postre_helado)

    combo_2 = Combo("Combo 2")
    combo_2.agregar(entrante_patatas)
    combo_2.agregar(pizza_pepperoni)
    combo_2.agregar(bebida_agua)
    combo_2.agregar(postre_frutas)

    combo_3 = Combo("Combo 3")
    combo_3.agregar(entrante_alitas)
    combo_3.agregar(pizza_vegetariana)
    combo_3.agregar(bebida_fanta_de_naranja)
    combo_3.agregar(postre_natillas)

    combo_4 = Combo("Combo 4")
    combo_4.agregar(entrante_nuggets)
    combo_4.agregar(pizza_hawaiana)
    combo_4.agregar(bebida_cerveza)
    combo_4.agregar(postre_tarta_de_la_abuela)

  # Crear combos pareja predefinidos

    combo_pareja_1 = ComboPareja("Combo Pareja 1")
    combo_pareja_1.personalizar(combo_1, combo_2)

    combo_pareja_2 = ComboPareja("Combo Pareja 2")
    combo_pareja_2.personalizar(combo_3, combo_4)

    # Mostrar combos predefinidos
    while True:
        print("\nCombos predefinidos:")
        combo_1.mostrar()
        combo_2.mostrar()
        combo_3.mostrar()
        combo_4.mostrar()
        print("\nCombos Pareja predefinidos:")
        combo_pareja_1.mostrar()
        combo_pareja_2.mostrar()

        print("\nOpciones:")
        print("1. Crear combo personalizado")
        print("2. Elegir combo predefinido")
        print('3. Elegir combo pareja predefinido')
        print('4.Mostrar historial de pedidos')
        print('5. Reconstruir menú desde historial')
        eleccion = solicitar_opcion("Elige una opción (1, 2, 3, 4, 5 o 6): ", [1, 2, 3, 4, 5, 6])

        if eleccion == 1:
            # Solicitar al usuario que elija elementos para el combo personalizado
            print("\nElige los elementos para tu combo personalizado:")
            eleccion_entrante = solicitar_opcion(
                "\nOpciones de entrantes:\n1. Ensalada\n2. Patatas\n3. Alitas de Pollo\n4. Nuggets\n5. Nachos\nElige un entrante (1, 2, 3, 4 o 5): ",
                [1, 2, 3, 4, 5]
            )
            eleccion_pizza = solicitar_opcion(
                "\nOpciones de pizzas:\n1. Margarita\n2. Pepperoni\n3. Vegetariana\n4. Hawaiana\n5. Cuatro Quesos\nElige una pizza (1, 2, 3, 4 o 5): ",
                [1, 2, 3, 4, 5]
            )
            eleccion_bebida = solicitar_opcion(
                "\nOpciones de bebidas:\n1. Cola\n2. Agua\n3. Fanta de Naranja\n4. Cerveza\n5. Nestea\nElige una bebida (1, 2, 3, 4 o 5): ",
                [1, 2, 3, 4, 5]
            )
            eleccion_postre = solicitar_opcion(
                "\nOpciones de postres:\n1. Tarta de queso\n2. Helado\n3. Frutas\n4. Natillas\n5. Tarta de la abuela\nElige un postre (1, 2, 3, 4 o 5): ",
                [1, 2, 3, 4, 5]
            )

            # Crear el combo personalizado
            combo_personalizado = Combo("Combo Personalizado")
            # Agregar elementos al combo personalizado según las elecciones del usuario
            if eleccion_entrante == 1:
                combo_personalizado.agregar(entrante_ensalada)
            elif eleccion_entrante == 2:
                combo_personalizado.agregar(entrante_patatas)
            elif eleccion_entrante == 3:
                combo_personalizado.agregar(entrante_alitas)
            elif eleccion_entrante == 4:
                combo_personalizado.agregar(entrante_nuggets)
            elif eleccion_entrante == 5:
                combo_personalizado.agregar(entrante_nachos)

            if eleccion_pizza == 1:
                combo_personalizado.agregar(pizza_margarita)
            elif eleccion_pizza == 2:
                combo_personalizado.agregar(pizza_pepperoni)
            elif eleccion_pizza == 3:
                combo_personalizado.agregar(pizza_vegetariana)
            elif eleccion_pizza == 4:
                combo_personalizado.agregar(pizza_hawaiana)
            elif eleccion_pizza == 5:
                combo_personalizado.agregar(pizza_cuatros_quesos)

            if eleccion_bebida == 1:
                combo_personalizado.agregar(bebida_cola)
            elif eleccion_bebida == 2:
                combo_personalizado.agregar(bebida_agua)
            elif eleccion_bebida == 3:
                combo_personalizado.agregar(bebida_fanta_de_naranja)
            elif eleccion_bebida == 4:
                combo_personalizado.agregar(bebida_cerveza)
            elif eleccion_bebida == 5:
                combo_personalizado.agregar(bebida_nestea)

            if eleccion_postre == 1:
                combo_personalizado.agregar(postre_tarta_de_queso)
            elif eleccion_postre == 2:
                combo_personalizado.agregar(postre_helado)
            elif eleccion_postre == 3:
                combo_personalizado.agregar(postre_frutas)
            elif eleccion_postre == 4:
                combo_personalizado.agregar(postre_natillas)
            elif eleccion_postre == 5:
                combo_personalizado.agregar(postre_tarta_de_la_abuela)

            # Mostrar el combo personalizado
            print("\nTu combo personalizado:")
            combo_personalizado.mostrar()
            total_combo_personalizado = combo_personalizado.calcular_precio_total()

            # Verificar si el total es mayor a 50 euros
            if total_combo_personalizado > 20:
                # Aplicar descuento del 5%
                descuento = total_combo_personalizado * 0.05
                total_combo_personalizado_con_descuento = total_combo_personalizado - descuento

                print(f"\nEl total de tu combo personalizado es {total_combo_personalizado:.2f} euros.")
                print(f"Se aplicó un descuento del 5%. Nuevo total con descuento: {total_combo_personalizado_con_descuento:.2f} euros.")
            else:
                print(f"\nEl total de tu combo personalizado es {total_combo_personalizado:.2f} euros.")

            #preguntamos si quiere guardar el historial
            if preguntar_guardar_historial():
                guardar_elemento_csv(combo_personalizado, 'pedidos.csv', usuario)
            else:
                print("No se guardará el historial de pedidos.")

        elif eleccion == 2:
            # Solicitar al usuario que elija un combo predefinido y mostrarlo
            opciones_combos_predefinidos = [1, 2, 3]
            eleccion_combo_predefinido = solicitar_opcion("Elige un combo predefinido (1, 2 o 3): ", opciones_combos_predefinidos)

            chosen_combo = None

            if eleccion_combo_predefinido == 1:
                chosen_combo = combo_1
            elif eleccion_combo_predefinido == 2:
                chosen_combo = combo_2
            elif eleccion_combo_predefinido == 3:
                chosen_combo = combo_3

            # Mostrar el combo predefinido
            print("\nEl combo predefinido que has elegido es:")
            chosen_combo.mostrar()
            total_chosen_combo = chosen_combo.calcular_precio_total()

            if total_chosen_combo > 20:
                # Aplicar descuento del 5%
                descuento = total_chosen_combo * 0.05
                total_chosen_combo_con_descuento = total_chosen_combo- descuento

                print(f"\nEl total de tu combo personalizado es {total_chosen_combo:.2f} euros.")
                print(f"Se aplicó un descuento del 5%. Nuevo total con descuento: {total_chosen_combo_con_descuento:.2f} euros.")
            else:
                print(f"\nEl total de tu combo personalizado es {total_chosen_combo:.2f} euros.")

            # Preguntar si quieren pedir este combo
            if input("¿Quieres pedir este combo? (s/n): ").lower() == 's':
                if preguntar_guardar_historial():
                    guardar_elemento_csv(chosen_combo, 'pedidos.csv', usuario)
                else:
                    print("No se guardará el historial de pedidos.")
            else:
                print("Pedido cancelado.")

        elif eleccion == 3:
            combo_pareja_personalizado = ComboPareja("Combo Pareja Personalizado")

            print("\nElige los combos para tu Combo Pareja:")
            print("1. Combo 1")
            print("2. Combo 2")
            eleccion_combo1 = solicitar_opcion("Elige el Combo 1 (1 o 2): ", [1, 2])
            eleccion_combo2 = solicitar_opcion("Elige el Combo 2 (1 o 2): ", [1, 2])

            if eleccion_combo1 == 1:
                combo_pareja_personalizado.personalizar(combo_1, None)
            elif eleccion_combo1 == 2:
                combo_pareja_personalizado.personalizar(combo_2, None)

            if eleccion_combo2 == 1:
                combo_pareja_personalizado.personalizar(combo_pareja_personalizado.combo1, combo_1)
            elif eleccion_combo2 == 2:
                combo_pareja_personalizado.personalizar(combo_pareja_personalizado.combo1, combo_2)

            # Mostrar el Combo Pareja personalizado
            print("\nTu Combo Pareja personalizado:")
            combo_pareja_personalizado.mostrar()
            total_combo_pareja_personalizado= combo_pareja_personalizado.calcular_precio_total()

            if total_combo_pareja_personalizado > 20:
                # Aplicar descuento del 5%
                descuento = total_combo_pareja_personalizado* 0.05
                total_combo_pareja_personalizado_con_descuento = total_combo_pareja_personalizado - descuento

                print(f"\nEl total de tu combo personalizado es {total_combo_pareja_personalizado:.2f} euros.")
                print(f"Se aplicó un descuento del 5%. Nuevo total con descuento: {total_combo_pareja_personalizado_con_descuento:.2f} euros.")
            else:
                print(f"\nEl total de tu combo personalizado es {total_combo_pareja_personalizado:.2f} euros.")

            #preguntamos si quiere guardar el historial
            if preguntar_guardar_historial():
                guardar_elemento_csv(combo_pareja_personalizado, 'pedidos.csv', usuario)
            else:
                print("No se guardará el historial de pedidos.")

        elif eleccion == 4:
    # Mostrar historial de pedidos según usuario
            print("\nHistorial de pedidos:")
            pedidos_usuario = leer_elementos_csv('pedidos.csv', usuario)

            if pedidos_usuario:
                print(f"\nPedidos antiguos de {usuario}:")
                for pedido in pedidos_usuario:
                    if isinstance(pedido, Combo):
                        print("\nPedido Combo:")
                        pedido.mostrar()
                    elif isinstance(pedido, ComboPareja):
                        print("\nPedido Combo Pareja:")
                        pedido.mostrar()
                    else:
                        print(f'{type(pedido).__name__}: {pedido.nombre} - Precio: {pedido.precio}')
            else:
                print(f"No hay pedidos antiguos de {usuario}.")

        elif eleccion == 5:
            # Reconstruir menú desde historial
            menu_reconstruido = reconstruir_menu_desde_historial('pedidos.csv', usuario)
            if menu_reconstruido:
                print("\nMenú reconstruido desde historial:")
                for item in menu_reconstruido:
                    if isinstance(item, Combo):
                        print("\nCombo:")
                        item.mostrar()
                    elif isinstance(item, ComboPareja):
                        print("\nCombo Pareja:")
                        item.mostrar()
                    else:
                        print(f'{type(item).__name__}: {item.nombre} - Precio: {item.precio}')
            else:
                print("No hay historial de pedidos para reconstruir el menú.")

        elif eleccion == 6:
            # Salir del programa
            print("Saliendo del programa...")
            break


#!/usr/bin/env python

from .periodictable import PeriodicTable
from .atomgroup import AtomGroup
from .atom import Atom
from .position import Position
import logging
logger = logging.getLogger(__name__)

class SimpleGro(object):
    """
    Simple .gro file

    sample:
    MD of 2 waters, t= 0.0
        6
        1WATER  OW1    1   0.126   1.624   1.679  0.1227 -0.0580  0.0434
        1WATER  HW2    2   0.190   1.661   1.747  0.8085  0.3191 -0.7791
        1WATER  HW3    3   0.177   1.568   1.613 -0.9045 -2.6469  1.3180
        2WATER  OW1    4   1.275   0.053   0.622  0.2519  0.3140 -0.1734
        2WATER  HW2    5   1.337   0.002   0.680 -1.0641 -1.1349  0.0257
        2WATER  HW3    6   1.326   0.120   0.568  1.9427 -0.8216 -0.0244
    1.82060   1.82060   1.82060
    """

    def __init__(self):
        self._title = ""
        self._num_of_atoms = 0
        self._atoms = []

    def load(self, gro_filepath):
        with open(gro_filepath, "r") as f:
            # line 1
            line = f.readline()
            line = line.rstrip()
            self._title = line

            # line 2
            line = f.readline()
            line = line.rstrip()
            self._num_of_atoms = int(line)

            # atom lines
            for i in range(self._num_of_atoms):
                line = f.readline()
                line = line.rstrip()

                residue_number = int(line[0:5])
                residue_name = line[5:10].strip()
                atom_name = line[10:15].strip()
                atom_number = int(line[15:20])
                # position (in nm, x y z in 3 columns, each 8 positions with 3 decimal places)
                position_x = float(self._str2float(line[20:28]))
                position_y = float(self._str2float(line[28:36]))
                position_z = float(self._str2float(line[36:44]))
                # velocity (in nm/ps (or km/s), x y z in 3 columns, each 8 positions with 4 decimal places)
                velocity_x = float(self._str2float(line[44:52]))
                velocity_y = float(self._str2float(line[52:60]))
                velocity_z = float(self._str2float(line[60:68]))

                atom_data = (residue_number, residue_name, atom_name, atom_number,
                             position_x, position_y, position_z,
                             velocity_x, velocity_y, velocity_z)
                # print(atom_data)
                self._atoms.append(atom_data)

            # box vectors
            line = f.readline()
            line = line.strip()
            box_vectors = line.split()
            box_vectors = [float(x) for x in box_vectors]
            for i in range(len(box_vectors), 6):
                box_vectors.append(0.0)
            self._box_vectors = box_vectors

    def _str2float(self, str):
        if len(str) == 0:
            return 0.0
        else:
            return float(str)

    def get_atomgroup(self):
        pt = PeriodicTable()
        output = AtomGroup()
        output.name = self._title

        model = AtomGroup()
        chain = AtomGroup()

        current_res_id = -1
        current_ag = None
        for atom_data in self._atoms:
            (res_id, res_name, name, id, x, y, z, vx, vy, vz) = atom_data
            if current_res_id != res_id:
                if current_ag != None:
                    chain.set_group(current_res_id, current_ag)
                current_res_id = res_id
                current_ag = AtomGroup()
                current_ag.name = res_name

            atom = Atom()
            name = name.strip()
            atom.name = name

            symbol = ""
            if len(name) == 1:
                symbol = name
            else:
                name2 = name[0:2]
                if name2 in pt:
                    symbol = name2
                else:
                    symbol = name[0]
            atom.symbol = symbol
            atom.position = Position(
                x * 10.0, y * 10.0, z * 10.0)  # nm -> angstrom
            current_ag.set_atom(id, atom)

        if current_ag != None:
            chain.set_group(current_res_id, current_ag)
            model.set_group("_", chain)
            output.set_group(1, model)

        return output

    def set_by_atomgroup(self, atomgroup):
        assert(isinstance(atomgroup, AtomGroup))

        self._title = atomgroup.name
        self._num_of_atoms = atomgroup.get_number_of_atoms()
        self._atoms = []

        #count = 0
        serial = 1
        residue_index = 1
        for model_key, model in atomgroup.groups():
            for chain_id, chain in model.groups():
                for res_key, residue in chain.groups():
                    residue_number = residue_index
                    residue_index += 1
                    residue_name = residue.name
                    for key, atom in residue.atoms():
                        atom_name = atom.name
                        atom_number = serial
                        serial += 1
                        position_x = atom.xyz.x * 0.1  # angstrom -> nm
                        position_y = atom.xyz.y * 0.1
                        position_z = atom.xyz.z * 0.1
                        velocity_x = 0.0
                        velocity_y = 0.0
                        velocity_z = 0.0
                        self._atoms.append((residue_number, residue_name, atom_name, atom_number,
                                            position_x, position_y, position_z,
                                            velocity_x, velocity_y, velocity_z))
                        #count += 1

        (pos1, pos2) = atomgroup.box()
        # the vdw radii of "C" = 1.96
        self._box_vectors = (abs(pos2.x - pos1.x),
                             abs(pos2.y - pos1.y), abs(pos2.z - pos1.z))

    def __str__(self):
        answer = ""
        answer += "{}\n".format(self._title)
        answer += "{}\n".format(len(self._atoms))
        for i in range(len(self._atoms)):
            residue_number = int(self._atoms[i][0] % 10000)
            residue_name = self._atoms[i][1][0:5]
            atom_name = self._atoms[i][2][0:5]
            atom_number = int(self._atoms[i][3] % 10000)
            position_x = self._atoms[i][4]
            position_y = self._atoms[i][5]
            position_z = self._atoms[i][6]
            velocity_x = self._atoms[i][7]
            velocity_y = self._atoms[i][8]
            velocity_z = self._atoms[i][9]

            answer += "{:>5}{:<5}{:>5}{:>5}{:8.3f}{:8.3f}{:8.3f}{:8.4f}{:8.4f}{:8.4f}\n".format(
                residue_number, residue_name, atom_name, atom_number,
                position_x, position_y, position_z,
                velocity_x, velocity_y, velocity_z)
        answer += " ".join(map(str, self._box_vectors))

        return answer


import os
import shutil
new_dir = '/home/pepe/Desktop/paccr-master/cosine/topic_doc_mat'
old_dir = '/home/pepe/Desktop/paccr-master/cosine/topic_doc_mat_kurwa'

#wchodzę w folder
    #biorę kolejne pliki
        #biorę nazwę pliku 01.py
        #przenoszę go do folderu 01.py
        #zmieniam jego nazwę na nazwę rodzica.py
        #przechodzę na kolejny plik
    #przechodzę na kolejny folder
print('STARTUJE!!!!')
#for dir in os.listdir(topic_dir):
#    for file_dir in os.listdir(topic_dir + '/' + dir):
#        parentName = os.path.basename(dir)
#        prevName = os.path.basename(file_dir)
#        prevName=prevName[:-4]
#        print('{} {}'.format(parentName, prevName))
#        os.rename(topic_dir + '/' + parentName + '/' + file_dir, new_topic_dir +'/' + prevName + '/' + parentName + '.npy')

# os.mkdir(new_dir)

# for i in range(1, 16):
#     os.mkdir('{}/{}'.format(new_dir, i))

for direstory in os.listdir(old_dir):
    print('{}/{}'.format(old_dir, direstory))
    assert 1 == 0
    for fileN in os.listdir('{}/{}'.format(old_dir, direstory)):
        print(fileN)

        #shutil.copy("{}/{}/{}".format(old_dir, direstory ,file), "{}/{}/{}".format(new_dir, file[:-4], direstory))

# for direstory in os.listdir(topic_dir):
#     for file in os.listdir('{}/{}'.format(topic_dir, direstory)):
#         shutil.copy("{}/{}/{}".format(topic_dir, direstory ,file), "{}/{}/{}".format(new_topic_dir, file[:-4], direstory))

print('skonczylem :)')


temp_ano,temp_t,c,mes = [],0,0,0
for ano in range(12):
    temp_ano.append(int(input(f'> Insira a temperatura média do mês {ano+1}: ')))
    temp_t += temp_ano[ano]
media_a = temp_t / (ano+1)

for m in temp_ano:
    c += 1
    if m > media_a:
        if c == 1:
            mes = 'Janeiro'
        if c == 2:
            mes = 'Fevereiro'
        if c == 3:
            mes = 'Março'
        if c == 4:
            mes = 'Abril'
        if c == 5:
            mes = 'Maio'
        if c == 6:
            mes = 'Junho'
        if c == 7:
            mes = 'Julho'
        if c == 8:
            mes = 'Agosto'
        if c == 9:
            mes = 'Setembro'
        if c == 10:
            mes = 'Outubro'
        if c == 11:
            mes = 'Novembro'
        if c == 12:
            mes = 'Dezembro'
        print(f'\nA temperatura de {m}° C está acima da média e se encontra no mês de {mes}')
media_bonita = (((media_a * 100) // 1) / 100)
print(f'\n> A média da temperatura é: {media_bonita}° C')


#consonant = ("b c d f g h j k l m n p q r s t v w x y z")
#x = consonant.split()
#print(x): check from (aniS)
def prime(num):
     for n in range(2, num-1):
        for x in range (2, num-1):
            if n % x == 0:
                return False
            else:
                return True

print(prime(5))