from __future__ import absolute_import

from builtins import str
from builtins import object
import itertools
import logging
import os
import posixpath
import re
import sys
import time

from boto.exception import BotoClientError, S3ResponseError
from boto.s3.connection import Location
from boto.s3.key import Key
from boto.s3.prefix import Prefix

from aws import s3
from aws.conf import get_default_region, get_locations, PERMISSION_ACTION_S3, is_raz_s3
from aws.s3 import normpath, s3file, translate_s3_error, S3A_ROOT
from aws.s3.s3stat import S3Stat

from filebrowser.conf import REMOTE_STORAGE_HOME

if sys.version_info[0] > 2:
  import urllib.request, urllib.error
  from urllib.parse import quote as urllib_quote, urlparse as lib_urlparse
  from django.utils.translation import gettext as _
else:
  from urllib import quote as urllib_quote
  from urlparse import urlparse as lib_urlparse
  from django.utils.translation import ugettext as _

DEFAULT_READ_SIZE = 1024 * 1024  # 1MB
BUCKET_NAME_PATTERN = re.compile(
  "^((?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9_\-]*[a-zA-Z0-9])\.)*(?:[A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9_\-]*[A-Za-z0-9]))$")

LOG = logging.getLogger()

class S3FileSystemException(IOError):
  def __init__(self, *args, **kwargs):
    super(S3FileSystemException, self).__init__(*args, **kwargs)

class S3ListAllBucketsException(S3FileSystemException):
  def __init__(self, *args, **kwargs):
    super(S3FileSystemException, self).__init__(*args, **kwargs)

def auth_error_handler(view_fn):
  def decorator(*args, **kwargs):
    try:
      return view_fn(*args, **kwargs)
    except (S3ResponseError, IOError) as e:
      LOG.exception('S3 error: ' + str(e))
      if 'Forbidden' in str(e) or (hasattr(e, 'status') and e.status == 403):
        path = kwargs.get('path')
        if not path and len(args) > 1:
          path = args[1]  # We assume that the path is the first argument
        msg = _('User is not authorized to perform the attempted operation. Check that the user has appropriate permissions.')
        if path:
          msg = _('User is not authorized to write or modify path: %s. Check that the user has write permissions.') % path
        raise S3FileSystemException(msg)
      else:
        msg = str(e)
        if isinstance(e, S3ResponseError):
          msg = e.message or e.reason
        raise S3FileSystemException(msg)
    except Exception as e:
      raise e
  return decorator

def get_s3_home_directory(user=None):
  from desktop.models import _handle_user_dir_raz

  remote_home_s3 = 's3a://'
  if hasattr(REMOTE_STORAGE_HOME, 'get') and REMOTE_STORAGE_HOME.get() and REMOTE_STORAGE_HOME.get().startswith('s3a://'):
    remote_home_s3 = REMOTE_STORAGE_HOME.get()

  remote_home_s3 = _handle_user_dir_raz(user, remote_home_s3)

  return remote_home_s3

class S3FileSystem(object):
  def __init__(self, s3_connection, expiration=None, fs='s3a', headers=None, filebrowser_action=PERMISSION_ACTION_S3):
    self._s3_connection = s3_connection
    self._filebrowser_action = filebrowser_action
    self.user = None
    self.is_sentry_managed = lambda path: False
    self.superuser = None
    self.supergroup = None
    self.expiration = expiration
    self.fs = fs
    self.header_values = headers

  def _get_bucket(self, name):
    try:
      return self._s3_connection.get_bucket(name, headers=self.header_values)
    except S3ResponseError as e:
      if e.status == 301 or e.status == 400:
        raise S3FileSystemException(
          _('Failed to retrieve bucket "%s" in region "%s" with "%s". Your bucket is in region "%s"') %
          (name, self._get_location(), e.message or e.reason, self.get_bucket_location(name)))
      else:
        raise e

  def get_bucket_location(self, name):
    try:
      # We use make_request, because self._s3_connection.get_bucket does not returns headers which contains the bucket location
      resp = self._s3_connection.make_request('HEAD', name)
      return resp.getheader('x-amz-bucket-region')
    except Exception as e:
      LOG.warning('Failed to fetch bucket "%s" location with "%s"' % (name, e.message or e.reason))
      return None

  def _get_or_create_bucket(self, name):
    try:
      bucket = self._get_bucket(name)
    except BotoClientError as e:
      raise S3FileSystemException(_('Failed to create bucket "%s" with "%s"') % (name, e.message or e.reason))
    except S3ResponseError as e:
      if e.status == 403:
        raise S3FileSystemException(_('User is not authorized to access bucket named "%s". '
          'If you are attempting to create a bucket, this bucket name is already reserved.') % name)
      elif e.status == 404:
        kwargs = {}
        if self._get_location():
          kwargs['location'] = self._get_location()
        bucket = self._create_bucket(name, **kwargs)
      else:
        raise S3FileSystemException(e.message or e.reason)
    return bucket

  def _create_bucket(self, name, **kwargs):
    # S3 API throws an exception when using us-east-1 and specifying CreateBucketConfiguration
    # Boto specifies CreateBucketConfiguration whenever the location is not default
    # We change location to default to fix issue
    # More information: https://github.com/boto/boto3/issues/125

    if kwargs.get('location') == 'us-east-1':
      kwargs['location'] = ''

    return self._s3_connection.create_bucket(name, **kwargs)

  def _delete_bucket(self, name):
    try:
      # Verify that bucket exists and user has permissions to access it
      bucket = self._get_bucket(name)
      # delete keys from bucket first
      for key in bucket.list():
        key.delete()
      self._s3_connection.delete_bucket(name)
      LOG.info('Successfully deleted bucket name "%s" and all its contents.' % name)
    except S3ResponseError as e:
      if e.status == 403:
        raise S3FileSystemException(_('User is not authorized to access bucket named "%s". '
          'If you are attempting to create a bucket, this bucket name is already reserved.') % name)
      else:
        raise S3FileSystemException(e.message or e.reason)

  def _get_key(self, path, validate=True):
    bucket_name, key_name = s3.parse_uri(path)[:2]
    bucket = self._get_bucket(bucket_name)

    try:
      return bucket.get_key(key_name, validate=validate)
    except BotoClientError as e:
      raise S3FileSystemException(_('Failed to access path at "%s": %s') % (path, e.reason))
    except S3ResponseError as e:
      if e.status in (301, 400):
        raise S3FileSystemException(_('Failed to access path: "%s" '
          'Check that you have access to read this bucket and that the region is correct: %s') % (path, e.message or e.reason))
      elif e.status == 403:
        raise S3FileSystemException(_('User is not authorized to access path at "%s".' % path))
      else:
        raise S3FileSystemException(e.message or e.reason)

  def _get_location(self):
    if get_default_region() in get_locations():
      return get_default_region()
    else:
      return Location.DEFAULT

  def _stats(self, path):
    if S3FileSystem.isroot(path):
      return S3Stat.for_s3_root()

    try:
      key = self._get_key(path, validate=True)
    except BotoClientError as e:
      raise S3FileSystemException(_('Failed to access path "%s": %s') % (path, e.reason))
    except S3ResponseError as e:
      if e.status == 404:
        return None
      elif e.status == 403:
        raise S3FileSystemException(_('User is not authorized to access path: "%s"') % path)
      else:
        raise S3FileSystemException(_('Failed to access path "%s": %s') % (path, e.reason))
    except Exception as e: # SSL errors show up here, because they've been remapped in boto
      raise S3FileSystemException(_('Failed to access path "%s": %s') % (path, str(e)))
    if key is None:
      key = self._get_key(path, validate=False)
    return self._stats_key(key, self.fs)

  @staticmethod
  def _stats_key(key, fs='s3a'):
    if key.size is not None:
      is_directory_name = not key.name or key.name[-1] == '/'
      return S3Stat.from_key(key, is_dir=is_directory_name, fs=fs)
    else:
      key.name = S3FileSystem._append_separator(key.name)
      ls = key.bucket.get_all_keys(prefix=key.name, max_keys=1)  # Not sure possible via signed request
      if len(ls) > 0:
        return S3Stat.from_key(key, is_dir=True, fs=fs)
    return None

  @staticmethod
  def _append_separator(path):
    if path and not path.endswith('/'):
      path += '/'
    return path

  @staticmethod
  def _cut_separator(path):
    return path.endswith('/') and path[:-1] or path

  @staticmethod
  def isroot(path):
    parsed = lib_urlparse(path)
    return (parsed.path == '/' or parsed.path == '') and parsed.netloc == ''

  @staticmethod
  def join(*comp_list):
    return s3.join(*comp_list)

  @staticmethod
  def normpath(path):
    return normpath(path)

  def netnormpath(self, path):
    return normpath(path)

  @staticmethod
  def parent_path(path):
    parent_dir = S3FileSystem._append_separator(path)
    if not S3FileSystem.isroot(parent_dir):
      bucket_name, key_name, basename = s3.parse_uri(path)
      if not basename:  # bucket is top-level so return root
        parent_dir = S3A_ROOT
      else:
        bucket_path = '%s%s' % (S3A_ROOT, bucket_name)
        key_path = '/'.join(key_name.split('/')[:-1])
        parent_dir = s3.abspath(bucket_path, key_path)
    return parent_dir

  @translate_s3_error
  def open(self, path, mode='r'):
    key = self._get_key(path, validate=True)
    if key is None:
      raise S3FileSystemException("No such file or directory: '%s'" % path)
    return s3file.open(key, mode=mode)

  @translate_s3_error
  def read(self, path, offset, length):
    fh = self.open(path, 'r')
    fh.seek(offset, os.SEEK_SET)
    return fh.read(length)

  @translate_s3_error
  def isfile(self, path):
    stat = self._stats(path)
    if stat is None:
      return False
    return not stat.isDir

  @translate_s3_error
  def isdir(self, path):
    stat = self._stats(path)
    if stat is None:
      return False
    return stat.isDir

  @translate_s3_error
  def exists(self, path):
    return self._stats(path) is not None

  @translate_s3_error
  def stats(self, path):
    path = normpath(path)
    stats = self._stats(path)
    if stats:
      return stats
    raise S3FileSystemException("No such file or directory: '%s'" % path)

  @translate_s3_error
  def listdir_stats(self, path, glob=None):
    if glob is not None:
      raise NotImplementedError(_("Option `glob` is not implemented"))

    if S3FileSystem.isroot(path):
      try:
        return sorted(
          [S3Stat.from_bucket(b, self.fs) for b in self._s3_connection.get_all_buckets(headers=self.header_values)], key=lambda x: x.name)
      except S3FileSystemException as e:
        raise e
      except S3ResponseError as e:
        if 'Forbidden' in str(e) or (hasattr(e, 'status') and e.status == 403):
          raise S3ListAllBucketsException(
            _('You do not have permissions to list all buckets. Please specify a bucket name you have access to.'))
        else:
          raise S3FileSystemException(_('Failed to retrieve buckets: %s') % e.reason)
      except Exception as e:
        raise S3FileSystemException(_('Failed to retrieve buckets: %s') % e)

    bucket_name, prefix = s3.parse_uri(path)[:2]
    bucket = self._get_bucket(bucket_name)
    prefix = self._append_separator(prefix)
    res = []
    for item in bucket.list(prefix=prefix, delimiter='/', headers=self.header_values):
      if isinstance(item, Prefix):
        res.append(S3Stat.from_key(Key(item.bucket, item.name), is_dir=True, fs=self.fs))
      else:
        if item.name == prefix:
          continue
        res.append(self._stats_key(item, self.fs))
    return res

  @translate_s3_error
  def listdir(self, path, glob=None):
    return [s3.parse_uri(x.path)[2] for x in self.listdir_stats(path, glob)]

  @translate_s3_error
  @auth_error_handler
  def rmtree(self, path, skipTrash=True):
    if not skipTrash:
      raise NotImplementedError(_('Moving to trash is not implemented for S3'))

    bucket_name, key_name = s3.parse_uri(path)[:2]
    if bucket_name and not key_name:
      self._delete_bucket(bucket_name)
    else:
      if self.isdir(path):
        path = self._append_separator(path)  # Really need to make sure we end with a '/'

      key = self._get_key(path, validate=False)

      if key.exists():
        to_delete = [key]
        dir_keys = []

        if self.isdir(path):
          dir_keys = key.bucket.list(prefix=path)
          to_delete = itertools.chain(dir_keys, to_delete)

        if not dir_keys:
          # Avoid Raz bulk delete issue
          deleted_key = key.delete()
          if deleted_key.exists():
            raise S3FileSystemException('Could not delete key %s' % deleted_key)
        else:
          result = key.bucket.delete_keys(to_delete)
          if result.errors:
            msg = "%d errors occurred while attempting to delete the following S3 paths:\n%s" % (
              len(result.errors), '\n'.join(['%s: %s' % (error.key, error.message) for error in result.errors])
            )
            LOG.error(msg)
            raise S3FileSystemException(msg)

  @translate_s3_error
  @auth_error_handler
  def remove(self, path, skip_trash=True):
    self.rmtree(path, skipTrash=skip_trash)

  def restore(self, *args, **kwargs):
    raise NotImplementedError(_('Moving to trash is not implemented for S3'))

  def filebrowser_action(self):
    return self._filebrowser_action

  def create_home_dir(self, home_path):
    # When S3 raz is enabled, try to create user home dir for REMOTE_STORAGE_HOME path
    if is_raz_s3():
      LOG.debug('Attempting to create user directory for path: %s' % home_path)
      try:
        self.mkdir(home_path)
      except Exception as e:
        LOG.exception('Failed to create user home directory for path %s with error: %s' % (home_path, str(e)))
    else:
      LOG.info('Create home directory is not available for S3 filesystem')

  @translate_s3_error
  @auth_error_handler
  def mkdir(self, path, *args, **kwargs):
    """
    Creates a directory and any parent directory if necessary.

    Actually it creates an empty object: s3://[bucket]/[path]/
    """
    bucket_name, key_name = s3.parse_uri(path)[:2]
    if not BUCKET_NAME_PATTERN.match(bucket_name):
      raise S3FileSystemException(_('Invalid bucket name: %s') % bucket_name)

    try:
      self._get_or_create_bucket(bucket_name)
    except S3FileSystemException as e:
      raise e
    except S3ResponseError as e:
      raise S3FileSystemException(_('Failed to create S3 bucket "%s": %s: %s') % (bucket_name, e.reason, e.body))
    except Exception as e:
      raise S3FileSystemException(_('Failed to create S3 bucket "%s": %s') % (bucket_name, e))

    stats = self._stats(path)
    if stats:
      if stats.isDir:
        return None
      else:
        raise S3FileSystemException("'%s' already exists and is not a directory" % path)
    path = self._append_separator(path)  # folder-key should ends by /
    self.create(path)  # create empty object

  @translate_s3_error
  @auth_error_handler
  def copy(self, src, dst, recursive=False, *args, **kwargs):
    self._copy(src, dst, recursive=recursive, use_src_basename=True)

  @translate_s3_error
  @auth_error_handler
  def copyfile(self, src, dst, *args, **kwargs):
    if self.isdir(dst):
      raise S3FileSystemException("Copy dst '%s' is a directory" % dst)
    self._copy(src, dst, recursive=False, use_src_basename=False)

  @translate_s3_error
  @auth_error_handler
  def copy_remote_dir(self, src, dst, *args, **kwargs):
    self._copy(src, dst, recursive=True, use_src_basename=False)

  def _copy(self, src, dst, recursive, use_src_basename):
    src_st = self.stats(src)
    if src_st.isDir and not recursive:
      return # omitting directory

    dst = s3.abspath(src, dst)
    dst_st = self._stats(dst)
    if src_st.isDir and dst_st and not dst_st.isDir:
      raise S3FileSystemException("Cannot overwrite non-directory '%s' with directory '%s'" % (dst, src))

    # Skip operation if destination path is same as source path
    if self._check_key_parent_path(src, dst):
      raise S3FileSystemException('Destination path is same as the source path, skipping the operation.')

    src_bucket, src_key = s3.parse_uri(src)[:2]
    dst_bucket, dst_key = s3.parse_uri(dst)[:2]

    keep_src_basename = use_src_basename and dst_st and dst_st.isDir
    src_bucket = self._get_bucket(src_bucket)
    dst_bucket = self._get_bucket(dst_bucket)

    if keep_src_basename:
      cut = len(posixpath.dirname(src_key))  # cut of an parent directory name
      if cut:
        cut += 1
    else:
      cut = len(src_key)
      if not src_key.endswith('/'):
        cut += 1

    for key in src_bucket.list(prefix=src_key):
      if not key.name.startswith(src_key):
        raise S3FileSystemException(_("Invalid key to transform: %s") % key.name)
      dst_name = posixpath.normpath(s3.join(dst_key, key.name[cut:]))

      if self.isdir(normpath(self.join(S3A_ROOT, key.bucket.name, key.name))):
        dst_name = self._append_separator(dst_name)

      key.copy(dst_bucket, dst_name)

  @translate_s3_error
  @auth_error_handler
  def rename(self, old, new):
    new = s3.abspath(old, new)

    # Skip operation if destination path is same as source path
    if not self._check_key_parent_path(old, new):
      self.copy(old, new, recursive=True)
      self.rmtree(old, skipTrash=True)
    else:
      raise S3FileSystemException('Destination path is same as source path, skipping the operation.')

  @translate_s3_error
  @auth_error_handler
  def _check_key_parent_path(self, src, dst):
    # Return True if parent path of source is same as destination path.
    if S3FileSystem.parent_path(src) == dst:
      return True
    else:
      return False

  @translate_s3_error
  @auth_error_handler
  def rename_star(self, old_dir, new_dir):
    if not self.isdir(old_dir):
      raise S3FileSystemException("'%s' is not a directory" % old_dir)
    if self.isfile(new_dir):
      raise S3FileSystemException("'%s' is not a directory" % new_dir)
    ls = self.listdir(old_dir)
    for entry in ls:
      self.rename(s3.join(old_dir, entry), s3.join(new_dir, entry))

  @translate_s3_error
  @auth_error_handler
  def create(self, path, overwrite=False, data=None):
    key = self._get_key(path, validate=False)
    key.set_contents_from_string(data or '', replace=overwrite)

  @translate_s3_error
  @auth_error_handler
  def copyFromLocal(self, local_src, remote_dst, *args, **kwargs):
    local_src = self._cut_separator(local_src)
    remote_dst = self._cut_separator(remote_dst)

    def _copy_file(src, dst):
      key = self._get_key(dst, validate=False)
      fp = open(src, 'r')
      key.set_contents_from_file(fp)

    if os.path.isdir(local_src):
      for (local_dir, sub_dirs, files) in os.walk(local_src, followlinks=False):
        remote_dir = local_dir.replace(local_src, remote_dst)

        if not sub_dirs and not files:
          self.mkdir(remote_dir)
        else:
          for file_name in files:
            _copy_file(os.path.join(local_dir, file_name), os.path.join(remote_dir, file_name))
    else:
      file_name = os.path.split(local_src)[1]
      if self.isdir(remote_dst):
        remote_file = os.path.join(remote_dst, file_name)
      else:
        remote_file = remote_dst
      _copy_file(local_src, remote_file)

  @translate_s3_error
  def upload(self, file, path, *args, **kwargs):
    pass  # upload is handled by S3FileUploadHandler

  @translate_s3_error
  @auth_error_handler
  def append(self, path, data):
    key = self._get_key(path, validate=False)
    current_data = key.get_contents_as_string() or ''
    new_data = data or ''
    key.set_contents_from_string(current_data + new_data, replace=True)

  @translate_s3_error
  def check_access(self, path, permission='READ'):
    permission = permission.upper()
    try:
      if permission == 'WRITE':
        tmp_file = 'temp_%s' % str(int(time.time() * 1000))
        tmp_path = '%s/%s' % (path, tmp_file)
        self.create(path=tmp_path, overwrite=True)
        self.remove(path=tmp_path)
      else:
        self.open(path)
    except Exception as e:
      LOG.warning('S3 check_access encountered error verifying %s permission at path "%s": %s' % (permission, path, str(e)))
      return False
    return True

  def setuser(self, user):
    self.user = user  # Only used in Cluster middleware request.fs

  def get_upload_chuck_size(self):
    from hadoop.conf import UPLOAD_CHUNK_SIZE # circular dependency
    return UPLOAD_CHUNK_SIZE.get()


#!/usr/bin/env python3
import sys, pandas, numpy, itertools, logging, argparse

parser = argparse.ArgumentParser()
parser.add_argument('open')
parser.add_argument('turnout')
parser.add_argument('incD')
parser.add_argument('incR')
parser.add_argument('votes')
args = parser.parse_args()

logging.basicConfig(format='%(asctime)s - %(filename)s - %(message)s',
    stream=sys.stderr, level=logging.INFO)

logging.info('Reading input files...')

# Democratic vote share in file 1,
# absolute turnout in file 2 scaled by .01 in upstream R code
dem_share = pandas.read_csv(args.open)
input_sims = len([c for c in dem_share.columns if c.startswith('v.')])
output_sims, rows = 350, dem_share.shape[0]

turnout = pandas.read_csv(args.turnout)
turnout.iloc[:, -input_sims:] *= 100

incd_share = pandas.read_csv(args.incD)
incr_share = pandas.read_csv(args.incR)

logging.info('Creating output frame...')

# Ignore the blank first column of input to prepare votes output,
# build an empty frame with 6x output_sims columns for DEM and REP votes
# in three candidate scenarios, concatenate both into a complete votes frame.
votes1 = dem_share.iloc[:, 1:-input_sims]
votes2 = pandas.DataFrame(data=numpy.empty((rows, output_sims*6)), dtype=float,
    columns=[f'{inc}:{party}{sim:03d}' for (inc, sim, party)
        in itertools.product(('O', 'D', 'R'), range(output_sims), ('DEM', 'REP'))])

votes = pandas.concat((votes1, votes2), axis=1)

# Iterate over simulations populating Democratic and Republican vote shares
s_cols, t_cols = dem_share.columns[-input_sims:], turnout.columns[-input_sims:]
d_cols, r_cols = incd_share.columns[-input_sims:], incr_share.columns[-input_sims:]

for (sim, s_col, t_col, d_col, r_col) in zip(range(output_sims), s_cols, t_cols, d_cols, r_cols):
    turnout_val, share_val = turnout[t_col], dem_share[s_col]
    incd_val, incr_val = incd_share[d_col], incr_share[r_col]

    # Calculate shares for open seat and incumbent scenarios
    open_dem_share = share_val
    open_rep_share = (1 - share_val)
    incd_dem_share = (share_val + incd_val)
    incd_rep_share = (1 - (share_val + incd_val))
    incr_dem_share = (share_val + incr_val)
    incr_rep_share = (1 - (share_val + incr_val))

    # Assign raw votes counts rounded to one decimal place
    votes[f'O:DEM{sim:03d}'] = round(turnout_val * open_dem_share, 1)
    votes[f'O:REP{sim:03d}'] = round(turnout_val * open_rep_share, 1)
    votes[f'D:DEM{sim:03d}'] = round(turnout_val * incd_dem_share, 1)
    votes[f'D:REP{sim:03d}'] = round(turnout_val * incd_rep_share, 1)
    votes[f'R:DEM{sim:03d}'] = round(turnout_val * incr_dem_share, 1)
    votes[f'R:REP{sim:03d}'] = round(turnout_val * incr_rep_share, 1)

logging.info('Writing output file...')
votes.to_csv(args.votes, index=False, compression='gzip')
logging.info('Done.')


class Solution:
    def subsets(self, nums: [int]) -> [[int]]:
        # def createSubsets(curList, remaining):
        #     for i in range(len(remaining)-1, -1, -1):
        #         num = remaining.pop(i)
        #         if curList and num < curList[-1]:
        #             return
        #         templ = curList + [num]
        #         retSet.add(tuple(templ))
        #         createSubsets(templ, remaining[:])
        #         remaining.insert(i, num)
        # retSet = {tuple()}
        # createSubsets([], sorted(nums))
        # return retSet
        retList = [[]]
        for num in nums:
            retList += [prevSubset + [num] for prevSubset in retList]
        return retList

Coding_Challenges/30 Day Coding Challenge July/Week 2/Day 11) Subsets.py


import os, pyautogui, time, datetime, json

# subprocess.Popen([r"C:\Program Files (x86)\AgencyAp\SIMMS v10.4.0\simms.exe"])

CurrentPath = os.getcwd()
#print(CurrentPath)

import webbrowser

url = 'https://i5.readyop.com/fs/4cim/9fb7'

try:
    chrome_path = 'open -a /Applications/Google\ Chrome.app %s'
    webbrowser.get(chrome_path).open(url)
    Mac = True
except:
    Mac = False
print(Mac)
try:
    chrome_path = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s'
    webbrowser.get(chrome_path).open(url)
    Windows = True
except:
    Windows = False
print(Windows)
try:
    chrome_path = '/usr/bin/google-chrome %s'
    webbrowser.get(chrome_path).open(url)
    Linux = True
except:
    Linux = FalseWRS
print(Linux)

os.chdir(CurrentPath)
WFile = 'PersonalInfomration.JSON'
W_File_Open = open(WFile)
WDict_ST = W_File_Open.read()
WDict = json.loads(WDict_ST)
print(WDict)

LName = WDict['LName']
FName = WDict['FName']
EmployeeID = WDict['EmployeeID']
OrgCode = WDict['OrgCode']

TMC = False
Remote = True
NWR = True
enter = [LName, FName, EmployeeID, OrgCode]
print(enter)
time.sleep(6)
k = 0
while k < len(enter):
        pyautogui.write('\t')
        time.sleep(.05)
        PN = enter[k]
        WAns = str(PN)
        WAns = WAns.capitalize()
        print(WAns)
        if k < 2:
            pyautogui.keyDown('shift')
            pyautogui.typewrite(WAns[0], interval=0.005)
            pyautogui.keyUp('shift')
            pyautogui.typewrite(WAns[1:], interval=0.005)
        else:
            pyautogui.typewrite(WAns, interval=0.005)
        time.sleep(.05)
        k = k + 1
print('Complete')


from PyQt5.QtWidgets import QApplication
from mainWindow import MainWindow
from inicial_window import InicialWindow
from final_window import FinalWindow
from entidad_dcc import DCC
from el_que_perdio_es_malo import TheLoserGuy
import sys

app = QApplication([])
lista_mapa = []
window = MainWindow()
inicial_window = InicialWindow()
final_window = FinalWindow()
dcc = DCC(window.display_x, window.display_y, lista_mapa)
loser = TheLoserGuy()
inicial_window.senal_nuevo_juego.connect(dcc.nuevo_juego)
inicial_window.senal_comenzar_ronda.connect(window.comienzo_ronda)
dcc.senal_nuevo_juego_armar.connect(window.iniciar_ventana_nueva)
window.senal_extender_lista_dcc.connect(dcc.actualizar_lista_extendida)
window.senal_nueva_reputacion.connect(dcc.mas_reputacion)

inicial_window.senal_continuar_juego.connect(dcc.cargar_mapa_seguir_juego) #se continua juego con datos anterioresa
dcc.senal_mandar_mapa.connect(window.cargar_mapa) #se envía mapa de datos anteriores. acá me falta actualizar el mapa y datos

dcc.senal_el_chef_cocina.connect(window.chef_trabajando)
dcc.senal_plato_recogido.connect(window.chef_trabajando)

window.senal_comenzar_ronda.connect(dcc.comienzo_ronda_dcc)
window.senal_traer_clientes.connect(dcc.arma_lista_clientes)
dcc.senal_nuevos_clientes.connect(window.llegada_clientes)
dcc.senal_aparece_bocadillo.connect(window.cliente_come)
dcc.senal_nuevo_estado_cliente.connect(window.metodo_cliente)
dcc.senal_termino.connect(window.cliente_termino)
window.senal_fin_ronda.connect(dcc.ronda_terminada)

window.senal_mover_jugador.connect(dcc.gamer.mover)
dcc.gamer.senal_nueva_posicion.connect(window.nueva_posicion)

window.senal_nuevo_drop.connect(dcc.revisar_cruce)
dcc.senal_comprobacion.connect(window.compra)
window.senal_acutalizar_lista.connect(dcc.actualizar_lista)
window.senal_eliminar_objeto.connect(dcc.eliminar_objeto)

dcc.senal_abrir_post_ronda.connect(final_window.armemos_y_abramos)
dcc.senal_perdiste.connect(loser.goodbye_my_friend)
dcc.senal_perdiste.connect(window.salir_perdedor)
final_window.senal_enviar_datos_guardar.connect(dcc.guardar_datos)

inicial_window.show()
sys.exit(app.exec_())


"""
@author: tamas
"""
import copy
import numpy as np
from Domain import Ant
class ACOController():

    def __init__(self,acoProblem):
        self.__problem = acoProblem
        self.__loadData()

    def __loadData(self):
        parameters = self.__problem.loadProblem()
        self.__matrixSize = parameters[0]
        self.__numberOfIterations = parameters[1]
        self.__numberOfAnts = parameters[2]
        self.__alpha = parameters[3]
        self.__beta = parameters[4]
        self.__rho = parameters[5]
        self.__q0 = parameters[6]
        self.__interupted = False
        self.__testing = False
        self.__trace = []

    def performTests(self):
        self.__testing = True
        resultACO = []
        AverageACO = None
        StandardDevACO = None
        print("ACO start")
        for i in range(30):
            resultACO.append(self.startACO(None)[2])
            print(i)
            if len(resultACO[-1]) != self.__numberOfIterations:
                resultACO[-1] = resultACO[-1] + (self.__numberOfIterations-len(resultACO[-1]))*[resultACO[-1][-1]]
            if self.__interupted:
                self.__testing = False
                return
        print("ACO done")
        averagesACO =  self.__averageForEachGeneration(resultACO)
        AverageACO = np.mean(resultACO)
        StandardDevACO = np.std(resultACO)
        return (averagesACO,AverageACO,StandardDevACO)

    def __averageForEachGeneration(self,resultACO):
        averages = []
        length = len(resultACO)
        for j in range(len(resultACO[0])):
            s = 0
            for i in range(len(resultACO)):
                s += resultACO[i][j]
            averages.append(s/length)
        return averages

    def setTesting(self,value):
        self.__testing = value

    def setProblem(self,newProblem):
        self.__problem = newProblem
        self.__loadData()
    '''
    def setMatrixSize(self,newValue):
        self.__matrixSize = newValue
    def setNumberOfAnts(self,newValue):
        self.__numberOfAnts = newValue
    def setNumberOfIterations(self,newValue):
        self.__numberOfIterations = newValue
    def setAlpha(self,newValue):
        self.__alpha = newValue
    def setBeta(self,newValue):
        self.__beta = newValue
    def setRho(self,newValue):
        self.__rho = newValue
    def setQ0(self,newValue):
        self.__q0 = newValue

    '''
    def interuptProcess(self):
        self.__interupted = True

    def startACO(self,progress_callback):
        sol=None
        self.__interupted = False

        self.__trace = [[[1 for i in range(self.__matrixSize)] for j in range(self.__matrixSize)] for k in range(2*self.__matrixSize)]

        bestSol = self.__performACOIteration()

        bestFitnesses = [bestSol.fitness()]
        bestForEachIter = [bestSol.fitness()]
        if bestFitnesses[0] == 0:
            return (bestSol,1,bestFitnesses,bestForEachIter)
        for i in range(self.__numberOfIterations-1):
            sol = self.__performACOIteration()
            if sol.fitness()<=bestSol.fitness():
                bestSol=copy.deepcopy(sol)
                if bestSol.fitness() == 0:
                    bestForEachIter.append(sol.fitness())
                    bestFitnesses.append(bestSol.fitness())
                    return (bestSol,i+2,bestFitnesses,bestForEachIter)
            bestForEachIter.append(sol.fitness())
            bestFitnesses.append(bestSol.fitness())
            if self.__interupted == True:
                break
            if i%10 == 0 and not self.__testing:
                progress_callback.emit((bestSol,i))

        return (bestSol,i+2,bestFitnesses,bestForEachIter)
    def __performACOIteration(self):
        antSet=[Ant(self.__matrixSize) for i in range(self.__numberOfAnts)]

        for i in range(2*self.__matrixSize*(self.__matrixSize-1)):
            for x in antSet:
                x.addMove(self.__q0,self.__trace,self.__alpha,self.__beta)

        for ant in antSet:
            if ant.fitness() == 0:
                return ant

            #print(x.fitness())
            #print(trace)
        dTrace=[ 1.0 / antSet[i].fitness() for i in range(len(antSet))]
        for k in range(len(self.__trace)):
            for i in range(len(self.__trace[k])):
                for j in range(len(self.__trace[i])):
                    self.__trace[k][i][j] = (1-self.__rho)*self.__trace[k][i][j]
        for k in range(len(antSet)):
            for i in range(len(antSet[k].getPath())):
                for j in range(len(antSet[k].getPath()[i])-1):
                    x = antSet[k].getPath()[i][j]
                    y = antSet[k].getPath()[i][j+1]
                    self.__trace[i][x][y] += dTrace[k]

        bestLocalSolution=[ [antSet[i].fitness(), i] for i in range(len(antSet))]
        bestLocalSolution=max(bestLocalSolution)
        return antSet[bestLocalSolution[1]]


"""
Module to preprocess email before proceed more
"""

import re
import pandas as pd
from halo import Halo

class EmailCleaner:
    """
    Class support cleansing function for Email
    """

    def clean_email(
        self,
        email: str
    ) -> str:
        """
        Process cleaning email:
        1. Remove spaces

        Parameters
        ----------
        email : str
            The input email to clean

        Returns
        -------
        str
            Cleaned email without any spaces
        """

        cleaned_email = self._remove_spaces(email)

        return cleaned_email

    def _remove_spaces(
        self,
        email: str
    ) -> str:
        """
        Function to remove spaces from email
        """
        cleaned_email = re.sub(' +', '', email)

        return cleaned_email

@Halo(
    text='Cleansing email',
    color='cyan',
    spinner='dots7',
    text_color='magenta'
)
def clean_email(
    data: pd.DataFrame,
    email_col: str = 'email'
) -> pd.DataFrame:
    """
    Process cleansing email from dataframe
    and created `cleaned_<email_col>` column contains the cleaned email

    Parameters
    ----------
    data : pd.DataFrame
        The input dataframe contains a column with email
    email_col : str, optional
        The name of the column contains email records, by default 'email'

    Returns
    -------
    pd.DataFrame
        The original dataframe with an additional column contains cleaned email
    """

    cleaner = EmailCleaner()

    cleaned_data = data

    cleaned_data[f'cleaned_{email_col}'] =\
        cleaned_data[email_col].apply(
            cleaner.clean_email
    )

    return cleaned_data


import cv2
import numpy as np
import matplotlib.pyplot as plt
import math

def hanning2D(n):
    h = np.hanning(n)
    return np.sqrt(np.outer(h,h))

def highpassFilter(size):
    rows = np.cos(np.pi*np.matrix([-0.5 + x/(size[0]-1) for x in range(size[0])]))
    cols = np.cos(np.pi*np.matrix([-0.5 + x/(size[1]-1) for x in range(size[1])]))
    X = np.outer(rows,cols)
    return (1.0 - X) * (2.0 - X)

domek = cv2.cvtColor(cv2.imread('./obrazy_Mellin/domek_r30.pgm'), cv2.COLOR_BGR2GRAY)
wzor = cv2.cvtColor(cv2.imread('./obrazy_Mellin/domek_r0_64.pgm'), cv2.COLOR_BGR2GRAY)

# wzor w rozmiarze obrazka bez filtracji
wzor_NP = np.zeros(domek.shape, dtype=np.uint8) #  NP- non performance
# okno Hanninga dla wzoru
han = hanning2D(wzor.shape[0])

# centrowanie wzoru
wzor_ = np.zeros(domek.shape, dtype = np.uint8)
l = np.int((domek.shape[0]-wzor.shape[0])/2)
r = np.int((domek.shape[1]+wzor.shape[1])/2)
wzor_[l:r,l:r] = wzor * han
wzor_NP[l:r,l:r] = wzor
# FFT na obrazkach
wzor_FFT = np.fft.fft2(wzor_)
domek_FFT = np.fft.fft2(domek)

# shift na obrazkach
wzor_SHIFT = np.fft.fftshift(wzor_FFT)
domek_SHIFT = np.fft.fftshift(domek_FFT)

# filtrowanie obrazków filterm górnoprzepustowym
wzor_F = wzor_SHIFT * highpassFilter(wzor_SHIFT.shape)
domek_F = domek_SHIFT * highpassFilter(domek_SHIFT.shape)

# parametry transformaty LogPolar
R = int(wzor_F.shape[0]//2)
M = 2*R/np.log(R)
# przygotowanie obrazków moduł liczb zespolonych
wzor_ABS = np.abs(wzor_F)
domek_ABS = np.abs(domek_F)
# transformata LogPolar
wzor_LP = cv2.logPolar(wzor_ABS, (wzor_F.shape[0]//2, wzor_F.shape[1]//2), M, cv2.INTER_LINEAR + cv2.WARP_FILL_OUTLIERS)
domek_LP = cv2.logPolar(domek_ABS, (domek_F.shape[0]//2, domek_F.shape[1]//2), M, cv2.INTER_LINEAR + cv2.WARP_FILL_OUTLIERS)

# ponowna transformata FFT
wzor_FFT2 = np.fft.fft2(wzor_LP)
domek_FFT2 = np.fft.fft2(domek_LP)

# korelacja ########################

ccor = np.conj(wzor_FFT2) * domek_FFT2
ccor = ccor/np.abs(ccor)
ccor = np.fft.ifftshift(ccor)
ccor = np.fft.ifft2(ccor)

wsp_kata, wsp_logr = np.unravel_index(np.argmax(abs(ccor)), ccor.shape)

# przeliczanie na skalowanie i stopnie
if wsp_logr > wzor_FFT2.shape[1]//2:
    wykl = wzor_FFT2.shape[1] - wsp_logr
else:
    wykl = - wsp_logr
A = (wsp_kata * 360.0)/wzor_FFT2.shape[1]
skala = np.exp(1/M) ** wykl
kat1 = 360 - A
kat2 = 360 - A - 180

# przeksztalcenie afiniczne
srodekTrans = [math.floor((domek.shape[0] + 1) / 2), math.floor((domek.shape[1] + 1 ) / 2)]
macierz_translacji1 = cv2.getRotationMatrix2D((srodekTrans[0], srodekTrans[1]), kat1, skala)
macierz_translacji2 = cv2.getRotationMatrix2D((srodekTrans[0], srodekTrans[1]), kat2, skala)

d1 = cv2.warpAffine(wzor_NP, macierz_translacji1, (wzor_NP.shape[1], wzor_NP.shape[0]))
d2 = cv2.warpAffine(wzor_NP, macierz_translacji2, (wzor_NP.shape[1], wzor_NP.shape[0]))

plt.figure(1)
plt.gray()
plt.imshow(wzor_NP)

d1fft = np.fft.fftshift(d1)
d2fft = np.fft.fftshift(d2)
d1fft = np.fft.fft2(d1fft)
d2fft = np.fft.fft2(d2fft)
d1fft = np.conj(d1fft)
d2fft = np.conj(d2fft)

korelacja1 = d1fft * domek_FFT
korelacja2 = d2fft * domek_FFT
korelacja1 = korelacja1/abs(korelacja1)
korelacja2 = korelacja2/abs(korelacja2)

korelacja1 = np.fft.ifftshift(korelacja1)
korelacja2 = np.fft.ifftshift(korelacja2)

korelacja1 = np.fft.ifft2(korelacja1)
korelacja2 = np.fft.ifft2(korelacja2)
korelacja1 = abs(korelacja1)
korelacja2 = abs(korelacja2)

y1, x1 = np.unravel_index( np.argmax(korelacja1), korelacja1.shape)
y2, x2 = np.unravel_index( np.argmax(korelacja2), korelacja2.shape)

if korelacja1[y1][x1] > korelacja2[y2][x2]:
    xk = x1
    yk = y1
    wzorzeck = d1
else:
    xk = x2
    yk = y2
    wzorzeck = d2

dx = xk - wzorzeck.shape[0]//2
dy = yk - wzorzeck.shape[1]//2
macierz_translacji = np.float32([[1,0,dx],[0,1,dy]])
obraz_przesuniety = cv2.warpAffine(wzorzeck, macierz_translacji, (wzorzeck.shape[1], wzorzeck.shape[0]))

plt.figure(1)
plt.imshow(obraz_przesuniety)
plt.figure(2)
plt.imshow(domek)

10. Korelacyjne dopasowywanie wzorca/zad2.py


#python黑箱：输入与输出

#input() 函数暂停程序运行，同时等待键盘输入；直到回车被按下，函数的参数即为提示语，输入的类型永远是字符串型（str）。
#print() 函数则接受字符串、数字、字典、列表甚至一些自定义类的输出。

#生产环境中，强制类型转换加上try，except

#文件输入输出
#      NLP（自然语言处理）

#读取文件；
# 去除所有标点符号和换行符，并把所有大写变成小写；
# 合并相同的词，统计每个词出现的频率，并按照词频从大到小排序；
# 将结果按行输出到文件 out.txt。

import re

def parse(text):
    # 使用正则表达式去除标点符号和换行符
    text = re.sub(r'[^\w ]', ' ', text)

    # 转为小写
    text = text.lower()

    # 生成所有单词的列表
    word_list = text.split(' ')

    # 去除空白单词
    word_list = filter(None, word_list)

    # 生成单词和词频的字典
    word_cnt = {}
    for word in word_list:
        if word not in word_cnt:
            word_cnt[word] = 0
        word_cnt[word] += 1

    # 按照词频排序
    sorted_word_cnt = sorted(word_cnt.items(), key=lambda kv: kv[1], reverse=True)

    return sorted_word_cnt

with open('in.txt', 'r') as fin:
    text = fin.read()

word_and_freq = parse(text)

with open('out.txt', 'w') as fout:
    for word, freq in word_and_freq:
        fout.write('{} {}\n'.format(word, freq))

#JSON序列化

import json

params = {
    'symbol': '123456',
    'type': 'limit',
    'price': 123.4,
    'amount': 23
}

params_str = json.dumps(params)

print('after json serialization')
print('type of params_str = {}, params_str = {}'.format(type(params_str), params))

original_params = json.loads(params_str)

print('after json deserialization')
print('type of original_params = {}, original_params = {}'.format(type(original_params), original_params))
print("-----------------------------------------------------------------------------")

#文件JSON

params = {
    'symbol': '123456',
    'type': 'limit',
    'price': 123.4,
    'amount': 23
}

with open('params.json', 'w') as fout:
    params_str = json.dump(params, fout)

with open('params.json', 'r') as fin:
    original_params = json.load(fin)

print('after json deserialization')
print('type of original_params = {}, original_params = {}'.format(type(original_params), original_params))

#剩下两个问题，谷歌工具Protocol Buffer和  如何读取大信息量的文件

#读取大文件

large_size =100

with open("in.txt","r")as fin:
    text =""
    while True:
        str =fin.read(large_size)
        if not str:
            break
        text +=str
    # print(text)


import BaseHTTPServer
from StringIO import StringIO
import shutil, os

class MyHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):

    cmds = {'/ping': 'ping www.thinkware.se',
            '/netstat' : 'netstat -a',
            '/tracert': 'tracert www.thinkware.se',
            '/srvstats': 'net statistics server',
            '/wsstats': 'net statistics workstation',
            '/route' : 'route print',
            }

    def do_GET(self):
        """Serve a GET request."""
        f = self.send_head()
        if f:
            f = StringIO()
            machine = os.popen('hostname').readlines()[0]
            if self.path == '/':
                heading = "Select a command to run on %s" % (machine)
                body = (self.getMenu() +
                        "
The screen won't update until the selected "
                        "command has finished. Please be patient.")
            else:
                heading = "Execution of ``%s´´ on %s" % (
                           self.cmds[self.path], machine)
                cmd = self.cmds[self.path]
                body = 'Main Menu
%s
\n' % os.popen(
                    cmd).read()
                # Translation CP437 -> Latin 1 needed for Swedish Windows.
                body = body.decode('cp437').encode('latin1')
            f.write("<title>%s</title>\n" % (heading))
            f.write('
%s
\n' % (heading))
            f.write(body)
            f.write('\n')
            f.seek(0)
            self.copyfile(f, self.wfile)
            f.close()
        return f

    def do_HEAD(self):
        """Serve a HEAD request."""
        f = self.send_head()
        if f:
            f.close()

    def send_head(self):
        path = self.path
        if not path in ['/'] + self.cmds.keys():
            head = 'Command "%s" not found. Try one of these:
' % path
            msg = head + self.getMenu()
            self.send_error(404, msg)
            return None
        self.send_response(200)
        self.send_header("Content-type", 'text/html')
        self.end_headers()
        f = StringIO()
        f.write("A test %s\n" % self.path)
        f.seek(0)
        return f

    def getMenu(self):
            keys = self.cmds.keys()
            keys.sort()
            msg = []
            for k in keys:
                msg.append('
%s => %s
' %(
                                         k,  k,    self.cmds[k]))
            msg.append('
')
            return "\n".join(msg)

    def copyfile(self, source, outputfile):
        shutil.copyfileobj(source, outputfile)

def main(HandlerClass = MyHTTPRequestHandler,
         ServerClass = BaseHTTPServer.HTTPServer):
    BaseHTTPServer.test(HandlerClass, ServerClass)

if __name__ == '__main__':
    main()


import sys
import utils as dc
import argparse
import os
import logging
import datetime
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sb
import numpy as np
import matplotlib
import json

# good luck~

def read_input_file(args):
    """
    this function is to parse and read the input file.
    everything will be stored in parser arguments

    parse param added:
    args.ligands    -   dictionary of ligand class
    args.msa        -   multiple sequence alignment inside MSA class
    args.msta       -   multiple structure alignment inside MSA class
    args.receptor   -   receptor class
    :param args:
    :return:
    """

    # read standard input file
    ligands = {}
    ref = args.reference

    with open(args.input_file) as infile:
        for line in infile:
            if line[0] != "#":
                line = line.strip().split()
                type = line[0]

                # new ligand
                if type == "LIGAND":
                    p, name, pdb = line[1:]
                    this_lig = dc.Ligand(name, pdb=pdb)
                    this_lig.prot_msa = dc.create_msa(open(p))
                    assert name not in ligands, "I am not overwriting ligand {}".format(name)
                    ligands[name] = this_lig
                # new MSA
                if type == "MSA":
                    p = line[1]
                    msa = dc.MSA("MSA", reference=ref)
                    msa.msa = dc.create_msa(open(p))
                    args.msa = msa
                # new MSTA
                if type == "MSTA":
                    p = line[1]
                    msta = dc.MSA("MSTA", reference=ref)
                    msta.msa = dc.create_msa(open(p))
                    args.msta = msta
                # new receptor
                if type == "RECEPTOR":
                    name, p = line[1:]
                    receptor = dc.Receptor(name, pdb=pdb, reference="Hsap")
                    receptor.prot_msa = dc.create_msa(open(p))
                    args.receptor = receptor

        # add ligands
        args.ligands = ligands

def dir_prediction(args):
    """
    Divergence Inducing Residue Prediction
    Basically like cross-conservation but averaging over all paralogs and correcting for coevolution

    :param args:
    :return:
    """
    rp = args.reference          # reference ligand name
    prot = args.ligands[rp]             # reference ligand
    seq = prot.get_ref_seq()            # reference ligand sequence
    msta = args.msta                    # multiple structure alignment
    msa = args.msa                      # multiple sequence alignment
    contest = args.conservation_test    # conservation test type
    algtest = args.alignment_test       # conservation for ligand alignment type

    # FOR NOW HARDCODE
    args.msa_cols = ["EVO cons MSA", "MSA", "COEVO receptor MSA", "COEVO ligands MSA"]
    args.msta_cols = ["EVO cons MSTA","MSTA", "COEVO receptor MSTA","COEVO ligands MSTA"]
    # data preparation
    cs = {}

    # ligands alignment scorings
    cs["MSA"] = [round(x, 2) for x in msa.get_cons_scores(algtest)]
    cs["MSTA"] = [round(x, 2) for x in msta.get_cons_scores(algtest)]
    # now I need one evo cons from MSA alignment average and one from MSTA alignment average
    relative_conservation = ligand_table(args)
    cs["EVO cons MSA"] = average_score(relative_conservation,"MSA")
    cs["EVO cons MSTA"] = average_score(relative_conservation,"MSTA")

    # now let's do the coevolution score
    rel_intra_coevol, rel_inter_coevol = coevol_test(args)
    cs["COEVO receptor MSA"] = average_score(rel_inter_coevol,"MSA")
    cs["COEVO receptor MSTA"] = average_score(rel_inter_coevol,"MSTA")
    cs["COEVO ligands MSA"] = average_score(rel_intra_coevol,"MSA")
    cs["COEVO ligands MSTA"] = average_score(rel_intra_coevol,"MSTA")

    # now make it DataFrame
    cs = pd.DataFrame(cs)
    # insert relative positions
    cs.insert(0, 'POS', [str(x) + seq[x - 1] for x in range(1, 1 + len(cs))])

    # get the values of abcd:
    abcd = [1/int(x) for x in args.abcd.split(",")]
    # average MSA/MSTA then distance with
    avg_dirp, part_scores = calculate_dirp_score(cs,args.msa_cols,args.msta_cols, abcd)
    cs["avg DIR score"] = avg_dirp
    cs["partial scores"] = part_scores

    makeplots(cs, args)
    # plotting

def makeplots(cs, args):

    relabel_cols = {
      "EVO cons MSA": "Evolutionary conservation",
        "EVO cons MSTA": "Evolutionary conservation",
        "MSA": "Paralogs conservation",
        "MSTA": "Paralogs conservation",
        "COEVO receptor MSA":"Ligand-Receptor co-evolution",
        "COEVO receptor MSTA":"Ligand-Receptor co-evolution",
        "COEVO ligands MSA":"Ligands internal co-evolution",
        "COEVO ligands MSTA":"Ligands internal co-evolution"
    }
    # plots folder
    plot_output = args.output_path + "/plots/"
    if not os.path.exists(plot_output):
        os.makedirs(plot_output)
    logging.warning("running plotting module")

    # palette
    sb.set_palette(sb.color_palette("Dark2"))

    # distribution plots
    df_dist = cs[args.msa_cols + args.msta_cols].melt(var_name='rows')
    df_dist['type'] = ["MSA" if "MSA" in x else "MSTA" for x in df_dist['rows']]
    df_dist['rows'] = [" ".join(x.split(" ")[:-1]) if len(x) > 4 else "Ligands alignment" for x in df_dist['rows']]

    # rename
    df_dist = df_dist.rename(columns=relabel_cols)

    # plot distributions
    g = sb.FacetGrid(df_dist, row='rows', col='type', hue='rows')
    g = (g.map(sb.distplot, 'value', hist=False, rug=True)).set_titles("{col_name} | {row_name}")
    plt.savefig("{}/scores_distribution.png".format(plot_output), dpi=400)
    plt.close()

    # stacked box plot
    matplotlib.rcParams.update({'font.size': 10})
    # format data
    ilab = [args.msa_cols, args.msta_cols]
    df_stack = cs[['POS', 'partial scores']].copy()
    for laidx in range(2):
        for idx in range(4):
            this_col = []
            for x in df_stack['partial scores']:
                this_col.append(x[laidx][idx])
            df_stack["{}".format(ilab[laidx][idx])] = this_col
    del (df_stack['partial scores'])
    #rename
    df_msa = df_stack[args.msa_cols].rename(columns={k:v for k,v in relabel_cols.items() if k in args.msa_cols})
    df_msta = df_stack[args.msta_cols].rename(columns={k:v for k,v in relabel_cols.items() if k in args.msta_cols})
    # figure out how to do this
    fig, axes = plt.subplots(2, 1, figsize=(12, 24))
    df_msa.iloc[::-1].plot.barh(stacked=True,ax=axes[0])
    axes[0].set_yticklabels(cs['POS'][::-1])
    axes[0].set_title('MSA',fontsize=24)
    df_msta.iloc[::-1].plot.barh(stacked=True,ax=axes[1],legend=False)
    axes[1].set_yticklabels(cs['POS'][::-1])
    axes[1].set_title('MSTA',fontsize=24)

    # handle legends
    patches, labels = axes[0].get_legend_handles_labels()
    axes[0].legend(patches,labels,bbox_to_anchor=(0.45,-0.08),ncol=2,loc="center", prop={'size': 18})
    plt.savefig("{}/combined_score.png".format(plot_output), dpi=400)
    plt.close()

    # same but sorted
    fig, axes = plt.subplots(2, 1, figsize=(12, 24))
    msa_sort = df_stack[args.msa_cols + ["POS"]].copy()
    msa_sort["sum"] = msa_sort[args.msa_cols].sum(axis=1)
    msa_sort = msa_sort.sort_values(by=['sum'])
    del(msa_sort['sum'])
    msa_lab = msa_sort.pop('POS')
    msa_sort = msa_sort.rename(columns=relabel_cols)
    msa_sort.plot.barh(stacked=True,ax=axes[0])
    axes[0].set_yticklabels(msa_lab)
    axes[0].set_title('MSA',fontsize=32)
    #msta
    msta_sort = df_stack[args.msta_cols + ["POS"]].copy()
    msta_sort["sum"] = msta_sort[args.msta_cols].sum(axis=1)
    msta_sort = msta_sort.sort_values(by=['sum'])
    del(msta_sort['sum'])
    msta_lab = msta_sort.pop('POS')
    msta_sort.plot.barh(stacked=True,ax=axes[1],legend=False)
    axes[1].set_yticklabels(msta_lab)
    axes[1].set_title('MSTA',fontsize=32)
    # handle legends
    patches, labels = axes[0].get_legend_handles_labels()
    axes[0].legend(patches,labels,bbox_to_anchor=(0.45,-0.08),ncol=2,loc="center", prop={'size': 18})

    plt.savefig("{}/combined_score_sorted.png".format(plot_output), dpi=400)
    plt.close()

    # save top 12
    matplotlib.rcParams.update({'font.size': 18})
    fig, axes = plt.subplots(2, 1, figsize=(12, 24))
    msa_sort.tail(12).plot.barh(stacked=True,ax=axes[0])
    axes[0].set_yticklabels(msa_lab[-12:])
    axes[0].set_title('MSA',fontsize=32)
    msta_sort.tail(12).plot.barh(stacked=True,ax=axes[1],legend=False)
    axes[1].set_yticklabels(msta_lab[-12:])
    axes[1].set_title('MSTA',fontsize=32)
    # handle legends
    patches, labels = axes[0].get_legend_handles_labels()
    axes[0].legend(patches,labels,bbox_to_anchor=(0.45,-0.09),ncol=2,loc="center", prop={'size': 18})

    plt.savefig("{}/combined_score_sorted_top12.png".format(plot_output), dpi=400)
    plt.close()

    # save text output also but add average
    #index plus one
    cs.index = cs.index + 1
    with open("{}/DIRpred.csv".format(args.output_path), "w") as outfile:
        cs.to_csv(outfile)
    # save also sorted version
    sorted_cs = cs.sort_values("avg DIR score", ascending=False)
    sorted_cs.index = [i for i in range(1,len(sorted_cs.index)+1)]
    with open("{}/DIRpred_sorted.csv".format(args.output_path), "w") as outfile:
        sorted_cs.to_csv(outfile)

def calculate_dirp_score(df, msa_ids, msta_ids, abcd=(0.25,0.25,0.25,0.25)):
    """sum method, v1.0
    the 4 scores are
    I: avg evolutionary conservation (positive)
    II: ligands alignment conservation (negative)
    III: avg ligand-receptor max coevolution (positive)
    IV: avg ligand-ligand max coevolution (negative)

    the 4 scores will be weighted by a parameter each, by default 0.25, and summed to compose the final score

    returns:
    average MSA,MSTA dirp score array = a(I) + b(1-II) + c(III) + d(1-IV)
    partial scores array = same as before but comma instead of sum, and (MSAps,MSTAps)
    """

    a,b,c,d = abcd
    MSA_score = []
    MSTA_score = []
    partial_score = []

    for i,r in df.iterrows():
        # msa
        I,II,III,IV = list(r[msa_ids])
        msa_partial_score = a * I, b * (1-II), c * III, d * (1 - IV)
        MSA_score.append(sum(msa_partial_score))
        # msta
        I,II,III,IV = list(r[msta_ids])
        msta_partial_score = a * I, b * (1-II), c * III, d * (1 - IV)
        MSTA_score.append(sum(msta_partial_score))
        partial_score.append((msa_partial_score, msta_partial_score))

    return np.mean([MSA_score, MSTA_score], axis=0).round(2), partial_score

def average_score(d,alg_type):
    """returns the average value from the dictionary of relative scores"""
    l = []
    for k in d:
        if alg_type in k:
            a = [np.nan if x == "-" else float(x) for x in d[k]]
            l.append(a)
    mean_out = np.nanmean(l,axis=0).round(2)
    return mean_out

def ligand_table(args):
    """
    realigns the paralogs to a reference sequence and save the results along with the reference-aligned conservation, or sort of...
    :param args:
    :return:
    """
    rp = args.reference          # reference ligand name
    prot = args.ligands[rp]             # reference ligand
    seq = prot.get_ref_seq()            # reference ligand sequence
    msta = args.msta                    # multiple structure alignment
    msa = args.msa                      # multiple sequence alignment
    contest = args.conservation_test    # conservation test type
    algtest = args.alignment_test       # ligand alignment test type

    # data preparation
    cs = {}
    rel_cons = {}  # relative conservation is stored here

    # add referenced positions
    for m in [msa, msta]:
        for n in m.get_names():
            logging.warning("processing {}".format(n))
            assert n in args.ligands, "{} not found in ligands list: {}".format(n,args.ligands.keys())
            this_ligand = args.ligands[n]
            this_ligand_score = this_ligand.get_cons_scores(contest)
            this_name = "{}_{}".format(m.name, n)
            cs[this_name] = m.get_referenced_positions(n)
            rel_cons[this_name] = m.get_referenced_scores(n, this_ligand, this_ligand_score)

    # add also cons score
    cs["MSA"] = [round(x, 2) + 0.04 for x in msa.get_cons_scores(algtest)]
    cs["MSTA"] = [round(x, 2) - 0.04 for x in msta.get_cons_scores(algtest)]
    cs[prot.name] = prot.get_cons_scores(contest)
    for n in rel_cons:
        cs[n+"_cons_{}".format(contest)] = rel_cons[n]

    cs = pd.DataFrame(cs)
    # add egf pos
    cs.insert(0, 'POS', [str(x) + seq[x - 1] for x in range(1, 1 + len(cs))])

    with open("{}/ligand_table.csv".format(args.output_path), "w") as outfile:
        cs.to_csv(outfile)

    return rel_cons

def coevol_test(args):
    """
    has to return two dictionaries, intra and inter coevolution
    as key msa_ligand, as values, an array based on reference with the max coevolution score
    :param args:
    :return:
    """
    # preparation
    rp = args.reference          # reference ligand name
    prot = args.ligands[rp]             # reference ligand
    seq = prot.get_ref_seq()            # reference sequence
    receptor = args.receptor            # receptor MSA
    msta = args.msta  # multiple structure alignment
    msa = args.msa  # multiple sequence alignment
    coevo_test = args.coevolution_test
    coevol_output = args.output_path + "/coevolution/"
    if not os.path.exists(coevol_output):
        os.makedirs(coevol_output)
    logging.warning("running coevolution module")

    # receptor intra coevol
    _ = dc.intra_coevol(receptor, "{}/{}".format(coevol_output, receptor.name), coevo_test)
    # every ligand coevol
    # now try to combine all ligands together using msa and msta
    # all ligands
    intra_rc,inter_rc = {},{}
    report_intra, report_inter = {},{}
    for m in [msa, msta]:
        lig_rc = dc.all_ligands_coevol(args, m, "{}/all_ligands".format(coevol_output), coevo_test)
        this_name = "{}_all_ligands".format(m.name)
        intra_rc[this_name] = lig_rc
        report_intra[this_name] = lig_rc

        for n in m.get_names():
            logging.warning("processing {}".format(n))
            assert n in args.ligands, "{} not found in ligands list: {}".format(n, args.ligands.keys())
            this_ligand = args.ligands[n]
            this_ligand_inter_score = dc.inter_coevol(this_ligand, receptor, "{}/{}u{}intercoevo".format(coevol_output, this_ligand.name, receptor.name), coevo_test)
            this_name = "{}_{}".format(m.name, n)
            report_inter[this_name] = m.get_referenced_positions(n)
            inter_rc[this_name] = m.get_referenced_scores(n, this_ligand, this_ligand_inter_score)

    report_intra["MSA"] = dc.intra_coevol(msa,"{}/{}".format(coevol_output, msa.name), coevo_test)
    report_intra["MSTA"] = dc.intra_coevol(msta, "{}/{}".format(coevol_output, msta.name), coevo_test)
#                                                 args.coevolution_test)
    report_inter[prot.name] = dc.inter_coevol(prot, receptor, "{}/inter_{}".format(coevol_output, prot.name), coevo_test)
    for n in intra_rc:
        report_intra[n+"_coevol_{}".format(coevo_test)] = intra_rc[n]
    for n in inter_rc:
        report_inter[n+"_coevol_{}".format(coevo_test)] = inter_rc[n]
    # make df
    report_intra_df = pd.DataFrame(report_intra)
    report_inter_df = pd.DataFrame(report_inter)
    # add egf pos
    report_intra_df.insert(0, 'POS', [str(x) + seq[x - 1] for x in range(1, 1 + len(report_intra_df))])
    report_inter_df.insert(0, 'POS', [str(x) + seq[x - 1] for x in range(1, 1 + len(report_inter_df))])

    # save reports
    with open("{}/intra_coevol_report.csv".format(coevol_output), "w") as outfile:
        report_intra_df.to_csv(outfile)
    with open("{}/inter_coevol_report.csv".format(coevol_output), "w") as outfile:
        report_inter_df.to_csv(outfile)

    return intra_rc, inter_rc

def main(argv):

    # PARSER
    parser = argparse.ArgumentParser(fromfile_prefix_chars='@', description="parser for handling input files of cons-cons pipeline")

    parser.add_argument("--input-file", required=True, help="input file contains all ligands with their MSA location"
                                                        "the MStA path and its format is very important, check example")
    parser.add_argument("--output-path", required=True, help="path to output folder, will be created if not ex")
    parser.add_argument("--test-type", default="DIRP", help="""The type of test:
     DIRP - average multiple concon, or Divergence Inducing Residue Prediction
     """)
    parser.add_argument("--reference", default="", help="the reference protein for DIRpred test.")
    parser.add_argument("--conservation-test", default="id", help="""type of conservation measure:"
     id - identity
     blos - blosum62
     jsdw - jensen shannon divergence with window (as in concavity)""")
    parser.add_argument("--alignment-test", default="", help="type of conservation measure, used for alignment. By default, like conservation_test")
    parser.add_argument("--coevolution-test", default="MI",
                        help="coevolution measure. By default, MI: mutual information. can be MIp, APC corrected MI")
    parser.add_argument("--abcd", default="4,4,4,4", help="the individual contributions for each score, as in 1 over x, by defaultis: 4,4,4,4. meaning 1 over 4, four times.")
    args = parser.parse_args()

    # CREATE LOG DETAILS
    if not os.path.exists("logs"):
        os.mkdir("logs")
    logging.basicConfig(level=logging.DEBUG, filename="logs/{}.txt".format(str(datetime.datetime.now()).replace(" ", "_")))
    logging.warning("LOGFILE INITIATED\nPIPELINE STARTED\nOk, I am back to life and ready to conquer the wo... oh.. damn..\n")

    # OUTPUT FOLDER CREATION
    o = args.output_path
    if not os.path.exists(o):
        os.makedirs(o)
        with open('{}/args.txt'.format(o), 'w') as f:
            json.dump(args.__dict__, f, indent=2)
        logging.warning("~~~\nCREATING OUTPUT FOLDER at {}\n~~~".format(o))

    # CONSERVATION check
    if not args.alignment_test:
        args.alignment_test = args.conservation_test

    # INPUT FILE READER
    read_input_file(args)

    # REPORT ARGS
    logging.warning("~~~~~pipeline has the following args:\n{}\n~~~~~".format(args))

    # DIRP
    if args.test_type == "DIRP":
        dir_prediction(args)

    if args.test_type == "COEVOL":
        coevol_test(args)

    if args.test_type == "LIGTAB":
        _ = ligand_table(args)

if __name__ == '__main__':
    main(sys.argv)


from django import template
register = template.Library()

@register.filter(name='categorySelected')
def categorySelected(category,cat_name):
	if category == cat_name:
		return True
	else:
		return False

@register.filter(name='countLC')
def countLC(dict,id):
	newList = []
	for i in dict:
		if i.post.id == id:
			newList.append(i.post.id)
	return len(newList)

@register.filter(name='hasLike')
def hasLike(allLike,loggedInUserId):
	for like in allLike:
		if like.user.id == loggedInUserId:
			return True
	return False

@register.filter(name='hasFriend')
def hasFriend(friendList,loggedInUserId):
	for friend in friendList:
		if friend.receiver.id == loggedInUserId or friend.sender.id == loggedInUserId:
			return True
	return False

@register.filter(name='loggedInUserReqFriend')
def loggedInUserReqFriend(friendList,profile_id):
	for friend in friendList:
		if friend.sender.id == profile_id:
			return True
	return False

@register.filter(name='messageFilter')
def messageFilter(msgObj):
	mList = []


import torchvision.models as models
import torch
import torch.nn as nn
import torch.nn.functional as F
import os
from torch.utils.data import random_split
from PIL import Image
from pathlib import Path
import numpy as np
import cv2
import time
import torchvision.transforms as T
from PIL import Image

data_dir = '/home/ican/Downloads/wow/Garbage classification/Garbage classification'
classes = os.listdir(data_dir)

from torchvision.datasets import ImageFolder
import torchvision.transforms as transforms

transformations = transforms.Compose([transforms.Resize((256, 256)), transforms.ToTensor()])

dataset = ImageFolder(data_dir, transform = transformations)

#train_ds, val_ds, test_ds = random_split(dataset, [1593, 176, 758])

def accuracy(outputs, labels):
    _, preds = torch.max(outputs, dim=1)
    return torch.tensor(torch.sum(preds == labels).item() / len(preds))

class ImageClassificationBase(nn.Module):
    def training_step(self, batch):
        images, labels = batch
        out = self(images)                  # Generate predictions
        loss = F.cross_entropy(out, labels) # Calculate loss
        return loss
    def validation_step(self, batch):
        images, labels = batch
        out = self(images)                    # Generate predictions
        loss = F.cross_entropy(out, labels)   # Calculate loss
        acc = accuracy(out, labels)           # Calculate accuracy
        return {'val_loss': loss.detach(), 'val_acc': acc}

    def validation_epoch_end(self, outputs):
        batch_losses = [x['val_loss'] for x in outputs]
        epoch_loss = torch.stack(batch_losses).mean()   # Combine losses
        batch_accs = [x['val_acc'] for x in outputs]
        epoch_acc = torch.stack(batch_accs).mean()      # Combine accuracies
        return {'val_loss': epoch_loss.item(), 'val_acc': epoch_acc.item()}

    def epoch_end(self, epoch, result):
        print("Epoch {}: train_loss: {:.4f}, val_loss: {:.4f}, val_acc: {:.4f}".format(
            epoch+1, result['train_loss'], result['val_loss'], result['val_acc']))

class ResNet(ImageClassificationBase):
    def __init__(self):
        super().__init__()
        # Use a pretrained model
        self.network = models.resnet50(pretrained=True)
        # Replace last layer
        num_ftrs = self.network.fc.in_features
        self.network.fc = nn.Linear(num_ftrs, 6)

    def forward(self, xb):
        return torch.sigmoid(self.network(xb))

def to_device(data, device):
    """Move tensor(s) to chosen device"""
    if isinstance(data, (list,tuple)):
        return [to_device(x, device) for x in data]
    return data.to(device, non_blocking=True)

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print("Device being used:", device)

model = ResNet()
model.load_state_dict(torch.load('/home/ican/Downloads/newest_file', map_location="cuda:0"))
model.to(device)
model.eval()

def gstreamer_pipeline(
    capture_width=1280,
    capture_height=720,
    display_width=820,
    display_height=616,
    framerate=30,
    flip_method=0,
):
    return (
        "nvarguscamerasrc ! "
        "video/x-raw(memory:NVMM), "
        "width=(int)%d, height=(int)%d, "
        "format=(string)NV12, framerate=(fraction)%d/1 ! "
        "nvvidconv flip-method=%d ! "
        "video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
        "videoconvert ! "
        "video/x-raw, format=(string)BGR ! appsink"
        % (
            capture_width,
            capture_height,
            framerate,
            flip_method,
            display_width,
            display_height,
        )
    )

def predict_image(img, model):
    # Convert to a batch of 1
    xb = to_device(img.unsqueeze(0), device)
    # Get predictions from model
    yb = model(xb)
    # Pick index with highest probability
    prob, preds  = torch.max(yb, dim=1)

    # Retrieve the class label
    return dataset.classes[preds[0].item()]

#img, label = test_ds[27]
#plt.imshow(img.permute(1, 2, 0))

def test_one():
    image = Image.open(Path('/home/ican/Downloads/test2/lacroix10.jpg'))
    img  = transformations(image)
    print('predicted', predict_image(img, model))
    return

def transformses(trains):
    new_image = transformations(trains)
    return new_image

prev_frame_time = 0
next_frame_time = 0
cap = cv2.VideoCapture(gstreamer_pipeline(), cv2.CAP_GSTREAMER)
ret = True

clip = []
while(ret):
    # Capture frame-by-frame
    #window_handle = cv2.namedWindow('iCAN_Detection', cv2.WINDOW_AUTOSIZE)
    ret, frame = cap.read()

    gray = cv2.resize(frame, (256, 256))
    gray2 = cv2.cvtColor(gray, cv2.COLOR_BGR2RGB)
    pil_image = Image.fromarray(gray2)

    new_frame_time = time.time()
    fps = 1/(new_frame_time-prev_frame_time)
    prev_frame_time = new_frame_time
    #frame2 = frame.astype('float32')
    #curr_img = cv2.resize(pil_image, (256, 256))
    #curr_img has been reiszew, apply PIL to it

    now_img = transformses(pil_image)
    # converting the fps into integer
    #
    fps = int(fps)

    # converting the fps to string so that we can display it on frame
    # by using putText function
    fps = str(fps)

    #img = transformations(frame)
    #print('predicted', predict_image(img, model))
    print('predicted', predict_image(now_img, model))

    #in between put somethng
    cv2.putText(frame, fps, (7, 70), cv2.FONT_HERSHEY_SIMPLEX, 3, (255, 255, 0))
    cv2.imshow('image', pil_image)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

#test_one()xasd


from pysnmp.entity import config
from pysnmp import error
from pyasn1.compat.octets import null

__all__ = ['CommunityData', 'UsmUserData',
           'usm3DESEDEPrivProtocol', 'usmAesCfb128Protocol',
           'usmAesCfb192Protocol', 'usmAesCfb256Protocol',
           'usmDESPrivProtocol', 'usmHMACMD5AuthProtocol',
           'usmHMACSHAAuthProtocol', 'usmNoAuthProtocol',
           'usmNoPrivProtocol']

class CommunityData:
    """Creates SNMP v1/v2c configuration entry.

    This object can be used by
    :py:class:`~pysnmp.hlapi.asyncore.AsyncCommandGenerator` or
    :py:class:`~pysnmp.hlapi.asyncore.AsyncNotificationOriginator`
    and their derivatives for adding new entries to Local Configuration
    Datastore (LCD) managed by :py:class:`~pysnmp.hlapi.SnmpEngine`
    class instance.

    See :RFC:`2576#section-5.3` for more information on the
    *SNMP-COMMUNITY-MIB::snmpCommunityTable*.

    Parameters
    ----------
    communityIndex : str
        Unique index value of a row in snmpCommunityTable. If it is the
        only positional parameter, it is taken as *communityName*.
    communityName : str
        SNMP v1/v2c community string.
    mpModel : int
        SNMP version - 0 for SNMPv1 and 1 for SNMPv2c.
    contextEngineId : str
        Indicates the location of the context in which management
        information is accessed when using the community string
        specified by the above communityName.
    contextName : str
        The context in which management information is accessed when
        using the above communityName.
    tag : str
        Arbitrary string that specifies a set of transport endpoints
        to which a notification may be sent using communityName above
        (see also :RFC:`3413#section-4.1.4`).

    Examples
    --------
    >>> from pysnmp.hlapi import CommunityData
    >>> CommunityData('public')
    CommunityData(communityIndex='s1410706889', communityName=<COMMUNITY>, mpModel=1, contextEngineId=None, contextName='', tag='')
    >>> CommunityData('public', 'public')
    CommunityData(communityIndex='public', communityName=<COMMUNITY>, mpModel=1, contextEngineId=None, contextName='', tag='')
    >>>

    """
    mpModel = 1 # Default is SMIv2
    securityModel = mpModel + 1
    securityLevel = 'noAuthNoPriv'
    contextName = null
    tag = null
    def __init__(self, communityIndex, communityName=None, mpModel=None,
                 contextEngineId=None, contextName=None, tag=None,
                 securityName=None):
        if mpModel is not None:
            self.mpModel = mpModel
            self.securityModel = mpModel + 1
        self.contextEngineId = contextEngineId
        if contextName is not None:
            self.contextName = contextName
        if tag is not None:
            self.tag = tag
        # a single arg is considered as a community name
        if communityName is None:
            communityName, communityIndex = communityIndex, None
        self.communityName = communityName
        # Autogenerate communityIndex if not specified
        if communityIndex is None:
            self.communityIndex = self.securityName = 's%s' % hash(
                (self.communityName, self.mpModel, self.contextEngineId,
                 self.contextName, self.tag)
            )
        else:
            self.communityIndex = communityIndex
            self.securityName = securityName is not None and securityName or communityIndex

    def __hash__(self):
        raise TypeError('%s is not hashable' % self.__class__.__name__)

    def __repr__(self):
        return '%s(communityIndex=%r, communityName=<COMMUNITY>, mpModel=%r, contextEngineId=%r, contextName=%r, tag=%r, securityName=%r)' % (
            self.__class__.__name__,
            self.communityIndex,
            self.mpModel,
            self.contextEngineId,
            self.contextName,
            self.tag,
            self.securityName
        )

    def clone(self, communityIndex=None, communityName=None,
              mpModel=None, contextEngineId=None,
              contextName=None, tag=None, securityName=None):
        # a single arg is considered as a community name
        if communityName is None:
            communityName, communityIndex = communityIndex, None
        return self.__class__(
            communityIndex,
            communityName is None and self.communityName or communityName,
            mpModel is None and self.mpModel or mpModel,
            contextEngineId is None and self.contextEngineId or contextEngineId,
            contextName is None and self.contextName or contextName,
            tag is None and self.tag or tag,
            securityName is None and self.securityName or securityName
        )

#: No Authentication Protocol.
usmNoAuthProtocol = config.usmNoAuthProtocol
#: The HMAC-MD5-96 Digest Authentication Protocol (:RFC:`3414#section-6`)
usmHMACMD5AuthProtocol = config.usmHMACMD5AuthProtocol
#: The HMAC-SHA-96 Digest Authentication Protocol (:RFC:`3414#section-7`)
usmHMACSHAAuthProtocol = config.usmHMACSHAAuthProtocol

#: No Privacy Protocol.
usmNoPrivProtocol = config.usmNoPrivProtocol
#: The CBC-DES Symmetric Encryption Protocol (:RFC:`3414#section-8`)
usmDESPrivProtocol = config.usmDESPrivProtocol
#: The 3DES-EDE Symmetric Encryption Protocol (`draft-reeder-snmpv3-usm-3desede-00 <https://tools.ietf.org/html/draft-reeder-snmpv3-usm-3desede-00#section-5>`_)
usm3DESEDEPrivProtocol = config.usm3DESEDEPrivProtocol
#: The CFB128-AES-128 Symmetric Encryption Protocol (:RFC:`3826#section-3`)
usmAesCfb128Protocol = config.usmAesCfb128Protocol
#: The CFB128-AES-192 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 <https://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_)
usmAesCfb192Protocol = config.usmAesCfb192Protocol
#: The CFB128-AES-256 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 <https://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_)
usmAesCfb256Protocol = config.usmAesCfb256Protocol

class UsmUserData:
    """Creates SNMP v3 User Security Model (USM) configuration entry.

    This object can be used by
    :py:class:`~pysnmp.hlapi.asyncore.AsyncCommandGenerator` or
    :py:class:`~pysnmp.hlapi.asyncore.AsyncNotificationOriginator`
    and their derivatives for adding new entries to Local Configuration
    Datastore (LCD) managed by :py:class:`~pysnmp.hlapi.SnmpEngine`
    class instance.

    See :RFC:`3414#section-5` for more information on the
    *SNMP-USER-BASED-SM-MIB::usmUserTable*.

    Parameters
    ----------
    userName : str
        A human readable string representing the name of the SNMP USM user.
    authKey : str
        Initial value of the secret authentication key.  If not set,
        :py:class:`~pysnmp.hlapi.usmNoAuthProtocol`
        is implied.  If set and no *authProtocol* is specified,
        :py:class:`~pysnmp.hlapi.usmHMACMD5AuthProtocol`
        takes effect.
    privKey : str
        Initial value of the secret encryption key.  If not set,
        :py:class:`~pysnmp.hlapi.usmNoPrivProtocol`
        is implied.  If set and no *privProtocol* is specified,
        :py:class:`~pysnmp.hlapi.usmDESPrivProtocol`
        takes effect.
    authProtocol : tuple
        An indication of whether messages sent on behalf of this USM user
        can be authenticated, and if so, the type of authentication protocol
        which is used.

        Supported authentication protocol identifiers are:

        * :py:class:`~pysnmp.hlapi.usmNoAuthProtocol` (default is *authKey* not given)
        * :py:class:`~pysnmp.hlapi.usmHMACMD5AuthProtocol` (default if *authKey* is given)
        * :py:class:`~pysnmp.hlapi.usmHMACSHAAuthProtocol`
    privProtocol : tuple
        An indication of whether messages sent on behalf of this USM user
        be encrypted, and if so, the type of encryption protocol which is used.

        Supported encryption protocol identifiers are:

        * :py:class:`~pysnmp.hlapi.usmNoPrivProtocol` (default is *authKey* not given)
        * :py:class:`~pysnmp.hlapi.usmDESPrivProtocol` (default if *authKey* is given)
        * :py:class:`~pysnmp.hlapi.usm3DESEDEPrivProtocol`
        * :py:class:`~pysnmp.hlapi.usmAesCfb128Protocol`
        * :py:class:`~pysnmp.hlapi.usmAesCfb192Protocol`
        * :py:class:`~pysnmp.hlapi.usmAesCfb256Protocol`

    Examples
    --------
    >>> from pysnmp.hlapi import UsmUserData
    >>> UsmUserData('testuser', authKey='authenticationkey')
    UsmUserData(userName='testuser', authKey=<AUTHKEY>, privKey=<PRIVKEY>, authProtocol=(1,3,6,1,6,3,10,1,1,2), privProtocol=(1,3,6,1,6,3,10,1,2,1))
    >>> UsmUserData('testuser', authKey='authenticationkey', privKey='encryptionkey')
    UsmUserData(userName='testuser', authKey=<AUTHKEY>, privKey=<PRIVKEY>, authProtocol=(1,3,6,1,6,3,10,1,1,2), privProtocol=(1,3,6,1,6,3,10,1,2,2))
    >>>

    """
    authKey = privKey = None
    authProtocol = config.usmNoAuthProtocol
    privProtocol = config.usmNoPrivProtocol
    securityLevel = 'noAuthNoPriv'
    securityModel = 3
    mpModel = 3
    contextName = null
    # the contextEngineId/contextName values stored here should
    # be used for USM configuration only, not for PDU contents
    def __init__(self, userName,
                 authKey=None, privKey=None,
                 authProtocol=None, privProtocol=None,
                 securityEngineId=None,
                 # deprecated parameters begin
                 contextName=None,
                 contextEngineId=None,
                 # deprecated parameters end
                 securityName=None):
        self.userName = userName
        if securityName is None:
            self.securityName = userName
        else:
            self.securityName = securityName

        if authKey is not None:
            self.authKey = authKey
            if authProtocol is None:
                self.authProtocol = config.usmHMACMD5AuthProtocol
            else:
                self.authProtocol = authProtocol
            if self.securityLevel != 'authPriv':
                self.securityLevel = 'authNoPriv'

        if privKey is not None:
            self.privKey = privKey
            if self.authProtocol == config.usmNoAuthProtocol:
                raise error.PySnmpError('Privacy implies authenticity')
            self.securityLevel = 'authPriv'
            if privProtocol is None:
                self.privProtocol = config.usmDESPrivProtocol
            else:
                self.privProtocol = privProtocol

        # the contextEngineId parameter is actually a securityEngineId
        if securityEngineId is None:
            securityEngineId = contextEngineId
        self.contextEngineId = self.securityEngineId = securityEngineId

        # the contextName parameter should never be used here
        if contextName is not None:
            self.contextName = contextName

    def __hash__(self):
        raise TypeError('%s is not hashable' % self.__class__.__name__)

    def __repr__(self):
        return '%s(userName=%r, authKey=<AUTHKEY>, privKey=<PRIVKEY>, authProtocol=%r, privProtocol=%r, securityEngineId=%r, securityName=%r)'%(
            self.__class__.__name__,
            self.userName,
            self.authProtocol,
            self.privProtocol,
            self.securityEngineId is None and '<DEFAULT>' or self.securityEngineId,
            self.securityName
        )

    def clone(self, userName=None,
              authKey=None, privKey=None,
              authProtocol=None, privProtocol=None,
              securityEngineId=None, securityName=None):
        return self.__class__(
            userName is None and self.userName or userName,
            authKey is None and self.authKey or authKey,
            privKey is None and self.privKey or privKey,
            authProtocol is None and self.authProtocol or authProtocol,
            privProtocol is None and self.privProtocol or privProtocol,
            securityEngineId is None and self.securityEngineId or securityEngineId,
            securityName=securityName is None and self.securityName or securityName
        )


import uvicorn
from fastapi import FastAPI
import pickle
import numpy as np
import pandas as pd
from pydantic import BaseModel
from utils import data_dict

app = FastAPI()
pickle_in = open("models/mlp_classifier.pkl", "rb")
classifier=pickle.load(pickle_in)

data = pd.read_csv("dataset/dis_sym_dataset_comb.csv").dropna(axis=1)

diseases = list(set(data['label_dis']))
diseases.sort()

class Symptoms(BaseModel):
    symptoms: str

@app.get('/')
def index():
    return {'message': 'Hi, this is an API to predict diseases given the symptoms'}

@app.post('/predict/')
def predict_disease(symptoms: Symptoms):
    symptoms = symptoms.symptoms
    symptoms = symptoms.split(",")

    # creating input data for the models
    input_data = [0] * len(data_dict["symptom_index"])
    for symptom in symptoms:
        index = data_dict["symptom_index"][symptom.capitalize()]
        input_data[index] = 1

    # reshaping the input data and converting it
    # into suitable format for model predictions
    input_data = np.array(input_data).reshape(1,-1)

    # generating individual outputs
    model_prediction = data_dict["predictions_classes"][classifier.predict(input_data)[0]]

    predictions = {
        "final_prediction": model_prediction
    }
    return predictions

@app.post('/predict_prob/')
def predictDisease_prob(symptoms):
    symptoms = symptoms.split(",")

    input_data = [0] * len(data_dict["symptom_index"])
    for symptom in symptoms:
        index = data_dict["symptom_index"][symptom.capitalize()]
        input_data[index] = 1

    input_data = np.array(input_data).reshape(1, -1)

    prediction = classifier.predict_proba(input_data)

    k = 5

    topk = prediction[0].argsort()[-k:][::-1]
    # print(topk)
    top_diseases = {}
    for i in topk:
        print(diseases[i], prediction[0][i]*100)
        if(prediction[0][i]*100):
            top_diseases[diseases[i]] = prediction[0][i]*100

    predictions = {
        "final_prediction": top_diseases
    }
    return predictions

# 5. Run the API with uvicorn
#    Will run on http://127.0.0.1:8000
if __name__ == '__main__':
    uvicorn.run(app, host='127.0.0.1', port=8000)


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

"""
    进度条插件
"""

from PyQt5.QtWidgets import QDialog, QLabel, QProgressBar, QHBoxLayout, QPushButton,QVBoxLayout

WINDOWS_WIDTH = 350
WINDOWS_HEIGHT = 100
BAR_MAXIMUM = 100

class ProgressBar(QDialog):
    ''' 进度条窗口 '''

    def __init__(self, title, parent=None):
        super(ProgressBar, self).__init__(parent)

        self.resize(WINDOWS_WIDTH, WINDOWS_HEIGHT)
        self.setWindowTitle(self.tr(title))

        # 设置label
        self.__bar_label = QLabel(self.tr(title + ":"))
        self.__tip_label = QLabel(self.tr("Processing:"))

        # 设置进度条
        self.__progress_bar = QProgressBar(self)
        self.__progress_bar.setMinimum(0)
        self.__progress_bar.setMaximum(BAR_MAXIMUM)
        self.__progress_bar.setValue(0)

        # 设置进度条框体
        __bar_layout = QHBoxLayout()
        __bar_layout.addWidget(self.__bar_label)
        __bar_layout.addWidget(self.__progress_bar)

        # 设置tip框体
        __tip_layout = QHBoxLayout()
        __tip_layout.addWidget(self.__tip_label)

        # 设置取消按钮
        self.__cancel_button = QPushButton('Cancel', self)
        __cancel_layout = QHBoxLayout()
        __cancel_layout.addStretch(1)
        __cancel_layout.addWidget(self.__cancel_button)

        # 框架展示
        layout = QVBoxLayout()
        layout.addLayout(__bar_layout)
        layout.addLayout(__tip_layout)
        layout.addLayout(__cancel_layout)
        self.setLayout(layout)
        self.show()

        # 取消按钮响应事件
        self.__cancel_button.clicked.connect(self.cancel)

    def set_value(self, index, total):
        ''' 即时进度 '''

        # 更新进度条
        process_value = index / total * BAR_MAXIMUM
        self.__progress_bar.setValue(process_value)
        # 更新tip
        self.__tip_label.setText(self.tr("Processing:  " + str(index) + " / " + str(total)))

    def cancel(self):
        ''' 取消按钮 '''

        self.close()


from PIL import Image

import numpy as np
import random
import os
import hyperparameters

image_width, image_height = hyperparameters.image_width, hyperparameters.image_height
ann_width, ann_height = 1000, 1000

def extract_image(ori_image_path):
    ori_image = Image.open(ori_image_path)
    # image = np.array(ori_image.resize((image_width, image_height))) / 255.0
    image = np.array(ori_image.resize((image_width, image_height)))

    return image

def extract_bounding_box(annotation_path):
    c0, r0, c1, r1 = float("inf"), float("inf"), -float("inf"), -float("inf")

    with open(annotation_path) as file:
        num_table_annotations = 0

        for line in file:
            annotations = line.split()

            if len(annotations) == 10 and annotations[9] == "table":
                num_table_annotations += 1

                c0 = min(c0, float(annotations[1]))
                r0 = min(r0, float(annotations[2]))
                c1 = max(c1, float(annotations[3]))
                r1 = max(r1, float(annotations[4]))

        if num_table_annotations == 0:
            # No tables in image
            # return np.array([-1, -1, -1, -1])
            return None

        file.seek(0)

        for line in file:
            annotations = line.split()

            if len(annotations) == 10 and annotations[9] != "table":
                if float(annotations[1]) > c0 and float(annotations[2]) > r0 and float(annotations[3]) < c1 and float(annotations[4]) < r1:
                    # multi-table image
                    return None

    return np.array([
        int(c0 * image_width / ann_width),
        int(r0 * image_height / ann_height),
        int(c1 * image_width / ann_width),
        int(r1 * image_height / ann_height),
    ])

def get_data(data_dir="../data/docbank-samples", train_test_split=0.8):
    doc_root_names_half = set()
    doc_root_names_full = set()

    for file_name in os.listdir(data_dir):
        full_file_name = os.path.join(data_dir, file_name)

        if not os.path.isfile(full_file_name):
            continue

        root_name = None

        if full_file_name[-8:] == "_ori.jpg":
            root_name = full_file_name[:-8]
        elif file_name[-4:] == ".txt":
            root_name = full_file_name[:-4]

        if not root_name or root_name in doc_root_names_full:
            continue

        if root_name in doc_root_names_half:
            doc_root_names_half.remove(root_name)
            doc_root_names_full.add(root_name)
        else:
            doc_root_names_full.add(root_name)

    images, bounding_boxes = [], []

    for doc_root_name in doc_root_names_full:
        ori_image_path = doc_root_name + "_ori.jpg"

        annotation_path = doc_root_name + ".txt"
        bounding_box = extract_bounding_box(annotation_path)

        if bounding_box is None:
            continue

        image = extract_image(ori_image_path)

        insertion_index = random.randint(0, len(bounding_boxes))
        images.insert(insertion_index, image)
        bounding_boxes.insert(insertion_index, bounding_box)

    split_index = int(len(bounding_boxes) * train_test_split)

    train_images, train_bounding_boxes = np.array(images[:split_index]), np.array(bounding_boxes[:split_index])
    test_images, test_bounding_boxes = np.array(images[split_index:]), np.array(bounding_boxes[split_index:])

    return train_images, train_bounding_boxes, test_images, test_bounding_boxes


import os
from jadi import component

from aj.plugins.dashboard.api import Widget

@component(Widget)
class RandomWidget(Widget):
    id = 'random'

    # display name
    name = 'Random'

    # template of the widget
    template = '/demo_5_widget:resources/partial/widget.html'

    # template of the configuration dialog
    config_template = '/demo_5_widget:resources/partial/widget.config.html'

    def __init__(self, context):
        Widget.__init__(self, context)

    def get_value(self, config):
        if 'bytes' not in config:
            return 'Not configured'
        return os.urandom(int(config['bytes'])).encode('hex')


import logging
import numpy as np
import pandas as pd
from sklearn.base import BaseEstimator, MetaEstimatorMixin
from ._constants import _REGRET_CHECK_START_T, _REGRET_CHECK_INCREASE_T, \
    _SHRINK_REGRET, _SHRINK_ETA, _MIN_T, _RUN_LP_STEP, _PRECISION
from ._lagrangian import _Lagrangian
from archive._input_validation import _KW_SENSITIVE_FEATURES

logger = logging.getLogger(__name__)

class ExponentiatedGradient(BaseEstimator, MetaEstimatorMixin):
    """An Estimator which implements the exponentiated gradient approach to reductions.

    The exponentiated gradient algorithm is described in detail by
    `Agarwal et al. (2018) <https://arxiv.org/abs/1803.02453>`_.

    :param estimator: An estimator implementing methods :code:`fit(X, y, sample_weight)` and
        :code:`predict(X)`, where `X` is the matrix of features, `y` is the vector of labels, and
        `sample_weight` is a vector of weights; labels `y` and predictions returned by
        :code:`predict(X)` are either 0 or 1.
    :type estimator: estimator

    :param constraints: The disparity constraints expressed as moments
    :type constraints: fairlearn.reductions.Moment

    :param eps: Allowed fairness constraint violation; the solution is guaranteed to have the
        error within :code:`2*best_gap` of the best error under constraint eps; the constraint
        violation is at most :code:`2*(eps+best_gap)`
    :type eps: float

    :param T: Maximum number of iterations
    :type T: int

    :param nu: Convergence threshold for the duality gap, corresponding to a
        conservative automatic setting based on the statistical uncertainty in measuring
        classification error
    :type nu: float

    :param eta_mul: Initial setting of the learning rate
    :type eta_mul: float
    """

    def __init__(self, rand_thresh, dataset1, estimator, constraints, eps, nu, it=50, eta0=2.0):  # noqa: D103
        self._estimator = estimator
        self._constraints = constraints
        self._eps = eps
        self._nu = nu
        self._eta0 = eta0
        self._dataset1 = dataset1
        self.B = 2
        self._iterations = it

        self._best_gap = None
        self._predictors = None
        self._weights = None
        self._last_t = None
        self._best_t = None
        self._n_oracle_calls = 0
        self._n_oracle_calls_dummy_returned = 0
        self._oracle_execution_times = None
        self._lambda_vecs = pd.DataFrame()
        self._lambda_vecs_LP = pd.DataFrame()
        self._lambda_vecs_lagrangian = pd.DataFrame()

        self.randomthresholds = rand_thresh

    def fit(self, X=None, y=None, **kwargs):
        """Return a fair classifier under specified fairness constraints.

        :param X: The feature matrix
        :type X: numpy.ndarray or pandas.DataFrame

        :param y: The label vector
        :type y: numpy.ndarray, pandas.DataFrame, pandas.Series, or list
        """
        # if isinstance(self._constraints, ClassificationMoment):
        #     logger.debug("Classification problem detected")
        #     is_classification_reduction = True
        # else:
        #     logger.debug("Regression problem detected")
        #     is_classification_reduction = False

        # doesnt work because y has two columns
        # _, y_train, sensitive_features = _validate_and_reformat_input(
        #     X, y, enforce_binary_labels=is_classification_reduction, **kwargs)
        # n = y_train.shape[0]

        self.lambda_vecs_EG_ = pd.DataFrame()
        self.lambda_vecs_LP_ = pd.DataFrame()
        self.lambda_vecs_ = pd.DataFrame()

        if y is not None and X is not None:
            if _KW_SENSITIVE_FEATURES in kwargs:
                sensitive_features = kwargs[_KW_SENSITIVE_FEATURES]
            y_train = y
            #n = y_train.shape[0]
            lagrangian = _Lagrangian(self._dataset1, self._estimator,
                                     self._constraints, self._eps, self.B, X, sensitive_features, y_train)

        else:
            lagrangian = _Lagrangian(self._dataset1, self._estimator,
                                     self._constraints, self._eps, self.B)

        #B = 1 / self._eps[0]
        #(1/0.3 = 3.33, 1/0.01 = 100) / 1/0.5 = 2
        # Assumption sens_att identity functions in H: B = 2

        theta = pd.Series(0, lagrangian.constraints.index)
        pisum = pd.Series(dtype="float64")
        gaps_EG = []
        gaps = []
        pis = []

        last_regret_checked = _REGRET_CHECK_START_T
        last_gap = np.PINF
        # Todo: let 100 iterations be set
        for t in range(0, self._iterations):
            #logger.debug("...iter=%03d", t)

            # set lambdas for every constraint
            lambda_vec = self.B * np.exp(theta) / (1 + np.exp(theta).sum())
            self.lambda_vecs_EG_[t] = lambda_vec
            lambda_EG = self.lambda_vecs_EG_.mean(axis=1)

            # select classifier according to best_h method
            h, h_idx = lagrangian.best_h(lambda_vec)

            if t == 0:
                # if self._nu is None:
                #     self._nu = _ACCURACY_MUL * (h(X) - y_train).abs().std() / np.sqrt(n)
                #eta_min = self._nu / (2 * B)
                # eta is 1
                eta = self._eta0 / self.B

            if h_idx not in pisum.index:
                pisum.at[h_idx] = 0.0
            pisum[h_idx] += 1.0
            gamma = lagrangian.gammas[h_idx]
            pi_EG = pisum / pisum.sum()
            result_EG = lagrangian.eval_gap(pi_EG, lambda_EG, self._nu)
            gap_EG = result_EG.gap()
            gaps_EG.append(gap_EG)

            if t == 0 or not _RUN_LP_STEP:
                gap_LP = np.PINF
            else:
                # saddle point optimization over the convex hull of
                # classifiers returned so far
                pi_LP, self.lambda_vecs_LP_[t], result_LP = lagrangian.solve_linprog(self._nu)
                gap_LP = result_LP.gap()

            # keep values from exponentiated gradient or linear programming
            if gap_EG < gap_LP:
                pis.append(pi_EG)
                gaps.append(gap_EG)
            else:
                pis.append(pi_LP)
                gaps.append(gap_LP)

            # logger.debug("%seta=%.6f, L_low=%.3f, L=%.3f, L_high=%.3f, gap=%.6f, disp=%.3f, "
            #              "err=%.3f, gap_LP=%.6f",
            #              _INDENTATION, eta, result_EG.L_low, result_EG.L, result_EG.L_high,
            #              gap_EG, result_EG.gamma.max(), result_EG.error, gap_LP)

            if (gaps[t] < self._nu) and (t >= _MIN_T):
                # solution found
                break

            # update regret (_REGRET_CHECK_INCREASE_T = 1.6, _SHRINK_REGRET = 0.8
            # _SHRINK_ETA = 0.8)
            if t >= last_regret_checked * _REGRET_CHECK_INCREASE_T:
                best_gap = min(gaps_EG)

                if best_gap > last_gap * _SHRINK_REGRET:
                    eta *= _SHRINK_ETA
                last_regret_checked = t
                last_gap = best_gap

            # update theta based on learning rate
            theta += eta * (gamma - self._eps)

        # retain relevant result data
        gaps_series = pd.Series(gaps)
        gaps_best = gaps_series[gaps_series <= gaps_series.min() + _PRECISION]
        self._best_t = gaps_best.index[-1]
        self._best_gap = gaps[self._best_t]
        self._weights = pis[self._best_t]
        self._hs = lagrangian.hs
        for h_idx in self._hs.index:
            if h_idx not in self._weights.index:
                self._weights.at[h_idx] = 0.0

        self._last_t = len(pis) - 1
        self._predictors = lagrangian.classifiers
        self._n_oracle_calls = lagrangian.n_oracle_calls
        self._n_oracle_calls_dummy_returned = lagrangian.n_oracle_calls_dummy_returned
        self._oracle_execution_times = lagrangian.oracle_execution_times
        self.lambda_vecs_lagrangian = lagrangian.lambdas

        # logger.debug("...eps=%.3f, B=%.1f, nu=%.6f, T=%d, eta_min=%.6f",
        #              self._eps, B, self._nu, self._T, eta_min)
        # logger.debug("...last_t=%d, best_t=%d, best_gap=%.6f, n_oracle_calls=%d, n_hs=%d",
        #              self._last_t, self._best_t, self._best_gap, lagrangian.n_oracle_calls,
        #              len(lagrangian.classifiers))

    def predict(self, X):
        """Provide a prediction for the given input data.

        Note that this is non-deterministic, due to the nature of the
        exponentiated gradient algorithm.

        :param X: Feature data
        :type X: numpy.ndarray or pandas.DataFrame

        :return: The prediction. If `X` represents the data for a single example
            the result will be a scalar. Otherwise the result will be a vector
        :rtype: Scalar or vector
        """
        # print('predict X', X)
        probs = self._pmf_predict(X).astype(float)
        positive_probs = probs[:, 1]

        threshold = self.randomthresholds[X.index[0]:X.index[-1]+1]
        # threshold = np.random.random(X.shape[0])
        dec = (positive_probs >= threshold) * 1

        return dec, probs

    def _pmf_predict(self, X):

        """Probability mass function for the given input data.

        :param X: Feature data
        :type X: numpy.ndarray or pandas.DataFrame
        :return: Array of tuples with the probabilities of predicting 0 and 1.
        :rtype: pandas.DataFrame
        """

        pred = pd.DataFrame()
        # print('model._pmf_predict: self._hs', self._hs)
        # print('model._pmf_predict: X', X)
        for t in range(len(self._hs)):
            pred[t] = self._hs[t](X)
        # print('model._pmf_predict: pred', pred)
        # print('pmf_pred, self._weights', pred, self._weights)
        # print('model._pmf_predict: self._weights', self._weights)
        positive_probs = pred[self._weights.index].dot(self._weights).to_frame()
        # print('model._pmf_predict: positive_probs', positive_probs)
        return np.concatenate((1-positive_probs, positive_probs), axis=1)