import cv2
import numpy as np
from threading import Thread
import time
import argparse
#from gui import onmouse, updateGUI
from gui import gui, getPath
from VideoStream import VideoStream#, VideoSave

parser = argparse.ArgumentParser()
parser.add_argument('--resolution', help='Desired webcam resolution in WxH. If the webcam does not support the resolution entered, errors may occur.',
                    default='1280x720')
parser.add_argument('--fps', help='Frames per second',
                    default=20)

args = parser.parse_args()
resW, resH = args.resolution.split('x')
w, h = int(resW), int(resH)
FPS = int(args.fps)

# Initialize frame rate calculation
frame_rate_calc = 1
freq = cv2.getTickFrequency()

# Initialize video stream
cv2.namedWindow("test",1)
g=gui()
cv2.setMouseCallback("test",g.onmouse)
path=g.getPath()
videostream = VideoStream(resolution=(w,h),framerate=FPS).start()
out=None
#videosave = None#VideoSave(path, FPS, (w,h)).start()

time.sleep(1)

while True:
    t1 = cv2.getTickCount()

    frame = videostream.read()
    #cv2.putText(frame,'FPS: {0:.2f}'.format(frame_rate_calc),(30,50),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,0),2,cv2.LINE_AA)
    cv2.imshow('frame', frame)

    img=g.updateGUI()
    cv2.imshow("test",img)

    if g.getRecordingStatus():
        if out == None:
            #out=cv2.VideoWriter(path, cv2.VideoWriter_fourcc(*'mp4v'), FPS, (w,h), True)
            #out=cv2.VideoWriter(path, cv2.VideoWriter_fourcc(*'MJPG'), FPS, (w,h), True)
            out=cv2.VideoWriter(path, cv2.VideoWriter_fourcc(*'WMV2'), 10, (w,h), True)
            print("recording start")
        out.write(frame)
    else:
        if not out == None:
            out.release()
            out=None
            print("recording stopped")

    '''
    if g.getRecordingStatus():
        path=g.getPath()
        videostream.recordupdate(True, path)
    else:
        videostream.recordupdate(False)
    '''
    '''
    if g.getRecordingStatus():
        if videosave==None:#videosave.getStatus():
            path=g.getPath()
            videosave = VideoSave(path, FPS, (w,h)).start()
            print("recording start")
        videosave.writeframe(img)

    else:
        if not videosave==None:#videosave.getStatus():
            videosave.stop()
            print("recording stop")
            videosave=None
    '''
    # Calculate framerate
    t2 = cv2.getTickCount()
    time1 = (t2-t1)/freq
    frame_rate_calc= 1/time1

    # Press 'q' to quit
    if cv2.waitKey(1) == ord('q'):
        break

# Clean up
cv2.destroyAllWindows()
videostream.stop()
#if not videosave == None:
#    videosave.stop()


from urllib import request, parse
import ssl, re

ssl._create_default_https_context = ssl._create_stdlib_context

def get_img(num):
    url = 'http://langlang2017.com/img/banner%s.png' % num
    res = request.urlopen(url).read()
    print(res)

    # with open('banner%s.png' % num, 'wb') as f:
    #     f.write(res)

if __name__ == '__main__':
    for i in range(1, 5):
        get_img(str(i))


# emacs: -*- mode: python-mode; py-indent-offset: 2; tab-width: 2; indent-tabs-mode: nil -*-
# ex: set sts=2 ts=2 sw=2 et:
""" A Neurosynth Dataset """

import logging
import re
import random
import os

import numpy as np
import pandas as pd
from scipy import sparse

import mappable

from neurosynth.base import mask, imageutils, transformations

logger = logging.getLogger('neurosynth.dataset')

class Dataset(object):

    def __init__(
        self, filename, feature_filename=None, masker=None, r=6, transform=True,
                  target='MNI'):
        """ Initialize a new Dataset instance.

        Creates a new Dataset instance from a text file containing activation data.
        At minimum, the input file must contain tab-delimited columns named x, y, z,
        id, and space (case-insensitive). The x/y/z columns indicate the coordinates
        of the activation center or peak, the id column is used to group multiple
        activations from a single Mappable (e.g. an article). Typically the id should
        be a uniquely identifying field accessible to others, e.g., a doi in the case
        of entire articles. The space column indicates the nominal atlas used to
        produce each activation. Currently all values except 'TAL' (Talairach) will
        be ignored. If space == TAL and the transform argument is True, all activations
        reported in Talairach space will be converted to MNI space using the
        Lancaster et al transform.

        Args:
          filename: The name of a database file containing a list of activations.
          feature_filename: An optional filename to construct a FeatureTable from.
          masker: An optional Nifti/Analyze image name defining the space to use for
            all operations. If no image is passed, defaults to the MNI152 2 mm
            template packaged with FSL.
          r: An optional integer specifying the radius of the smoothing kernel, in mm.
            Defaults to 6 mm.
          transform: Optional argument specifying how to handle transformation between
            coordinates reported in different stereotactic spaces. When True (default),
            activations in Talairach (T88) space will be converted to MNI space using
            the Lancaster et al (2007) transform; no other transformations will be
            applied. When False, no transformation will be applied. Alternatively,
            the user can pass their own dictionary of named transformations to apply,
            in which case each activation will be checked against the dictionary
            as it is read in and the specified transformation will be applied if
            found (for further explanation, see transformations.Transformer).
          target: The name of the target space within which activation coordinates
            are represented. By default, MNI.

        Returns:
          A Dataset instance.

        """

        # Instance properties
        self.r = r

        # Set up transformations between different image spaces
        if transform:
            if not isinstance(transform, dict):
                transform = {'T88': transformations.t88_to_mni(),
                              'TAL': transformations.t88_to_mni()
                             }
            self.transformer = transformations.Transformer(transform, target)
        else:
            self.transformer = None

        # Load mappables
        self.mappables = self._load_mappables_from_txt(filename)

        # Load the volume into a new Masker
        try:
            if masker is None:
                resource_dir = os.path.join(os.path.dirname(__file__),
                                            os.path.pardir,
                                            'resources')
                masker = os.path.join(
                    resource_dir, 'MNI152_T1_2mm_brain.nii.gz')
            self.masker = mask.Masker(masker)
        except Exception as e:
            logger.error("Error loading masker %s: %s" % (masker, e))
            # yoh: TODO -- IMHO should re-raise or not even swallow the exception here
            # raise e

        # Create supporting tables for images and features
        self.create_image_table()
        if feature_filename is not None:
            self.feature_table = FeatureTable(self, feature_filename)

    def _load_mappables_from_txt(self, filename):
        """ Load mappables from a text file.

        Args:
          filename: a string pointing to the location of the txt file to read from.
        """
        logger.info("Loading mappables from %s..." % filename)

        # Read in with pandas
        contents = pd.read_csv(filename, sep='\t')
        contents.columns = [col.lower() for col in list(contents.columns)]

        # Make sure all mandatory columns exist
        mc = ['x', 'y', 'z', 'id', 'space']
        if (set(mc) - set(list(contents.columns))):
            logger.error(
                "At least one of mandatory columns (x, y, z, id, and space) is missing from input file.")
            return

        extra_fields = list(set(list(contents.columns)) - set(mc))  # save non-standard fields

        def get_mappable_data(grp):
            first = grp.iloc[0]
            d = { 'peaks': grp[['x','y','z']].values }
            for f in ['id', 'space'] + extra_fields:
                d[f] = first[f]
            return d

        data = list(contents.groupby('id').apply(get_mappable_data))

        # Initialize all mappables--for now, assume Articles are passed
        logger.info("Converting text to mappables...")
        return [mappable.Article(m, self.transformer) for m in data]

    def create_image_table(self, r=None):
        """ Create and store a new ImageTable instance based on the current Dataset.

        Will generally be called privately, but may be useful as a convenience
        method in cases where the user wants to re-generate the table with a
        new smoothing kernel of different radius.

        Args:
          r: An optional integer indicating the radius of the smoothing kernel.
            By default, this is None, which will keep whatever value is currently
            set in the Dataset instance.
        """
        logger.info("Creating image table...")
        if r is not None:
            self.r = r
        self.image_table = ImageTable(self)

    def add_mappables(self, filename=None, mappables=None, remap=True):
        """ Append new Mappable objects to the end of the list.

        Either a filename or a list of mappables must be passed.

        Args:
          filename: The location of the file to extract new mappables from.
          mappables: A list of Mappable instances to append to the current list.
          remap: Optional boolean indicating whether to regenerate the entire
            ImageTable after appending the new Mappables.
        """
        # TODO: (i) it would be more effiicent to only map the new Mappables into
        # the ImageTable instead of redoing everything. (ii) we should check for
        # duplicates and prompt whether to overwrite or update in cases where
        # conflicts occur.
        if filename != None:
            self.mappables.extend(self._load_mappables_from_txt(filename))
        elif mappables != None:
            self.mappables.extend(mappables)
        if remap:
            self.image_table = create_image_table()

    def delete_mappables(self, ids, remap=True):
        """ Delete specific Mappables from the Dataset.

        Note that 'ids' is a list of unique identifiers of the Mappables (e.g., doi's),
        and not indices in the current instance's mappables list.

        Args:
          ids: A list of ids corresponding to the Mappables to delete.
          remap: Optional boolean indicating whether to regenerate the entire
            ImageTable after deleting undesired Mappables.
        """
        self.mappables = [m for m in self.mappables if m not in ids]
        if remap:
            self.image_table = create_image_table()

    def get_mappables(self, ids, get_image_data=False):
        """ Takes a list of unique ids and returns corresponding Mappables.

        Args:
          ids: A list of ids of the mappables to return.
          get_image_data: An optional boolean. When True, returns a voxel x mappable matrix
            of image data rather than the Mappable instances themselves.

        Returns:
          If get_image_data is True, a 2D numpy array of voxels x Mappables. Otherwise, a
          list of Mappables.
        """
        if get_image_data:
            return self.get_image_data(ids)
        else:
            return [m for m in self.mappables if m.id in ids]

    def get_ids_by_features(self, features, threshold=None, func=np.sum, get_image_data=False, get_weights=False):
        """ A wrapper for FeatureTable.get_ids().

        Args:
          features: A list of features to use when selecting Mappables.
          threshold: Optional float between 0 and 1. If passed, the threshold will be used as
            a cut-off when selecting Mappables.
          func: The function to use when aggregating over the list of features. See
            documentation in FeatureTable.get_ids() for a full explanation.
          get_image_data: An optional boolean. When True, returns a voxel x mappable matrix
            of image data rather than the Mappable instances themselves.
        """
        ids = self.feature_table.get_ids(features, threshold, func, get_weights)
        return self.get_image_data(ids) if get_image_data else ids

    def get_ids_by_expression(self, expression, threshold=0.001, func=np.sum, get_image_data=False):
        ids = self.feature_table.get_ids_by_expression(expression, threshold, func)
        return self.get_image_data(ids) if get_image_data else ids

    def get_ids_by_mask(self, mask, threshold=0.0, get_image_data=False):
        """ Return all mappable objects that activate within the bounds
        defined by the mask image. Optional threshold parameter specifies
        the proportion of voxels within the mask that must be active to
        warrant inclusion. E.g., if threshold = 0.1, only mappables with
        > 10% of voxels activated in mask will be returned. """
        mask = self.masker.mask(mask).astype(bool)
        num_vox = np.sum(mask)
        prop_mask_active = self.image_table.data.T.dot(
            mask).astype(float) / num_vox
        indices = np.where(prop_mask_active > threshold)[0]
        return self.get_image_data(indices) if get_image_data else [self.image_table.ids[ind] for ind in indices]

    def get_ids_by_peaks(self, peaks, r=10, threshold=0.0, get_image_data=False):
        """ A wrapper for get_ids_by_mask. Takes a set of xyz coordinates and generates
        a new Nifti1Image to use as a mask.

        Args:
          peaks: Either an n x 3 numpy array, or a list of lists (e.g., [[-10, 22, 14]])
            specifying the world (x/y/z) coordinates of the target location(s).
          r: Radius in millimeters of the sphere to grow around each location.
          threshold: Optional float indicating the proportion of voxels that must be
            active in order for a Mappable to be considered active.
          get_image_data: If true, returns the image data for all activated Mappables in
            a voxel x Mappable numpy array. Otherwise, returns just the IDs of Mappables.

        Returns:
          Either a list of ids (if get_image_data = False) or a numpy array of image data.

        """
        peaks = np.array(peaks)  # Make sure we have a numpy array
        peaks = transformations.xyz_to_mat(peaks)
        img = imageutils.map_peaks_to_image(
            peaks, r, vox_dims=self.masker.vox_dims,
            dims=self.masker.dims, header=self.masker.get_header())
        return self.get_ids_by_mask(img, threshold, get_image_data=get_image_data)

    def add_features(self, filename, description=''):
        """ Construct a new FeatureTable from file. Note: this is destructive, and will
        overwrite existing FeatureTable. Need to add merging operations that gracefully
        handle missing studies and conflicting feature names. """
        self.feature_table = FeatureTable(self, filename, description)

    def get_image_data(self, ids=None, voxels=None, dense=True):
        """ A convenience wrapper for ImageTable.get_image_data(). """
        return self.image_table.get_image_data(ids, voxels=voxels, dense=dense)

    def get_feature_data(self, ids=None, **kwargs):
        """ A convenience wrapper for FeatureTable.get_image_data(). """
        return self.feature_table.get_feature_data(ids, **kwargs)

    def get_feature_names(self, features=None):
        """ Returns names of features. If features is None, returns all features.
        Otherwise assumes the user is trying to find the order of the features.  """
        if features:
            return self.feature_table.get_ordered_names(features)
        else:
            return self.feature_table.feature_names

    def get_feature_counts(self, func=np.sum, threshold=0.001):
        """ Returns a dictionary, where the keys are the feature names
        and the values are the number of studies tagged with the feature. """
        result = {}
        for f in self.get_feature_names():
            result[f] = len(self.get_ids_by_features([f], func=func, threshold=threshold))
        return result

    @classmethod
    def load(cls, filename):
        """ Load a pickled Dataset instance from file. """
        import cPickle
        dataset = cPickle.load(open(filename, 'rb'))
        dataset.feature_table._csr_to_sdf()
        return dataset

    def save(self, filename, keep_mappables=False):
        """ Pickle the Dataset instance to the provided file.

        If keep_mappables = False (default), will delete the Mappable objects
        themselves before pickling. This will save a good deal of space and
        is generally advisable once a stable Dataset is created, as the
        Mappables are rarely used after the ImageTable is generated.
        """
        if not keep_mappables:
            self.mappables = []

        self.feature_table._sdf_to_csr()

        import cPickle
        cPickle.dump(self, open(filename, 'wb'), -1)

        self.feature_table._csr_to_sdf()

    def to_json(self, filename=None):
        """ Save the Dataset to file in JSON format.

        This is not recommended, as the resulting file will typically be several
        GB in size. If no filename is provided, returns the JSON string.
        """
        import json
        mappables = [m.to_json() for m in self.mappables]
        json_string = json.dumps({'mappables': mappables})
        if filename is not None:
            open(filename, 'w').write(json_string)
        else:
            return json_string

class ImageTable(object):

    def __init__(self, dataset=None, mappables=None, masker=None, r=6, use_sparse=True):
        """ Initialize a new ImageTable.

        If a Dataset instance is passed, all inputs are taken from the Dataset.
        Alternatively, a user can manually pass the desired mappables
        and masker (e.g., in cases where the ImageTable class is being used without a
        Dataset). Can optionally specify the radius of the sphere used for smoothing (default:
        6 mm), as well as whether or not to represent the data as a sparse array
        (generally this should be left to True, as these data are quite sparse and
        computation can often be speeded up by an order of magnitude.)
        """
        if dataset is not None:
            mappables, masker, r = dataset.mappables, dataset.masker, dataset.r
        for var in [mappables, masker, r]:
            assert var is not None
        self.ids = [m.id for m in mappables]
        self.masker = masker
        self.r = r

        data_shape = (self.masker.num_vox_in_mask, len(mappables))
        if use_sparse:
            # Fancy indexing assignment is not supported for sparse matrices, so
            # let's keep lists of values and their indices (rows, cols) to later
            # construct the csr_matrix.
            vals, rows, cols = [], [], []
        else:
            self.data = np.zeros(data_shape, dtype=int)

        logger.info("Creating matrix of %d mappables..." % (len(mappables),))
        for i, s in enumerate(mappables):
            logger.debug("%s/%s..." % (str(i + 1), str(len(mappables))))
            img = imageutils.map_peaks_to_image(
                s.peaks, r=r, header=self.masker.get_header())
            img_masked = self.masker.mask(img)
            if use_sparse:
                nz = np.nonzero(img_masked)
                assert(len(nz) == 1)
                vals += list(img_masked[nz])
                rows += list(nz[0])
                cols += [i] * len(nz[0])
            else:
                self.data[:, i] = img_masked

        if use_sparse:
            self.data = sparse.csr_matrix((
                vals, (rows, cols)), shape=data_shape)

    def get_image_data(self, ids=None, voxels=None, dense=True):
        """ Slices and returns a subset of image data.

        Args:
          ids: A list or 1D numpy array of Mappable ids to return. If None, returns
            data for all Mappables.
          voxels: A list or 1D numpy array of voxel indices (i.e., rows) to return.
            If None, returns data for all voxels.
          dense: Optional boolean. When True (default), convert the result to a dense
            array before returning. When False, keep as sparse matrix.

        Returns:
          A 2D numpy array, with voxels in rows and mappables in columns.
        """
        result = self.data
        if ids is not None:
            idxs = np.where(np.in1d(np.array(self.ids), np.array(ids)))[0]
            result = result[:, idxs]
        if voxels is not None:
            result = result[voxels,:]
        return result.toarray() if dense else result

    def trim(self, ids):
        """ Trim ImageTable to keep only the passed Mappables. This is a convenience
        method, and should generally be avoided in favor of non-destructive alternatives
        that don't require slicing (e.g., matrix multiplication). """
        self.data = self.get_image_data(ids, dense=False)  # .tocoo()
        idxs = np.where(np.in1d(np.array(self.ids), np.array(ids)))[0]
        self.ids = [self.ids[i] for i in idxs]

    def save_images_to_file(self, ids, outroot='./'):
        """ Reconstructs vectorized images corresponding to the specified Mappable ids
        and saves them to file, prepending with the outroot (default: current directory). """
        pass

    def save(self, filename):
        import cPickle
        cPickle.dump(self, open(filename, 'wb'), -1)

class FeatureTable(object):

    """ A FeatureTable instance stores a matrix of mappables x features, along with
    associated manipulation methods. """

    def __init__(self, dataset, filename, description=None, validate=False):
        """ Initialize a new FeatureTable. Takes as input a parent DataSet instance and
        the name of a file containing feature data. Optionally, can provide a description
        of the feature set. """
        self.dataset = dataset
        self.load(filename)
        self.description = description

    def load(self, filename):
        """ Loads FeatureTable data from file. Input must be a dense matrix stored as
        plaintext (see _parse_txt() for details).
        """
        try:
            self._features_from_txt(filename)
        except Exception as e:
            logger.error("%s cannot be parsed: %s" % (filename, e))

    def _features_from_txt(self, filename):
        """ Parses FeatureTable from a plaintext file that represents a dense matrix,
        with mappable objects in rows and features in columns. Values in cells reflect the
        weight of the intersecting feature for the intersecting study. Feature names and
        mappable IDs should be included as the first column and first row, respectively. """

        # Use pandas to read in data
        self.data = pd.read_csv(filename, delim_whitespace=True, index_col=0).to_sparse()

        # Remove mappables without any features
        # if validate:
        #     valid_ids = set(self.ids) & set(self.dataset.image_table.ids)
        #     if len(valid_ids) < len(self.dataset.image_table.ids):
        #         valid_id_inds = np.in1d(self.ids, np.array(valid_ids))
        #         self.data = self.data[valid_id_inds,:]
        #         self.ids = self.ids[valid_id_inds]
        # self.data = sparse.csr_matrix(self.data)

    @property
    def feature_names(self):
        return list(self.data.columns)

    def get_feature_data(self, ids=None, features=None, dense=True):
        """ Slices and returns a subset of feature data.

        Args:
            ids: A list or 1D numpy array of Mappable ids to return rows for.
                If None, returns data for all Mappables (i.e., all rows in array).
            features: A list or 1D numpy array of named features to return.
                If None, returns data for all features (i.e., all columns in array).
            dense: Optional boolean. When True (default), convert the result to a dense
                array before returning. When False, keep as sparse matrix. Note that if
                ids is not None, the returned array will always be dense.
        Returns:
          A 2D numpy array, with mappable IDs in rows and features in columns.
        """
        result = self.data

        if ids is not None:
            result = result.ix[ids]

        if features is not None:
            result = result.ix[:,features]

        return result#.to_dense() if dense else result

    def get_ordered_names(self, features):
        """ Given a list of features, returns features in order that they appear in database
        Args:
            features: A list or 1D numpy array of named features to return.

        Returns:
            A list of features in order they appear in database
        """

        idxs = np.where(np.in1d(self.data.columns.values, np.array(features)))[0]
        return list(self.data.columns[idxs].values)

    def get_ids(self, features, threshold=None, func=np.sum, get_weights=False):
        """ Returns a list of all Mappables in the table that meet the desired feature-based
        criteria.

        Will most commonly be used to retrieve Mappables that use one or more
        features with some minimum frequency; e.g.,: get_ids(['fear', 'anxiety'], threshold=0.001)

        Args:
          features: a list of feature names to search on
          threshold: optional float indicating threshold features must pass to be included
          func: any numpy function to use for thresholding (default: sum). The function will be
            applied to the list of features and the result compared to the threshold. This can be
            used to change the meaning of the query in powerful ways. E.g,:
              max: any of the features have to pass threshold (i.e., max > thresh)
              min: all features must each individually pass threshold (i.e., min > thresh)
              sum: the summed weight of all features must pass threshold (i.e., sum > thresh)
          get_weights: boolean indicating whether or not to return weights.

        Returns:
          When get_weights is false (default), returns a list of Mappable names. When true,
          returns a dict, with mappable names as keys and feature weights as values.
        """

        if isinstance(features, str):
            features = [features]
        features = self.search_features(features)  # Expand wild cards
        feature_weights = self.data.ix[:, features]
        weights = feature_weights.apply(func, 1)
        above_thresh = weights[weights >= threshold]
        # ids_to_keep = self.ids[above_thresh]
        return above_thresh if get_weights else list(above_thresh.index)

    def search_features(self, search):
        ''' Returns all features that match any of the elements in the input list. '''
        search = [s.replace('*', '.*') for s in search]
        cols = list(self.data.columns)
        results = []
        for s in search:
            results.extend([f for f in cols if re.match(s + '$', f)])
        return list(set(results))

    def get_ids_by_expression(self, expression, threshold=0.001, func=np.sum):
        """ Use a PEG to parse expression and return mappables. """
        from neurosynth.base import lexparser as lp
        lexer = lp.Lexer()
        lexer.build()
        parser = lp.Parser(
            lexer, self.dataset, threshold=threshold, func=func)
        parser.build()
        return parser.parse(expression).keys()

    def get_features_by_ids(self, ids=None, threshold=0.0001, func=np.mean, get_weights=False):
        ''' Returns features for which the mean loading across all specified studies (in ids)
        is >= threshold. '''
        weights = self.data.ix[ids].apply(func, 0)
        above_thresh = weights[weights >= threshold]
        return above_thresh if get_weights else list(above_thresh.index)

    def _sdf_to_csr(self):
        """ Convert FeatureTable to SciPy CSR matrix because pandas has a weird bug that
        crashes de-serializing when data are in SparseDataFrame. (Bonus: takes up
        less space.) Really need to fix this! """
        data = self.data.to_dense()
        self.data = {
            'columns': list(data.columns),
            'index': list(data.index),
            'values': sparse.csr_matrix(data.values)
        }

    def _csr_to_sdf(self):
        """ Inverse of _sdf_to_csr(). """
        self.data = pd.DataFrame(self.data['values'].todense(), index=self.data['index'],
                            columns=self.data['columns']).to_sparse()


class Animal:
    def __init__(self, name, number_of_legs):
        self.name = name
        self.number_of_legs = number_of_legs

def sort_animals(lst):
    if not lst:
        return []

    sorted_animals = sorted(lst, key=lambda animal: (
        animal.number_of_legs, animal.name))

    return sorted_animals

animal1 = Animal("cat", 4)
animal2 = Animal("spider", 8)
animal3 = Animal("cow", 4)
animal4 = Animal("hen", 2)

animal_list = [animal1, animal2, animal3, animal4]
sorted_animals = sort_animals(animal_list)

for animal in sorted_animals:
    print(animal.name, animal.number_of_legs)


from PyQt5.QtWidgets import QMainWindow, QLabel
from PyQt5.QtCore import QPoint, Qt

from fuzzyclock import FuzzyClock

class SimpleFuzzyClockWindow(QMainWindow):

    def __init__(self, fuzzy_clock=None, size=(190, 35)):
        super().__init__()

        if fuzzy_clock is None:
            self.fuzzy_clock = FuzzyClock()
        else:
            self.fuzzy_clock = fuzzy_clock

        self.main_widget = QMainWindow(self)
        self.setWindowFlags(Qt.FramelessWindowHint)

        self.setFixedSize(size[0], size[1])

        self.label = QLabel(self)
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setStyleSheet("background-color: rgb(0,0,0);"
                                 "color: rgb(0,255,0);"
                                 "font: bold 14pt 'Times New Roman';")

        self.label.setGeometry(0, 0, size[0], size[1])
        self.set_text(text=self.fuzzy_clock.get_time())

        self.old_pos = self.pos()

    def set_text(self, text=""):
        self.label.setText(text)
        self.show()

    def mousePressEvent(self, event):
        self.old_pos = event.globalPos()

    def mouseMoveEvent(self, event):
        movement = QPoint(event.globalPos() - self.old_pos)
        self.move(self.x() + movement.x(), self.y() + movement.y())
        self.old_pos = event.globalPos()

    def update_label(self):
        self.fuzzy_clock.update()
        self.set_text(self.fuzzy_clock.get_time())


from aiogram import types
from aiogram.dispatcher import FSMContext
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton

from data.config import admins
from keyboards.default.menu_keyboards import menu
from keyboards.inline.callback_datas import report_data
from loader import dp, db, bot
from states.menu_states import Reports

@dp.callback_query_handler(text='cancel_filter_change', state=Reports.WaitReport)
async def cancel_report(call: types.CallbackQuery, state: FSMContext):
    """Отмена отправки репорта"""
    await call.message.answer("Отмена", reply_markup=menu)
    await call.message.edit_reply_markup()
    await state.finish()

@dp.message_handler(state=Reports.WaitReport)
async def get_cancel(message: types.Message, state: FSMContext):
    """Нажатие на кнопку Главное меню"""
    report = message.text
    await db.add_report(user_id=message.from_user.id, name=message.from_user.full_name, status_report=False,
                        report=report)
    report_id = await db.sellect_last_report_id()
    for user in admins:
        await bot.send_message(chat_id=user, text=f"Новое сообщение об ошибке!\n\nid репорта: {report_id}\n{report}",
                               reply_markup=InlineKeyboardMarkup(row_width=2,
                                                                 inline_keyboard=[
                                                                     [
                                                                         InlineKeyboardButton(
                                                                             text='Отметить как исправленный',
                                                                             callback_data=report_data.new(
                                                                                report_id=report_id,
                                                                                user_id=message.from_user.id)
                                                                         )
                                                                     ]
                                                                 ]))
    await message.answer('Спасибо за Ваше сообщение!\n'
                         f'Номер Вашего отчета: {report_id}\n'
                         'Мы исправим ошибку в ближайшее время',
                         reply_markup=menu)
    await state.finish()


import sys
import pygame

from pygame.locals import KMOD_CTRL
from pygame.locals import KMOD_SHIFT
from pygame.locals import K_ESCAPE
from pygame.locals import K_F1
from pygame.locals import K_SLASH
from pygame.locals import K_TAB

from pygame.locals import K_h
from pygame.locals import K_i
from pygame.locals import K_q

MAP_DEFAULT_SCALE = 0.1
HERO_DEFAULT_SCALE = 1.0

def exit_game():
    """Shuts down program and PyGame"""
    pygame.quit()
    sys.exit()

class InputControl(object):
    """Class that handles input received such as keyboard and mouse."""

    def __init__(self):
        """Initializes input member variables when instance is created."""
        self.mouse_pos = (0, 0)
        self.mouse_offset = [0.0, 0.0]
        self.wheel_offset = 0.1
        self.wheel_amount = 0.025

        # Modules that input will depend on
        self._hud = None
        self._world = None

    def start(self, hud, world):
        """Assigns other initialized modules that input module needs."""
        self._hud = hud
        self._world = world

    def render(self, display):
        """Does nothing. Input module does not need render anything."""

    def tick(self, clock):
        """Executed each frame. Calls method for parsing input."""
        self.parse_input(clock)

    def _parse_events(self):
        """Parses input events. These events are executed only once when pressing a key."""
        self.mouse_pos = pygame.mouse.get_pos()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit_game()
            elif event.type == pygame.KEYUP:
                if self._is_quit_shortcut(event.key):
                    exit_game()
                elif event.key == K_h or (
                    event.key == K_SLASH and pygame.key.get_mods() & KMOD_SHIFT
                ):
                    self._hud.help.toggle()
                elif event.key == K_TAB:
                    # Toggle between hero and map mode
                    if self._world.hero_actor is None:
                        self._world.select_hero_actor()
                        self.wheel_offset = HERO_DEFAULT_SCALE
                        self._hud.notification("Ego Mode")
                    else:
                        self.wheel_offset = MAP_DEFAULT_SCALE
                        self.mouse_offset = [0, 0]
                        self.mouse_pos = [0, 0]
                        self._world.scale_offset = [0, 0]
                        self._world.hero_actor = None
                        self._hud.notification("Map Mode")
                elif event.key == K_F1:
                    self._hud.show_info = not self._hud.show_info
                elif event.key == K_i:
                    self._world.show_actor_ids = not self._world.show_actor_ids

            elif event.type == pygame.MOUSEBUTTONDOWN:
                # Handle mouse wheel for zooming in and out
                if event.button == 4:
                    self.wheel_offset += self.wheel_amount
                    if self.wheel_offset >= 1.0:
                        self.wheel_offset = 1.0
                elif event.button == 5:
                    self.wheel_offset -= self.wheel_amount
                    if self.wheel_offset <= 0.1:
                        self.wheel_offset = 0.1

    def _parse_mouse(self):
        """Parses mouse input"""
        if pygame.mouse.get_pressed()[0]:
            x, y = pygame.mouse.get_pos()
            self.mouse_offset[0] += (1.0 / self.wheel_offset) * (x - self.mouse_pos[0])
            self.mouse_offset[1] += (1.0 / self.wheel_offset) * (y - self.mouse_pos[1])
            self.mouse_pos = (x, y)

    def parse_input(self, clock):
        """Parses the input, which is classified in keyboard events and mouse"""
        self._parse_events()
        self._parse_mouse()

    @staticmethod
    def _is_quit_shortcut(key):
        """Returns True if one of the specified keys are pressed"""
        return (key == K_ESCAPE) or (key == K_q and pygame.key.get_mods() & KMOD_CTRL)


import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from pytorch_transformers.modeling_bert import BertPooler, BertSelfAttention, BertConfig

from layers.attention import Attention, NoQueryAttention
from layers.squeeze_embedding import SqueezeEmbedding

class GNN(nn.Module):
    def __init__(self, input_dim, hidden_dim, step=2, drop=0.0):
        super(GNN, self).__init__()
        self.step = step
        self.drop = drop
        self.W1 = nn.Parameter(torch.Tensor(input_dim, hidden_dim))
        if input_dim == hidden_dim:
            self.W2 = self.W1
        else:
            self.W2 = nn.Parameter(torch.Tensor(hidden_dim, hidden_dim))
        self.b1 = nn.Parameter(torch.Tensor(hidden_dim))
        if input_dim == hidden_dim:
            self.b2 = nn.Parameter(torch.Tensor(hidden_dim))
        else:
            self.b2 = self.b1

    def forward(self, X, A):
        """B L H, B L L -> B H L"""
        for i in range(self.step):
            if i == 0:
                X = torch.matmul(X, self.W1)
            else:
                X = torch.matmul(X, self.W2)
            normed_A = A / A.sum(1, keepdim=True)[0]
            X = torch.matmul(A, X)
            if i == 0:
                X = X + self.b1
            else:
                X = X + self.b2
            if i < self.step - 1:
                X = F.relu(X)
                if self.drop > 0:
                    X = F.dropout(X)
        return X

class GNN_RELU(nn.Module):
    def __init__(self, input_dim, hidden_dim, step=2, drop=0.0):
        super(GNN_RELU, self).__init__()
        self.step = step
        self.drop = drop
        self.W1 = nn.Parameter(torch.Tensor(input_dim, hidden_dim))
        if input_dim == hidden_dim:
            self.W2 = self.W1
        else:
            self.W2 = nn.Parameter(torch.Tensor(hidden_dim, hidden_dim))
        self.b1 = nn.Parameter(torch.Tensor(hidden_dim))
        if input_dim == hidden_dim:
            self.b2 = nn.Parameter(torch.Tensor(hidden_dim))
        else:
            self.b2 = self.b1

    def forward(self, X, A):
        """B L H, B L L -> B H L"""
        normed_A = A / (A.sum(1, keepdim=True)[0])
        for i in range(self.step):
            if i == 0:
                X = torch.matmul(X, self.W1)
            else:
                X = torch.matmul(X, self.W2)

            X = torch.matmul(normed_A, X)
            if i == 0:
                X = X + self.b1
            else:
                X = X + self.b2
            X = F.relu(X)
            if self.drop > 0:
                X = F.dropout(X)
        return X

class GNN_RELU_DIFF(nn.Module):
    def __init__(self, input_dim, hidden_dim, step=2, drop=0.0):
        super(GNN_RELU_DIFF, self).__init__()
        self.step = step
        self.drop = drop
        self.Ws = nn.ParameterList(
            [nn.Parameter(torch.Tensor(input_dim, hidden_dim))])
        self.bs = nn.ParameterList([nn.Parameter(torch.Tensor(hidden_dim))])
        for i in range(1, step):
            self.Ws.append(nn.Parameter(torch.Tensor(hidden_dim, hidden_dim)))
            self.bs.append(nn.Parameter(torch.Tensor(hidden_dim)))

    def forward(self, X, A):
        """B L H, B L L -> B H L"""
        normed_A = A / (A.sum(1, keepdim=True)[0])
        for i in range(self.step):
            X = torch.matmul(X, self.Ws[i])
            X = torch.matmul(normed_A, X)
            X = X + self.bs[i]
            X = F.relu(X)
            if self.drop > 0:
                X = F.dropout(X)
        return X

class SelfAttention(nn.Module):
    def __init__(self, config, opt):
        super(SelfAttention, self).__init__()
        self.opt = opt
        self.config = config
        self.SA = BertSelfAttention(config)
        self.tanh = torch.nn.Tanh()

    def forward(self, inputs):
        # zero_tensor = torch.tensor(np.zeros((inputs.size(0), 1, 1, self.opt.max_seq_len),
        #                                     dtype=np.float32), dtype=torch.float32).to(self.opt.device)
        zero_tensor = 0
        SA_out = self.SA(inputs, zero_tensor)
        return self.tanh(SA_out[0])

class LayerNorm(nn.Module):
    "Construct a layernorm module (See citation for details)."

    def __init__(self, features, eps=1e-6):
        super(LayerNorm, self).__init__()
        self.a_2 = nn.Parameter(torch.ones(features))
        self.b_2 = nn.Parameter(torch.zeros(features))
        self.eps = eps

    def forward(self, x):
        mean = x.mean(-1, keepdim=True)
        std = x.std(-1, keepdim=True)
        return self.a_2 * (x - mean) / (std + self.eps) + self.b_2

class BERT_ALBERT_GCN(nn.Module):
    """
    bert:做encoder 输入：context_asp_ids, context_asp_seg_ids, context_asp_att_mask, adj_matrix, start, end, polarity
    glove+bom做encoder 输入同上 init 时需要embedding_matrix_pkl(conf.tokenizer_pkl),需要embedding层
    除encoder层外一样，能够控制是否加入 pos+pct gnn+pct short_cut
                    /-------short cut +-------\  /---no sa---\
    squeeze -> bert -> norm + gcn -> pct + gelu -> sa + tanh -> bert_pooler -> fc -> logits
    """

    def __init__(self, bert_or_embedding_matrix, opt):
        super(BERT_ALBERT_GCN, self).__init__()
        self.opt = opt
        bert = bert_or_embedding_matrix
        self.context_bert = bert
        self.squeeze_embedding = SqueezeEmbedding()
        if not opt.no_gnn:
            self.gcn = GNN_RELU_DIFF(opt.bert_dim, opt.bert_dim,
                                     step=opt.gnn_step, drop=0.0)
            self.encoder_fn = nn.Linear(opt.bert_dim, opt.bert_dim)
            self.norm = LayerNorm(opt.bert_dim)
        if not opt.no_sa:
            self.bert_self_att = SelfAttention(bert.config, opt)
        if self.opt.pool_tp == 'bert_pool':
            self.bert_pooler = BertPooler(bert.config)
        elif self.opt.pool_tp == 'max_pool':
            self.pool_fc = nn.Linear(opt.bert_dim, opt.bert_dim)
        self.fc = nn.Linear(opt.bert_dim, 3)

    def forward(self, inputs):
        # 解开inputs:context=text+asp
        context, context_seg = inputs[0], inputs[1]
        asp_start, asp_end, adj_matrixs = inputs[2], inputs[3], inputs[4]
        attention_mask = inputs[5]
        for e in inputs:
            assert not torch.isnan(e).any()
        # 获得context_len ,并进行squeezeEmbedding
        context_len = torch.sum(context != 0, dim=-1).long()
        context = self.squeeze_embedding(context, context_len)
        context_ids = context
        context_seg = self.squeeze_embedding(context_seg, context_len)
        attention_mask = self.squeeze_embedding(attention_mask, context_len)
        # context 进行 bert/glove encode
        context, _ = self.context_bert(
            context, context_seg, attention_mask)

        if not self.opt.no_gnn:
            batch_size, seq_len = context.size()[:-1]
            # +short_cut(
            highway = context
            context = self.norm(context)

            # +gnn【cls sep连所有，context按照语法树连成无向图，asp连所有】
            A = adj_matrixs[:, :seq_len, :seq_len]
            context = self.gcn(context, A)

            # + pct + gelu
            context = self.encoder_fn(context)
            context = F.gelu(context)

            # +short_cut)
            if not self.opt.no_short_cut:
                context += highway

        # + sa
        if not self.opt.no_sa:
            rep = self.bert_self_att(context)
        else:
            rep = context
        # + bert_pooler
        if self.opt.pool_tp == 'bert_pool':
            rep = self.bert_pooler(rep)
        elif self.opt.pool_tp == 'max_pool':
            # B L
            mask = torch.zeros(rep.size()[:-1]).to(self.opt.device)
            for i, (seq, s, e, true_len) in enumerate(zip(context_ids, asp_start, asp_end, context_len)):
                seq = seq.tolist()
                first_sep_idx = seq.index(102)
                mask[i, 0] = 1
                mask[i, s:e] = 1
                mask[i, first_sep_idx + 1:true_len] = 1
            rep = rep * mask.unsqueeze(-1)  # B L H * B L 1-->B L H
            rep = rep.max(1)[0]  # B H
            rep = self.pool_fc(rep)
            rep = F.tanh(rep)
        # fc
        out = self.fc(rep)
        return out


'''
문제
정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 4가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다. 합을 이루고 있는 수의 순서만 다른 것은 같은 것으로 친다.

1+1+1+1
2+1+1 (1+1+2, 1+2+1)
2+2
1+3 (3+1)
정수 n이 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법의 수를 구하는 프로그램을 작성하시오.

입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 n이 주어진다. n은 양수이며 10,000보다 작거나 같다.

출력
각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 출력한다.
'''

import sys
T = int(sys.stdin.readline())
ns = [int(sys.stdin.readline()) for _ in range(T)]
n = max(ns)
dp = [1]+[0]*n
for i in range(1, 3+1):
    for k in range(1, n+1):
        if k < i: continue
        dp[k] += dp[k-i]
print(*[dp[i] for i in ns])


#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from PySide import QtGui, QtCore
import controller
from ventana_nuevacategoria import *

class Form_2(QtGui.QWidget):

    def __init__(self, parent=None):
        super(Form_2, self).__init__()
        self.ventana = Ui_ventana_nuevacategoria()
        self.ventana.setupUi(self)
        self.ventana.btn_aceptar.clicked.connect(self.aceptar)
        self.ventana.btn_cancelar.clicked.connect(self.cancelar)
        self.codigo = ""
        self.var = 0

        self.show()

    def carga(self, categoria, codigo):
        self.codigo = codigo
        self.ventana.id_categoria.setText(str(categoria[0][0]))
        self.ventana.nombre_categoria.setText(categoria[0][1])
        self.ventana.descripcion_categoria.setText(categoria[0][2])
        self.var = 1

    def aceptar(self):
        id_cate = self.ventana.id_categoria.text()
        nombre = self.ventana.nombre_categoria.text()
        descrip = self.ventana.descripcion_categoria.text()
        var = 1

        datos = (id_cate, nombre, descrip)
        cod2 = self.codigo

        if(self.var == 1):

            controller.reescribeProducto(datos, cod2)

        self.close()

    def cancelar(self):
        self.close()


from django.shortcuts import render

# Create your views here.
# start game fonk

def start_game(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        image = request.FILES.get('image')
        puzzle = generate_puzzle(image)
        request.session['name'] = name
        request.session['puzzle'] = puzzle
        request.session['moves'] = 0
        request.session['start_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        return redirect('game')
    return render(request, 'game/start_game.html')

# play game fonk

from django.shortcuts import render, redirect
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import Player, Puzzle

def play_game(request):
    if request.method == 'POST':
        player_name = request.POST.get('player_name')
        puzzle_id = request.POST.get('puzzle_id')
        player_score = int(request.POST.get('player_score'))
        player, created = Player.objects.get_or_create(name=player_name)
        if not created:
            player.score += player_score
            player.save()
        puzzle = Puzzle.objects.get(id=puzzle_id)
        puzzle.correct += 1
        if puzzle.correct == puzzle.rows * puzzle.cols:
            puzzle.status = 'solved'
        puzzle.save()
        return JsonResponse({'success': True})
    else:
        puzzles = Puzzle.objects.all()
        context = {'puzzles': puzzles}
        return render(request, 'play_game.html', context)

#

from django.shortcuts import render
from django.http import HttpResponse
from django.core.files.storage import FileSystemStorage
from PIL import Image
import io

from .models import Player, Score

def home(request):
    if request.method == 'POST':
        # Get player name and uploaded image
        player_name = request.POST.get('player_name')
        uploaded_image = request.FILES.get('image')

        # Save the player
        player = Player(name=player_name)
        player.save()

        # Convert uploaded image to puzzle format
        image = Image.open(uploaded_image)
        cropped_images = []
        width, height = image.size
        cropped_width, cropped_height = width // 4, height // 4
        for i in range(4):
            for j in range(4):
                box = (j * cropped_width, i * cropped_height, (j + 1) * cropped_width, (i + 1) * cropped_height)
                cropped_images.append(image.crop(box))

        # Shuffle cropped images
        import random
        random.shuffle(cropped_images)

        # Save cropped images
        fs = FileSystemStorage()
        image_paths = []
        for i, cropped_image in enumerate(cropped_images):
            file_name = f"{player.id}_{i}.png"
            file_path = fs.save(file_name, io.BytesIO())
            image_paths.append(file_path)

        # Render game page
        context = {
            'player_id': player.id,
            'image_paths': image_paths,
        }
        return render(request, 'game.html', context)
    else:
        return render(request, 'home.html')

def save_score(request):
    if request.method == 'POST':
        # Get player and score
        player_id = request.POST.get('player_id')
        score = request.POST.get('score')

        # Save the score
        player = Player.objects.get(id=player_id)
        score = Score(player=player, score=score)
        score.save()

        return HttpResponse('Score saved!')
    else:
        return HttpResponse('Invalid request!')

#

from django.shortcuts import render, redirect
from .forms import StartGameForm
from .utils import convert_to_puzzle
import time

def start_game(request):
    """
    Starts the puzzle game.
    """
    if request.method == 'POST':
        form = StartGameForm(request.POST, request.FILES)
        if form.is_valid():
            name = form.cleaned_data.get('name')
            image = form.cleaned_data.get('image')
            puzzle = convert_to_puzzle(image)
            if puzzle:
                request.session['name'] = name
                request.session['puzzle'] = puzzle
                request.session['moves'] = 0
                request.session['start_time'] = time.time()
                request.session['game_over'] = False
                request.session.modified = True
                return redirect('game')
    else:
        form = StartGameForm()

    return render(request, 'start_game.html', {'form': form})

from django.shortcuts import render, redirect
from django.http import HttpResponse
from PIL import Image

def play(request):
    if request.method == 'POST':
        name = request.POST['name']
        image = request.FILES['image']

        # Yüklenen görseli yeniden boyutlandırma
        size = (480, 480)
        im = Image.open(image)
        im_resized = im.resize(size)

        # Yeniden boyutlandırılmış görseli geçici bir dosyada kaydetme
        im_resized_path = f'media/images/{name}.jpg'
        im_resized.save(im_resized_path, "JPEG")

        # Puzzle'ı oluşturma
        puzzle = create_puzzle(im_resized_path)

        # Skorları getirme
        scores = Score.objects.all().order_by('-score')[:10]

        context = {
            'name': name,
            'puzzle': puzzle,
            'scores': scores
        }

        return render(request, 'play.html', context)

    else:
        return redirect('home')

#from django.shortcuts import render
from .models import Puzzle

def puzzle(request):
    if request.method == 'POST':
        size = int(request.POST.get('size'))
        if size < 2:
            size = 2
        elif size > 10:
            size = 10
        puzzle = Puzzle(size)
        puzzle.create_solution()
        puzzle.shuffle()
        request.session['puzzle'] = puzzle
    elif request.method == 'GET':
        puzzle = request.session.get('puzzle')
        if not puzzle:
            puzzle = Puzzle(4)
            puzzle.create_solution()
            puzzle.shuffle()
            request.session['puzzle'] = puzzle

    board = puzzle.get_board()
    context = {
        'board': board,
        'size': puzzle.size,
        'moves': puzzle
    }

#

from django.shortcuts import render

def home(request):
    return render(request, 'home.html')


import altair as alt
import math
import pandas as pd
import streamlit as st
from PIL import Image

"""
# Which German Business Sector are you?

Take this personality quiz to find out which part of the Volkswirtschaft is your spirit animal.

This uses clustering from the ifo Business Climate Survey taken by thousands of businesses monthly to determine which sector you're responses are most similar to.
Are you the high-tech industry embodied or heavy industry personified? People have chosen careers over less.
"""
#st.set_page_config(page_title='Which Business Sector are you?', page_icon=':heart:')
# QUESTION 1
st.title('How was lunch?')
vg_statebus = st.radio(
"We evaluate our state of business to be",
('Good', 'Satisfiable', 'Bad'))
if vg_statebus == 'Good':
    vg_statebus_index = 1
if vg_statebus == 'Satisfiable':
    vg_statebus_index = 2
    st.text('7/10')
if vg_statebus == 'Bad':
    vg_statebus_index = 3
    st.text('Ooof')

#vg_statebus = give_choice(['Good', 'Satisfiable', 'Bad'])

# QUESTION 2
st.title('How oldschool are you?')
online = st.radio(
    "I would filled out the ifo survey via",
    ("Paper", "Fax", "Online", "Manual collection"))

#assign integers to answers as in ifo survey
if online == 'Paper':
    online_index = 0
if online == 'Fax':
    online_index =  1
    st.text('They said in the Buzzfeed survey')
if online == 'Online' :
    online_index = 2
    st.text('THANK YOU; FINALLY A NORMAL PERSON')
if online == 'Manual collection':
    online_index = 5
    st.text('Fighting unemployment one special request at a time')

# QUESTION 3
st.title('U scared yet?')
vg_comexp = st.radio(
"During the next 6 months our business operation will be",
('Favourable', 'Not changing', 'Unfavourable'))
#assign integers to answers as in ifo survey
if vg_comexp == 'Favourable':
    vg_comexp_index = 1
if vg_comexp == 'Not changing':
    vg_comexp_index = 2
    st.text('Dream on')
if vg_comexp == 'Unfavourable':
    vg_comexp_index = 3
    st.text('You betcha')

# QUESTION 4
st.title('When did you first become important enough that ifo would care about you?')
age = st.radio(
"",
('Before 1980', 'Before 2000', 'After 2000'))
if age == 'Before 1980':
    age_index=0
if age == 'Before 2000':
    age_index=1
    st.text('TikTok is werid, right?')
if age == 'After 2000':
    image = Image.open('images/lindner.webp')
    st.image(image, width = 300)
    age_index=2

# QUESTION 5
st.title('How greedy are you?')
vg_price = st.radio(
"Our prices in the next 3 months will expectedly be",
('Rising', 'Not changing', 'Falling'))
if vg_price == 'Rising':
    vg_price_index = 1
if vg_price == 'Not changing':
    vg_price_index = 2
    st.text('In this economy?')
if vg_price == 'Falling':
    vg_price_index = 3
    st.text('The unwashed masses thank you')

# QUESTION 6
st.title('Are you hot or not?')
vg_demand_vpq = st.radio(
"In the last 3 months the demand situation has been",
('Rising', 'Not changing', 'Falling'))
if vg_demand_vpq == 'Rising':
    vg_price_index = 1
if vg_demand_vpq == 'Not changing':
    vg_price_index = 2
    st.text('You got it guuurl!')
if vg_demand_vpq == 'Falling':
    vg_price_index = 3
    st.text('We will always love you.')

# QUESTION 7
st.title('Labour exploitation attitudes')
vg_demand_vpq = st.radio(
"The number of your employees will be",
('Increasing', 'Not changing', 'Decreasing'))
if vg_demand_vpq == 'Increasing':
    vg_price_index = 1
if vg_demand_vpq == 'Not changing':
    st.text('Coward.')
    vg_price_index = 2
if vg_demand_vpq == 'Decreasing':
    vg_price_index = 3
    st.text('Our condolences.')

data = pd.read_csv("average_answers_by_sector.csv",engine='python')

# Form responses as in the same format as the ifo survey
our_responses = {'vg_statebus': vg_statebus_index,
                'vg_comexp': vg_comexp_index,
                'vg_priceexp': vg_price_index,
                'is_fax': online_index == 1, # Should be 1 if the respondent answered by fax
                'is_online': online_index == 2, # Should be 1 if the respondent answered online
                'is_neither_online_fax': online_index != 1 and online_index != 2, # Otherwise
                'vg_demand_vpq':vg_price_index,
                'vg_emplexp': 1,
                'year_binned': age_index # AKA age_index 0 if before 1980, 1 if before 2000, 2 otherwise
               }

# This gets the row with the smallest L1 distance to our_responses in the dataframe.
# It output is min_distance_sector wz93 sector code

data['sector'] = data['sector'].replace('0.', '0')
data['sector'] = data['sector'].replace('na', '0')
data['sector'] = data['sector'].astype(int)

#create sector names and assigning them to the variable
sector_names = {
    0: "no sector",
    15: "Food and Drinks",
    16: 'Tobacco',
    17: 'Textiles',
    18: 'Clothing',
    19: 'Leather Goods',
    20: 'Wooden Stuff',
    21: 'Paper Stuff',
    22: 'Media',
    23: 'Energy',
    24: 'Chemicals',
    25: 'Rubber and Plastic Stuff',
    26: 'Other Non Metallic Stuff',
    27: 'Basic Metals',
    28: 'Some Metal Products',
    29: 'Machinery and equipment',
    30: 'Office and Computer',
    31: 'Electrical Machinery',
    32: 'Communication Equipment',
    33: 'Precision Instruments',
    34: 'Motor Vehicles',
    35: 'Other Transport',
    36: 'Furniture',
}

data['sector_name'] = data['sector'].map(sector_names)

min_distance_sector = None
min_distance = 1000
for index, row in data.iterrows():
    distance = 0
    for key, value in our_responses.items():
        distance += abs(value - row[key])
    if distance < min_distance and row['sector'] != 0:
        min_distance = distance
        min_distance_sector = row['sector']

show_checkbox = st.checkbox('Show result')

if show_checkbox:
    st.title("Sector number " + str(min_distance_sector) + ": " + sector_names[min_distance_sector])
    if min_distance_sector == 15:
        im_path = '1.jpeg'
    elif min_distance_sector == 16:
        im_path = 'pipe.jpeg'
    elif min_distance_sector == 17:
        im_path = 'clothes.jpeg'
    elif min_distance_sector == 18:
        im_path = 'clothes.jpeg'
    elif min_distance_sector == 19:
        im_path = 'leather.jpeg'
    elif min_distance_sector == 21:
        im_path = 'forest.jpeg'
    elif min_distance_sector == 22:
        im_path = 'propaganda.jpeg'
    elif min_distance_sector == 23:
        im_path = 'nukes.jpeg'
    elif min_distance_sector == 24:
        im_path = 'oil.jpeg'
    elif min_distance_sector == 25:
        im_path = 'oil.jpeg'
    elif min_distance_sector == 26:
        im_path = 'mine.jpeg'
    elif min_distance_sector == 28:
        im_path = 'machines.jpeg'
    elif min_distance_sector == 29:
        im_path = 'machines.jpeg'
    elif min_distance_sector == 30:
        im_path = 'nerd.jpeg'
    elif min_distance_sector == 31:
        im_path = 'satelite.jpeg'
    elif min_distance_sector == 32:
        im_path = 'satelite.jpeg'
    elif min_distance_sector == 33:
        im_path = 'machines.jpeg'
    elif min_distance_sector == 34:
        im_path = 'transrapid.jpeg'
    elif min_distance_sector == 35:
        im_path = 'transrapid.jpeg'
    elif min_distance_sector == 36:
        im_path = 'furniture.jpeg'
    else:
        im_path=''
    if len(im_path) > 0:
        image = Image.open("images/"+im_path)
        st.image(image, width = 600)


# https://www.youtube.com/watch?v=8Qk2M1Jy-Mg&t=1641s

from tkinter import *
from database import *

def add():
    line = id.get()+'-'+name.get()+'-'+year.get()
    save(line)
    show()

def show():
    sv = read()
    listbox.delete(0,END)
    for i in sv:
        listbox.insert(END,i)

def sort():
    sv=read()
    for i in range(len(sv)):
        for j in range(len(sv)):
            x,y = sv[i],sv[j]
            if x[2]>y[2]:
                sv[i], sv[j] = y,x
    listbox.delete(0,END)
    for i in sv:
        listbox.insert(END,i)

root = Tk()
#khai báo bien Var
id = StringVar()
name = StringVar()
year = StringVar()

root.title("quản li sinh viên")
root.minsize(height=500,width=500)

Label(root,text="Ứng dụng quản lí sinh viên",fg='red',font=('cambria',16),width=20).grid(row=0)
listbox= Listbox(root,width=80,height=20)
listbox.grid(row=1,columnspan=2)
show()

Label(root,text="MSV: ").grid(row=2,column=0)
Entry(root,width=40,textvariable=id).grid(row=2,column=1)

Label(root,text="Tên SV: ").grid(row=3,column=0)
Entry(root,width=40,textvariable=name).grid(row=3,column=1)

Label(root,text="Năm sinh: ").grid(row=4,column=0)
Entry(root,width=40,textvariable=year).grid(row=4,column=1)

button = Frame(root)
Button(button,text = 'Thêm',command=add).pack(side=LEFT)
Button(button,text = 'Xem',command=show).pack(side=LEFT)
Button(button,text = 'Sắp xếp',command=sort).pack(side=LEFT)
Button(button,text = 'Thoát',command=root.quit).pack(side=LEFT)
button.grid(row=5,column=1)

root.mainloop()


def fibonacci(n,zero=0,one=0):
    if vis[n]:
        return dp[n]
    vis[n] = 1

    if n == 0:
        dp[n] = [1,0]
        return [1,0]
    if n == 1:
        dp[n] = [0,1]
        return [0,1]

    first = fibonacci(n-1)
    second = fibonacci(n-2)
    dp[n][0] = first[0] + second[0]
    dp[n][1] = first[1] + second[1]
    return dp[n]

dp = [[0]*2 for _ in range(41)]
vis = [0]*41
fibonacci(40)

for T in range(int(input())):
    for i in dp[int(input())]:
        print(i, end=' ')
    print('')


# -*- coding: utf-8 -*-

"""
@File    : balancedString.py
@Author  : wenhao
@Time    : 2023/2/13 9:26
@LC      : 1234
"""
from math import inf
from collections import Counter

class Solution:
    '''
    思路：
    同向双指针：
    '''
    def balancedString(self, s: str) -> int:
        cnt, m = Counter(s), len(s)
        if all(cnt[x] == m for x in "QWER"):
            return 0
        ans, left = inf, 0
        for right, c in enumerate(s):
            cnt[c] -= 1
            while all(cnt[x] <= m for x in "QWER"):
                ans = min(ans, right - left + 1)
                cnt[s[left]] += 1
                left += 1
        return ans


#!/usr/bin/env python3

"""
trivial strategy
"""

import archon.config as config
import traceback
from datetime import datetime

#import archon.broker as broker
from archon.brokersrv.brokerservice import BrokerService
import archon.exchange.exchanges as exc
import archon.exchange.bitmex.bitmex as mex
import archon.exchange.bitmex.book_util as book_util
import archon.exchange.bitmex.timeseries as timeseries
import archon.broker.facade as facade
import archon.model.models as models
from archon.custom_logger import setup_logger, remove_loggers
import archon.orders as orders
from archon.util import *

import pandas as pd
import numpy

import time
import json
import atexit
import logging
import threading

from abc import ABC, abstractmethod

from strat import Strategy

class TrivialStrategy(Strategy):

    def __init__(self, abroker, mex_sym, order_qty, zoff):
        setup_logger(logger_name=__name__, log_file=__name__ + '.log')
        self.log = logging.getLogger(__name__)
        self.log.info('marb strategy')

        remove_loggers()

        # init data
        self.book_mex = None
        self.pos_qty = 0

        self.zoff = zoff # the offset in $
        self.diff_cancel = 1.0 # cancel if diff is larger than this
        self.order_qty = order_qty

        super().__init__(abroker, mex_sym)

    def calc_mid(self, book):
        print (book)
        bids = list(filter(lambda x: x['side']=='Buy', book))
        asks = list(filter(lambda x: x['side']=='Sell', book))
        print (">>>> " ,bids[0])
        #, asks)
        mb = bids[0]
        ma = asks[0]
        mid = (mb['price'] + ma['price'])/2
        return mid

    def round_tick(self, price):
        """ round to bitmex tick size of 0.50$ """
        ip = round(price,0)
        if ip > price: ip=ip-1
        rest = price - ip
        r = -1
        if rest > 0.5 and rest <= 0.75:
            r = ip + 0.5
        elif rest > 0.75:
            r = ip
        elif rest <= 0.5:
            r = ip
        return r

    def calc_quotes(self):
        """ calculate one buy and sell quote
        trivial offset from bid and ask"""

        bids = list(filter(lambda x: x['side']=='Buy', self.book))
        asks = list(filter(lambda x: x['side']=='Sell', self.book))
        da = asks[0]['price']
        db = bids[0]['price']

        FV = self.calc_mid(self.book)

        buyorder = None
        sellorder = None

        oq = self.zoff #offset parameter in $

        qty = self.order_qty
        target_price = self.round_tick(FV - oq) # offset from mid
        order = [orders.ORDER_SIDE_BUY, qty, target_price]
        buyorder = order

        qty = self.order_qty
        target_price = self.round_tick(FV + oq) # offset from mid
        order = [ orders.ORDER_SIDE_SELL, qty, target_price]
        sellorder = order

        return [buyorder, sellorder]

    def replace_order(self, old_order, new_order):
        oid = old_order['orderID']
        result = self.abroker.cancel_order(oid, exc.BITMEX)
        return result
        #self.submit_order(new_order)

    def order_str(self, o):
        s = "%s %5.3f %5.3f"%(o['side'],o['orderQty'],o['price'])
        return s

    def handle_no_position(self):
        self.log.info("handle_no_position")
        target_orders = self.calc_quotes()
        self.log.info("target orders %s"%target_orders)
        #TODO adjust orders instead
        oo = abroker.openorders(exc.BITMEX)
        self.log.info("open orders %s"%str(oo))

        buys = list(filter(lambda x: x['side']=='Buy', oo))
        sells = list(filter(lambda x: x['side']=='Sell', oo))
        [target_buyorder, target_sellorder] = target_orders

        # if existing orders adjust orders by checking against targets

        if len(buys) > 0:
            for o in buys:
                self.log.info("check order %s"%str(o))
                dif = target_buyorder[2] - o['price']
                self.log.info("order dif %s"%str(dif))
                if dif >= 1:
                    self.log.info("price too low. cancel")
                    self.replace_order(o, target_buyorder)

                elif dif <= -1:
                    self.log.info("price too high. cancel")
                    self.replace_order(o, target_buyorder)

                else:
                    self.log.info("price of existing order ok")

        if len(sells) > 0:
            for o in sells:
                self.log.info("check order %s"%self.order_str(o))
                dif = target_sellorder[2] - o['price']
                self.log.info("order dif %s"%str(dif))
                if dif >= self.diff_cancel:
                    self.log.info("price too low. cancel")
                    self.replace_order(o, target_sellorder)

                elif dif <= -self.diff_cancel:
                    self.log.info("price too high. cancel")
                    self.replace_order(o, target_sellorder)

                else:
                    self.log.info("price of existing order ok")

        if len(buys) == 0:
            for order in [target_buyorder]:
                #TODO cleanup order array to dict
                ttype = order[0]
                market = self.mex_sym
                qty = order[1]
                order_price = order[2]
                order = [market,ttype,order_price,qty]
                result = self.abroker.submit_order_post(order, exc.BITMEX)
                self.log.info("order result %s"%str(result))
                time.sleep(1)

        if len(sells) == 0:
            for order in [target_sellorder] :
                #TODO cleanup order array to dict
                ttype = order[0]
                market = self.mex_sym
                qty = order[1]
                order_price = order[2]
                order = [market,ttype,order_price,qty]
                result = self.abroker.submit_order_post(order, exc.BITMEX)
                self.log.info("order result %s"%str(result))
                time.sleep(1)

    def handle_position(self):
        #TODO same with skew
        return

    def handle_books(self, mexbook):
        self.log.info("handle books")
        #db = self.abroker.get_db()
        #db.books.insert_one({"orderbook":mexbook})

        self.book = mexbook
        #self.update_orders()

        #book_util.display_book(self.book)
        mid = self.calc_mid(self.book)
        self.log.info("mid price %s"%str(mid))

        pos = abroker.position(exc.BITMEX)
        try:
            self.pos_qty = int(pos[0]['currentQty'])
        except:
            self.pos_qty = 0

        got_max_position = self.pos_qty > 50
        oo = abroker.openorders(exc.BITMEX)
        self.log.info("finished setting data")

        if len(oo)>4:
            self.log.info("too many orders")
            #self.cancel_all()
            self.alive_flag = False
            return

        self.log.info("got_max_position %s"%str(got_max_position))

        if got_max_position:
            #self.handle_position()
            self.log.info("todo...")
            self.alive_flag = False
            return

        else:
            self.handle_no_position()

if __name__=='__main__':
    #todo register exit handler
    #atexit.register(clean_exit)

    try:
        #assume service is running, this is just a proxy
        abroker = BrokerService(setAuto=True,initFeeder=False)
        abroker.set_keys_exchange_file(exchanges=[exc.BITMEX])
        mex_sym = mex.instrument_btc_perp
        zoff = 1.0
        order_qty = 1.0
        strategy = TrivialStrategy(abroker, mex_sym, order_qty, zoff)
        strategy.start()
        strategy.join()
    except Exception as e:
        traceback.print_exc()


# -*- coding: utf-8 -*-
"""
Created on Wed Jan  5 21:46:21 2022

@author: Cumali Atalan
"""

#%%

#gerekli kütüphaneler import edilir.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from collections import Counter
from tensorflow import keras
from keras.models import Sequential,load_model
from keras.layers import Dense,GlobalAveragePooling2D,Flatten,Conv2D,BatchNormalization,Dropout,MaxPooling2D,Activation
from keras.preprocessing import image
from keras.preprocessing.image import ImageDataGenerator as Imgen

from PIL import Image
from sklearn.metrics import confusion_matrix,classification_report

import os

import warnings
warnings.filterwarnings("ignore")

#%%

#verilerin adresi verilir.
train_csv = pd.read_csv("C:\\Users\\tr\\Desktop\\input\\plant-pathology-2021-fgvc8\\train.csv")
train_path = "C:\\Users\\tr\\Desktop\\input\\plant-pathology-2021-fgvc8\\train_images"
test_path = "C:\\Users\\tr\\Desktop\\input\\plant-pathology-2021-fgvc8\\test_images"

#%%
#veriler hakkında bilgi alınır.
train_csv.head(3)
train_csv.info()

#%%

#verilerin içerisinde hangi etikette kaç veri olduğu konsola yazdırılır.
etiketler = train_csv["labels"].value_counts().index
veri = train_csv["labels"].value_counts().values

print(veri)
#%%
# veriler etiketlerine göre pasta grafiğinde gösterilir.

"""
explode = (0, 0.1, 0, 0,0,0,0,0,0,0,0,0)
pie, ax = plt.subplots(figsize=[10,6])
plt.pie(x=data, autopct="%.1f%%",explode=explode, labels=labels, pctdistance=0.5)
plt.title("Delivery Tips by type", fontsize=14);
pie.savefig("DeliveryPieChart.png")
"""

#%%
#her etiket bir class olarak ayrılır.
class_numarasi = len(train_csv["labels"].value_counts())

#%%

# verilerin ön işlemesi yapılır.
# xception'a göre ağırlıklar önceden verilir.
datagen = Imgen(preprocessing_function=keras.applications.xception.preprocess_input,
                 rotation_range=4,
                  shear_range=0.2,
                  zoom_range=0.15,
                  horizontal_flip=True,
                  validation_split=0.2
                 )

#%%
# datagende işlenen verilerin öğrenimi için gerekli veriler verilir.
train_ds = datagen.flow_from_dataframe(
    train_csv,
    directory = train_path, #nereden alacak veriyi
    x_col = 'image',
    y_col = 'labels',
    subset="training",
    color_mode="rgb",
    target_size = (224,224),
    class_mode="categorical",
    batch_size=32,
    shuffle=True,
    seed=123
)
#%%
# datagende işlenen verilerin doğrulaması için gerekli veriler verilir.
val_ds = datagen.flow_from_dataframe(
    train_csv,
    directory = train_path,
    x_col = 'image',
    y_col = 'labels',
    subset="validation",
    color_mode="rgb",
    target_size = (224,224),
    class_mode="categorical",
    batch_size=32,
    shuffle=True,
    seed=123
)

#%%
# np dizileri oluşturulur.
x,y = next(train_ds)
x.shape
#%%
from tensorflow.keras.applications.vgg16 import VGG16

# model olarak VGG16 kullanıyorum.
vgg = VGG16()
#%%
model = Sequential()
vgg_layers = vgg.layers # vgg modelinde katmanları tanımlıyorum.

for i in range(len(vgg_layers)-1):
    model.add(vgg_layers[i])
    #katmanlar modele ekleniyor.
#%%
model.build(x.shape)
model.summary()
#%%

#katman özellikleri aktif ediliyor.

for l in vgg_layers:
    l.trainable = True

#%%

# aktivasyonu softmax olan dense katmanları ekleniyor.

model.add(Dense(class_numarasi, activation="softmax"))
model.summary()
#%%

# model tamamlanırken accuracy'e göre ölçüm yapması bekleniyor.

model.compile(loss = "categorical_crossentropy" , optimizer = "adam" , metrics=["accuracy"])
batch_size = 32

# epoch sayısı verilir. ve her epochta kaç veri işleneceği belirtilir.
# 14900 görseli batch_size bölüp hep epochta öğrenimi işlenecek veri sayısı belirtilir.
# 3700 görseli batch_size bölüp hep epochta doğrulaması işlenecek veri sayısı belirtilir.

#öğrenme başlatılır.
hist = model.fit_generator(train_ds,
                           steps_per_epoch = 14900//batch_size,
                           epochs = 15,
                           validation_data = val_ds,
                           validation_steps = 3700//batch_size)

#%%

#öğrenme ve doğrulama oranları tablolaştırılır.
plt.plot(hist.history["accuracy"],label = "training accuracy")
plt.plot(hist.history["val_accuracy"],label = "validation accuracy")


import copy
import sys

sys.modules['_decimal'] = None
import decimal
from decimal import *
from decimal import Decimal

getcontext().Emin = -10 ** 10000
getcontext().Emax = 10 ** 10000
getcontext().traps[Overflow] = 0
getcontext().traps[Underflow] = 0
getcontext().traps[DivisionByZero] = 0
getcontext().traps[InvalidOperation] = 0
getcontext().prec = 100

POSSIBLE_OPERATIONS: list = ["INTERSECT", "UNION"]

def is_operation(a_str: str) -> bool:
    return a_str in POSSIBLE_OPERATIONS

def graph_exists(a_str, graph_list):
    # type: (str, list) -> bool
    for graph in graph_list:
        if graph.name == a_str:
            return True

    return False

def evaluate_expression(expr, graph_list):
    # type: (str, list) -> Graph
    nodes: list = []  # initial value
    whitespace: str = " "
    values: list = expr.split(whitespace)
    for value in values:
        if is_operation(value):
            nodes.append(OperationNode(value))
        elif graph_exists(value, graph_list):
            # Getting the corresponding graph
            corresponding_graph: Graph or None = None  # initial value
            for graph in graph_list:
                if graph.name == value:
                    corresponding_graph = graph
                    break

            nodes.append(GraphNode(corresponding_graph))

    while len(nodes) > 1:
        first_graph: Graph = nodes[0].evaluate(nodes[1], nodes[2])
        temp_list: list = [GraphNode(first_graph)]  # initial value
        for i in range(3, len(nodes)):
            temp_list.append(nodes[i])

        nodes = temp_list

    return nodes[0].value

class Node:
    """
    This class contains attributes of nodes to store data
    """

    def __init__(self):
        self.value = None

class GraphNode(Node):
    """
    This class contains attributes of nodes to store graphs.
    """

    def __init__(self, value):
        # type: (Graph) -> None
        super(GraphNode, self).__init__()
        self.value: Graph = value

    def evaluate(self, operation_node, graph_node):
        # type: (OperationNode, GraphNode) -> Graph
        new_graph: Graph = Graph()
        if operation_node.value == "INTERSECT":
            for link in self.value.links:
                # Getting the corresponding link
                corresponding_link: Link or None = None  # initial value
                for curr_link in graph_node.value.links:
                    if (curr_link.from_vertex == link.from_vertex and curr_link.to_vertex == link.to_vertex) or \
                            (curr_link.from_vertex == link.to_vertex and curr_link.to_vertex == link.from_vertex):
                        corresponding_link = curr_link
                        break

                if corresponding_link is not None:
                    to_add: Link = corresponding_link if corresponding_link.weight > link.weight else link
                    new_graph.add_link(to_add)

        elif operation_node.value == "UNION":
            for link in self.value.links:
                # Getting the corresponding link
                corresponding_link: Link or None = None  # initial value
                for curr_link in graph_node.value.links:
                    if (curr_link.from_vertex == link.from_vertex and curr_link.to_vertex == link.to_vertex) or \
                            (curr_link.from_vertex == link.to_vertex and curr_link.to_vertex == link.from_vertex):
                        corresponding_link = curr_link
                        break

                if corresponding_link is not None:
                    to_add: Link = corresponding_link if corresponding_link.weight > link.weight else link
                    new_graph.add_link(to_add)
                else:
                    new_graph.add_link(link)

            for link in graph_node.value.links:
                # Getting the corresponding link
                corresponding_link: Link or None = None  # initial value
                for curr_link in self.value.links:
                    if (curr_link.from_vertex == link.from_vertex and curr_link.to_vertex == link.to_vertex) or \
                            (curr_link.from_vertex == link.to_vertex and curr_link.to_vertex == link.from_vertex):
                        corresponding_link = curr_link
                        break

                if corresponding_link is None:
                    new_graph.add_link(link)

        return new_graph

class OperationNode(Node):
    """
    This class contains attributes of nodes used for storing operations.
    """

    def __init__(self, value: str):
        super().__init__()
        assert value in POSSIBLE_OPERATIONS, "Invalid argument 'value'!"
        self.value: str or None = value

class Operation:
    """
    This class contains attributes of graph operations which the user can use.
    """

    def __init__(self, name):
        # type: (str) -> None
        self.name: str or None = name if name in POSSIBLE_OPERATIONS else None

    def clone(self):
        # type: () -> Operation
        return copy.deepcopy(self)

class Graph:
    """
    This class contains attributes of a graph.
    """

    def __init__(self):
        # type: () -> None
        self.name: str = ""  # initial value
        self.vertices: list = []  # initial value
        self.links: list = []  # initial value

    def set_name(self, name: str):
        self.name = name

    def to_string(self):
        # type: () -> str
        res: str = ""  # initial value
        res += "Graph " + str(self.name) + "\n"
        res += "List of vertices: \n"
        for i in range(len(self.vertices)):
            res += str(i + 1) + ". " + str(self.vertices[i].to_string()) + "\n"

        res += "List of links: \n"
        for link in self.links:
            res += str(link.to_string()) + "\n"

        return res

    def add_vertex(self, vertex):
        # type: (Vertex) -> bool
        if vertex not in self.vertices:
            self.vertices.append(vertex)
            return True
        return False

    def remove_vertex(self, vertex):
        # type:(Vertex) -> bool
        if vertex in self.vertices:
            self.vertices.remove(vertex)
            for link in self.links:
                if link.from_vertex == vertex or link.to_vertex == vertex:
                    self.remove_link(link)

            return True
        return False

    def add_link(self, link):
        # type: (Link) -> bool
        link_exists: bool = False  # initial value
        for curr_link in self.links:
            if (curr_link.from_vertex == link.from_vertex and curr_link.to_vertex == link.to_vertex) or \
                    (curr_link.from_vertex == link.to_vertex and curr_link.to_vertex == link.from_vertex):
                link_exists = True
                break

        if not link_exists:
            self.links.append(link)
            self.add_vertex(link.from_vertex)
            self.add_vertex(link.to_vertex)
            return True
        return False

    def remove_link(self, link):
        # type: (Link) -> bool
        corresponding_link: Link or None = None  # initial value
        link_exists: bool = False  # initial value
        for curr_link in self.links:
            if (curr_link.from_vertex == link.from_vertex and curr_link.to_vertex == link.to_vertex) or \
                    (curr_link.from_vertex == link.to_vertex and curr_link.to_vertex == link.from_vertex):
                link_exists = True
                corresponding_link = curr_link
                break

        if not link_exists:
            return False
        else:
            start_vertex: Vertex = corresponding_link.from_vertex
            end_vertex: Vertex = corresponding_link.to_vertex
            self.links.remove(corresponding_link)
            start_vertex_linked: bool = False  # initial value
            end_vertex_linked: bool = False  # initial value
            for curr_link in self.links:
                if curr_link.from_vertex == start_vertex or curr_link.to_vertex == start_vertex:
                    start_vertex_linked = True
                    break

            for curr_link in self.links:
                if curr_link.from_vertex == end_vertex or curr_link.to_vertex == end_vertex:
                    end_vertex_linked = True
                    break

            if not start_vertex_linked:
                self.remove_vertex(start_vertex)

            if not end_vertex_linked:
                self.remove_vertex(end_vertex)

            return True

    def clone(self):
        # type: () -> Graph
        return copy.deepcopy(self)

class Vertex:
    """
    This class contains attributes of vertices in a graph.
    """

    def __init__(self, name):
        # type: (str) -> None
        self.name: str = name

    def to_string(self):
        # type: () -> str
        return str(self.name)

    def clone(self):
        # type: () -> Vertex
        return copy.deepcopy(self)

class Link:
    """
    This class contains attributes of links between two nodes in a graph.
    """

    def __init__(self, from_vertex, to_vertex, weight):
        # type: (Vertex, Vertex, Decimal or int or float) -> None
        self.from_vertex: Vertex = from_vertex
        self.to_vertex: Vertex = to_vertex
        self.weight: Decimal or int or float = weight

    def to_string(self):
        # type: () -> str
        return str(self.from_vertex.to_string()) + " - " + str(self.to_vertex.to_string()) + ", weight = " + \
               str(self.weight) + "\n"

    def clone(self):
        # type: () -> Link
        return copy.deepcopy(self)

def main():
    """
    This function is used to run the program.
    :return:
    """
    print("Enter 1 to type an expression.")
    print("Enter 2 to add a new graph.")
    print("Enter 3 to edit an existing graph.")
    print("Enter 4 to remove an existing graph.")
    print("Enter 5 to quit.")
    existing_graphs: list = []  # initial value
    option: int = int(input("Please enter a number: "))
    while option < 1 or option > 5:
        option: int = int(input("Sorry, invalid input! Please enter a number: "))

    while option != 5:
        if option == 1:
            alphabets: str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
            allowed_chars: list = [" "]  # initial value
            for char in alphabets:
                allowed_chars.append(char)

            for char in POSSIBLE_OPERATIONS:
                allowed_chars.append(char)

            if len(existing_graphs) > 1:
                expression: str = input("Please enter an expression: ")
                can_proceed: bool = True  # initial value
                for char in expression:
                    if char not in allowed_chars:
                        can_proceed = False

                while not can_proceed:
                    expression: str = input("Sorry, invalid expression! Please enter another expression: ")
                    can_proceed = True  # initial value
                    for char in expression:
                        if char not in allowed_chars:
                            can_proceed = False

                result: Graph = evaluate_expression(expression, existing_graphs)
                print(str(expression) + " = " + str(result.to_string()))

        elif option == 2:
            print("Please enter information regarding the new graph you want to add.")
            new_graph: Graph = Graph()
            name: str = input("Please enter name of the graph: ")
            new_graph.set_name(name)
            num_vertices: int = int(input("How many vertices do you want? "))
            for i in range(num_vertices):
                name: str = input("Please enter name of vertex: ")
                new_vertex: Vertex = Vertex(name)
                new_graph.add_vertex(new_vertex)

            print("Enter Y for yes.")
            print("Enter anything else for no.")
            add_link_ask: str = input("Do you want to add a link? ")
            while add_link_ask == "Y":
                start_vertex_name: str = input("Please enter the vertex where the link starts: ")
                end_vertex_name: str = input("Please enter the vertex where the link ends: ")
                matching_start_vertex: Vertex or None = None  # initial value
                matching_end_vertex: Vertex or None = None  # initial value
                for vertex in new_graph.vertices:
                    if vertex.name == start_vertex_name:
                        matching_start_vertex = vertex

                    if vertex.name == end_vertex_name:
                        matching_end_vertex = vertex

                while matching_start_vertex is None or matching_end_vertex is None or \
                        matching_start_vertex == matching_end_vertex:
                    start_vertex_name: str = input("Invalid input! Please enter the vertex where the link starts: ")
                    end_vertex_name: str = input("Invalid input! Please enter the vertex where the link ends: ")
                    matching_start_vertex: Vertex or None = None  # initial value
                    matching_end_vertex: Vertex or None = None  # initial value
                    for vertex in new_graph.vertices:
                        if vertex.name == start_vertex_name:
                            matching_start_vertex = vertex

                        if vertex.name == end_vertex_name:
                            matching_end_vertex = vertex

                weight: Decimal or int or float = Decimal(input("Please enter weight of the link: "))
                new_graph.add_link(Link(matching_start_vertex, matching_end_vertex, weight))
                add_link_ask: str = input("Do you want to add a link? ")

            existing_graphs.append(new_graph)

        elif option == 3:
            print("Below is a list of graphs that you have: \n")
            for graph in existing_graphs:
                print(graph.to_string())

            graph_index: int = int(input("Please enter the index of the graph that you want to edit: "))
            while graph_index < 0 or graph_index >= len(existing_graphs):
                graph_index: int = int(input("Invalid input! "
                                             "Please enter the index of the graph that you want to edit: "))

            graph_to_edit: Graph = existing_graphs[graph_index]
            print("Enter 1 to add a new vertex.")
            print("Enter 2 to remove an existing vertex.")
            print("Enter 3 to add a new link.")
            print("Enter 4 to remove an existing link.")
            print("Enter 5 to return to main menu.")
            decision: int = int(input("Please enter your decision code: "))
            while decision < 1 or decision > 5:
                decision: int = int(input("Sorry, invalid input! Please enter your decision code: "))

            while decision != 5:
                if decision == 1:
                    vertex_name: str = input("Please enter name of vertex: ")
                    to_add: Vertex = Vertex(vertex_name)
                    graph_to_edit.add_vertex(to_add)
                elif decision == 2:
                    print("Below is a list of vertices you already have.\n")
                    for vertex in graph_to_edit.vertices:
                        print(vertex.to_string())

                    vertex_index: int = int(input("Please enter index of vertex you want to delete: "))
                    while vertex_index < 0 or vertex_index >= len(graph_to_edit.vertices):
                        vertex_index: int = int(input("Invalid input! "
                                                      "Please enter index of vertex you want to delete: "))

                    to_remove: Vertex = graph_to_edit.vertices[vertex_index]
                    graph_to_edit.remove_vertex(to_remove)
                elif decision == 3:
                    start_vertex_name: str = input("Please enter the vertex where the link starts: ")
                    end_vertex_name: str = input("Please enter the vertex where the link ends: ")
                    matching_start_vertex: Vertex or None = None  # initial value
                    matching_end_vertex: Vertex or None = None  # initial value
                    for vertex in graph_to_edit.vertices:
                        if vertex.name == start_vertex_name:
                            matching_start_vertex = vertex

                        if vertex.name == end_vertex_name:
                            matching_end_vertex = vertex

                    while matching_start_vertex is None or matching_end_vertex is None or \
                            matching_start_vertex == matching_end_vertex:
                        start_vertex_name: str = input("Invalid input! Please enter the vertex where the link starts: ")
                        end_vertex_name: str = input("Invalid input! Please enter the vertex where the link ends: ")
                        matching_start_vertex: Vertex or None = None  # initial value
                        matching_end_vertex: Vertex or None = None  # initial value
                        for vertex in graph_to_edit.vertices:
                            if vertex.name == start_vertex_name:
                                matching_start_vertex = vertex

                            if vertex.name == end_vertex_name:
                                matching_end_vertex = vertex

                    weight: Decimal or int or float = Decimal(input("Please enter weight of the link: "))
                    graph_to_edit.add_link(Link(matching_start_vertex, matching_end_vertex, weight))

                elif decision == 4:
                    print("Below is a list of existing links in the graph.\n")
                    for link in graph_to_edit.links:
                        print(link.to_string())

                    link_index: int = int(input("Please enter index of link you want to remove: "))
                    to_remove: Link = graph_to_edit.links[link_index]
                    graph_to_edit.remove_link(to_remove)

                decision: int = int(input("Please enter your decision code: "))
                while decision < 1 or decision > 5:
                    decision: int = int(input("Sorry, invalid input! Please enter your decision code: "))

        elif option == 4:
            print("Below is a list of graphs that you have: \n")
            for graph in existing_graphs:
                print(graph.to_string())

            graph_index: int = int(input("Please enter the index of the graph that you want to remove: "))
            while graph_index < 0 or graph_index >= len(existing_graphs):
                graph_index: int = int(input("Invalid input! "
                                             "Please enter the index of the graph that you want to remove: "))

            graph_to_remove: Graph = existing_graphs[graph_index]
            existing_graphs.remove(graph_to_remove)

        option: int = int(input("Please enter a number: "))
        while option < 1 or option > 5:
            option: int = int(input("Sorry, invalid input! Please enter a number: "))

    sys.exit()

main()


# -*- coding: UTF-8 -*-
import json
from xf import text_tovoice
from xf import voice_totext
from xf import text_tovoice_totext
import time

def test1():
    print("---start---")
    start = time.time()
    voiceResultStr = text_tovoice.init('百度传来了喜讯',
                                      "E:/jianguocloud/learn/Python/pythonTest/pythonUtils/datas/chat/output.mp3")
    print(voiceResultStr)
    voiceResultJson = json.loads(voiceResultStr)
    code = voiceResultJson['code']
    if code == "0":
        print("文字转音频成功")
    else:
        print("文字转音频失败：" + voiceResultStr)
    textResultStr = voice_totext.init("E:/jianguocloud/learn/Python/pythonTest/pythonUtils/datas/chat/output.mp3")
    textResultJson = json.loads(textResultStr)
    code = textResultJson['code']
    if code == "0":
        print("音频转文字成功" + textResultStr)
    else:
        print("音频转文字失败：" + textResultStr)
    end = time.time()
    print(end - start)
    print("---end---")

def test2():
    start = time.time()
    text_tovoice_totext.change("摆渡船来")
    end = time.time()
    print(end - start)

if __name__ == '__main__':
    test2()


def part1():
    L1 = [1,2,3,4,5] ; L2 = [2,3,4,5,1,0]
    print(L1<L2)
    print(L1 != L2)
    L3 = ['1','2','3','4','5']
    #print(  L1>L3) results in error. Cant compare string and int
    print(L1 and L2)
    print(not L3)
    print(not[])
    L1 = [1,2];L2 = [1,2]; L3 = L1
    print(L1 is L2)
    print(L1 is L3)
    sentence = "Hello, Welcome to Python"
    print("Python" in sentence)
    print(min("Python"))
    seasons = ['Summer','Spring','Fall','Winter']
    print(list(enumerate(seasons,start = 1)))
def makeDict(names,scores):
    return dict(zip(names,scores))
def part3():
    names = ['joe','tom','barb','sue','sally']
    scores = [10,17,20,18,15]
    ages = [20,17,19,18,22]
    setTuple = tuple(zip(names,scores))
    fset = frozenset(zip(names,ages))
    print(fset.intersection(setTuple))
def scoreDict(names,scores):
    temp = makeDict(names,scores)
    temp['john'] = 19
    temp['sue'] = 20
    temp['sally'] = 19
    del temp['tom']
    for k,v in temp.items():
        print(k,v)
    return temp
def getMedianScore(temp):
    t = []
    for k,v in temp.items():
        t.append(v)
    print(t[int(len(t)/2)])
class Error(Exception):
    pass
def getScore(name, d):
    returnV = -1
    if name in d:
        returnV = int(d[name])
    if name not in d:
        print(name,' not found')
        raise Error
    return returnV


"""
Makes it possible to run a game through terminal.

"""
import sys
import threading

from bot.step_score_bot import StepScoreBot
from game_client.game_loop import game_loop
from game_client.server_interaction import GameSession, WrongPayloadFormatError

HELP_TEXT = (
    "Usage:\n"
    "python terminal_interface.py {username}\n"
    "python terminal_interface.py {username} {game}\n"
    "python terminal_interface.py "
    "{username} {game} {num_turns} {num_players}\n"
    "--gui - launch the game with gui"
)

CMD_FLAGS = ["--gui"]

def game_init(**login_info) -> GameSession:
    """
    Returns GameSession instance if acceptable login_info was provided.

    """
    try:
        return GameSession(**login_info)
    except WrongPayloadFormatError:
        print(HELP_TEXT)
        sys.exit(1)

def game_launch(bot, game, gui) -> None:
    """
    Launches the game.

    :param bot: bot that will play the game
    :param game: game to be played
    :param gui: to use gui or not
    """
    if gui:
        game_loop_thread = threading.Thread(target=game_loop, args=(bot, game))
        game_loop_thread.start()
        # pylint: disable=import-outside-toplevel
        # Written here as it opens empty window if --gui was not provided
        # if imported at the top of the file
        from gui.game_state_property import game_state_property
        from gui.gui import WoTStrategyApp

        WoTStrategyApp(game.map, game_state_property).run()

        game_loop_thread.join()
    else:
        game_loop(bot, game)

def main() -> None:
    """
    Parses terminal args and initiates game with given params.

    """
    args = sys.argv.copy()
    flags_dict = {}
    for flag in CMD_FLAGS:
        flags_dict[flag] = flag in args
        if flags_dict[flag]:
            args.remove(flag)

    if len(args) == 2:
        game = game_init(name=args[1])

    elif len(args) == 3:
        game = game_init(name=args[1], game=args[2])

    elif len(args) == 5:
        game = game_init(
            name=args[1],
            game=args[2],
            num_turns=args[3],
            num_players=args[4],
        )

    else:
        print(HELP_TEXT)
        sys.exit(1)

    bot = StepScoreBot(game.map)
    game_launch(bot, game, flags_dict["--gui"])

if __name__ == "__main__":
    main()