from init import *
from optim.models import Models
from optim.dqn import DQN
from optim.scheduler import Scheduler

def run(env_name: str,
        model_name: str,
        hidden_size=256,
        total_timesteps=200000,
        **kwargs):
    # Prepare environment
    env = get_env(env_name)
    log.info(f'Env: {env}')

    # Initialize model
    input_shape = space_shape(env.observation_space)
    if kwargs.get('dueling_mode', False):
        # For duelling mode: adjust output_shape so that model will output a tuple of: (advantages, value)
        output_shape = (space_shape(env.action_space), 1)
    else:
        # For vanilla DQN a model outputs qvalues directly
        output_shape = space_shape(env.action_space)
    model_class = Models[model_name]
    model = model_class(input_shape=input_shape, output_shape=output_shape, hidden_size=hidden_size, norm=False)
    log.info(f'Model: {model}')

    # Initialize optimizer
    autosave_prefix = f'dqn_{model_name.lower()}_{env_name.rsplit("-", 1)[0].lower()}'
    trainer = DQN(
        env=env,
        model=model,
        step_delay=0.015,
        autosave_dir=WORK_DIR,
        autosave_prefix=autosave_prefix,
        autosave_interval=timedelta(minutes=1),
        log=log,
        **kwargs
    )
    log.info(f'Trainer: {trainer}')

    trainer.fit(total_timesteps=total_timesteps, render=True)
    trainer.autosave(force=True)

def test(env_name: str, model_name: str, hidden_size=256, **kwargs):
    # Prepare environment
    env = get_env(env_name)
    log.info(f'Env: {env}')

    # Initialize model
    input_shape = space_shape(env.observation_space)
    if kwargs.get('dueling_mode', False):
        # For duelling mode: adjust output_shape so that model will output a tuple of: (advantages, value)
        output_shape = (space_shape(env.action_space), 1)
    else:
        # For vanilla DQN a model outputs qvalues directly
        output_shape = space_shape(env.action_space)
    model_class = Models[model_name]
    model = model_class(input_shape=input_shape, output_shape=output_shape, hidden_size=hidden_size, norm=False)
    log.info(f'Model: {model}')

    # Load model
    autosave_prefix = f'dqn_{model_name.lower()}_{env_name.rsplit("-", 1)[0].lower()}'
    model_file_name = os.path.join(WORK_DIR, autosave_prefix + '.model.pt')
    model.load_state_dict(th.load(model_file_name), strict=True)

    state = env.reset()
    while True:
        action = model(state)
        action = action.argmax(dim=-1).squeeze().item()
        state, reward, done, info = env.step(action)
        env.render()
        if done:
            state = env.reset()

if __name__ == '__main__':
    # run(env_name='CartPole-v0', model_name='fc2')
    # run(env_name='Acrobot-v1', model_name='fc2', entropy_factor=1.0)
    # run(env_name='BreakoutDeterministic-v4', model_name='convfc1', hidden_size=128)
    run(
        env_name='LunarLander-v2',
        model_name='fc2',
        double_mode=True,
        dueling_mode=False,
        learning_rate=Scheduler((5e-4, 1e-7), 's'),
        gamma=0.99,
        batch_size=128,
        total_timesteps=150000,
        anneal_period=int(100000 * 0.12),
        prioritized_replay=True,
        replay_buffer_capacity=50000,
        samples_to_start=10000,
        samples_per_iteration=4,
        updates_per_iteration=4,
        target_update_period=250
    )
    test(env_name='LunarLander-v2', model_name='fc2')


#! python3
# gff3_to_fasta.py
# This program reads a genome fasta file and corresponding gff3 file in a format
# output by PASA and retrieves the main and/or alternative isoform transcripts
# from each locus

import os, argparse, sys
from Bio import SeqIO

sys.path.append(os.path.dirname(os.path.dirname(__file__))) # 2 dirs up is where we find dependencies
from Various_scripts.Function_packages import ZS_GFF3IO

# Define functions for later use
def validate_args(args):
        # Validate input file locations
        if not os.path.isfile(args.fasta):
                print('I am unable to locate the genome fasta file (' + args.fasta + ')')
                print('Make sure you\'ve typed the file name or location correctly and try again.')
                quit()
        if not os.path.isfile(args.gff3):
                print('I am unable to locate the input gff3 gene annotation file (' + args.gff3 + ')')
                print('Make sure you\'ve typed the file name or location correctly and try again.')
                quit()
        # Validate behaviour arguments
        if args.geneIDs == True and args.locusSeqs == "isoforms":
            print('--gene_ids is only relevant to specify if you are outputting main sequences, not isoforms.')
            quit()
        # Ensure that translationTable value is sensible
        if args.translationTable < 1:
                print('translationTable value must be greater than 1. Fix this and try again.')
                quit()
        elif args.translationTable > 31:
                print('translationTable value must be less than 31. Fix this and try again.')
                quit()
        # Format output names
        mainOutputFileName = None
        nuclOutputFileName = None
        protOutputFileName = None
        if args.seqType == 'cds' or args.seqType == 'both':
                nuclOutputFileName = args.outputPrefix + '.nucl'
                protOutputFileName = args.outputPrefix + '.aa'
        if args.seqType == 'transcript' or args.seqType == 'both':
                mainOutputFileName = args.outputPrefix + '.trans'
        # Handle file overwrites
        if args.seqType == 'transcript' or args.seqType == 'both':
                if os.path.isfile(mainOutputFileName) and args.force != True:
                        print('There is already a file named ' + mainOutputFileName + '. Either specify a new file name, delete these older file(s), or provide the -force argument either "Y" or "y"')
                        quit()
                elif os.path.isfile(mainOutputFileName) and args.force == True:
                        os.remove(mainOutputFileName)
        if args.seqType == 'cds' or args.seqType == 'both':
                # Nucl
                if os.path.isfile(nuclOutputFileName) and args.force != True:
                        print('There is already a file named ' + nuclOutputFileName + '. Either specify a new file name, delete these older file(s), or provide the -force argument either "Y" or "y"')
                        quit()
                elif os.path.isfile(nuclOutputFileName) and args.force == True:
                        os.remove(nuclOutputFileName)
                # Prot
                if os.path.isfile(protOutputFileName) and args.force != True:
                        print('There is already a file named ' + protOutputFileName + '. Either specify a new file name, delete these older file(s), or provide the -force argument either "Y" or "y"')
                        quit()
                elif os.path.isfile(protOutputFileName) and args.force == True:
                        os.remove(protOutputFileName)
        # Return file names
        return mainOutputFileName, nuclOutputFileName, protOutputFileName

def longest_iso(mrnaFeatures):
    '''
    We pick out the representative gene based on length. If length is identical,
    we'll end up picking the entry listed first in the gff3 file since our > condition
    won't be met. I doubt this will happen much or at all though.
    '''
    longestMrna = [None, 0]
    for feature in mrnaFeatures:
        mrnaLen = 0

        if hasattr(feature, "CDS"):
            featType = "CDS"
        elif hasattr(feature, "exon"):
            featType = "exon"
        else:
            continue # no CDS or exon means this feature cannot be used

        for subFeature in feature.__dict__[featType]:

            mrnaLen += (subFeature.end - subFeature.start + 1)

        if mrnaLen > longestMrna[1]:
            longestMrna = [feature, mrnaLen]

    mrnaList = [longestMrna[0]]
    return mrnaList

# Hacky code to allow with->open statements to be compacted [based on https://stackoverflow.com/questions/22226708/can-a-with-statement-be-used-conditionally]
class Dummysink(object):
        def write(self, data):
                pass # ignore the data
        def __enter__(self): return self
        def __exit__(*x): pass

def datasink(filename, thisSeqType, argSeqType):
        if argSeqType == 'both':
                return open(filename, "w")
        elif argSeqType == 'transcript' and thisSeqType == 'transcript':
                return open(filename, "w")
        elif argSeqType == 'cds' and thisSeqType == 'cds':
                return open(filename, "w")
        else:
                return Dummysink()

def main():
    ##### USER INPUT SECTION
    usage = """%(prog)s reads in genome fasta file and corresponding GFF3 file and retrieves
    the main and/or alternative isoform transcripts and/or nucleotide CDS and translated amino acid
    sequences for each locus. Alternatively, you can grab the CDS regions which will produce nucleotide
    and AA files (name format == OUTPUT.nucl / OUTPUT.aa). This function will only output mRNA
    sequences from features annotated as "gene" in the GFF3.
    """
    # Required
    p = argparse.ArgumentParser(description=usage)
    p.add_argument("-i", "-input", dest="fasta",
                   required=True,
                   help="Genome fasta file")
    p.add_argument("-g", "-gff", dest="gff3",
                   required=True,
                   help="GFF3 file")
    p.add_argument("-l", "-locusSeqs", dest="locusSeqs",
                   required=True,
                   choices = ['main', 'isoforms'],
                   help="Type of transcripts to extract from each locus (main == just the longest isoform of each gene, isoforms == all isoforms)")
    p.add_argument("-s", "-seqType", dest="seqType",
                   required=True,
                   choices = ['transcript', 'cds', 'both'],
                   help="""Type of sequence to output (transcripts == exon regions,
                   cds == coding regions)""")
    p.add_argument("-o", "-output", dest="outputPrefix",
                   required=True,
                   help="""Output prefix for fasta files (suffixes will be appended to this;
                   transcript suffix == .fasta, nucleotide cds == .nucl, amino acid cds == .aa)""")
    # Optional
    p.add_argument("-t", "-translation", dest="translationTable",
                   required=False,
                   type=int,
                   help="""Optionally specify the NCBI numeric genetic code to utilise for CDS
                   translation (if relevant); this should be an integer from 1 to 31
                   (default == 1 i.e., Standard Code)""", default=1)
    p.add_argument("-f", "-force", dest="force",
                   required=False,
                   action='store_true',
                   help="""By default this program will not overwrite existing files.
                   Specify this argument to allow this behaviour at your own risk.""",
                   default=False)
    p.add_argument("--relaxed", dest="relaxedParsing",
                   required=False,
                   action='store_true',
                   help="""Optionally specify whether we should use relaxed GFF3 parsing.""",
                   default=False)
    p.add_argument("--gene_ids", dest="geneIDs",
                   required=False,
                   action='store_true',
                   help="""Optionally, if you're outputting main sequences only, specify this flag
                   to write the representative sequence using the gene ID rather than the best
                   mRNA ID.""",
                   default=False)
    p.add_argument("--non_mrna", dest="nonMrnas",
                   required=False,
                   action='store_true',
                   help="""Optionally, choose to output not just mRNAs / genes with mRNA features,
                   but every sequence with an exon.""",
                   default=False)

    args = p.parse_args()
    mainOutputFileName, nuclOutputFileName, protOutputFileName = validate_args(args)

    # Load the fasta file and parse its contents
    genomeRecords = SeqIO.to_dict(SeqIO.parse(args.fasta, 'fasta'))

    # Parse the gff3 file
    GFF3_obj = ZS_GFF3IO.LinesGFF3(args.gff3, not args.relaxedParsing) # negate it for strict_parsing
    GFF3_obj.add_comments()
    GFF3_obj.pasaprots_extract()

    # Produce output files
    with datasink(mainOutputFileName, 'transcript', args.seqType) as mainOut, datasink(nuclOutputFileName, 'cds', args.seqType) as nuclOut, datasink(protOutputFileName, 'cds', args.seqType) as protOut:
        for geneFeature in GFF3_obj.types["gene"]:

            # Figure out if we'll accept this gene feature for consideration
            if hasattr(geneFeature, "mRNA"):
                mrnaFeatures = geneFeature.mRNA
            elif args.nonMrnas == False:
                continue
            else:
                # Figure out what our subfeature child is
                if not hasattr(geneFeature, "exon"):
                    mrnaFeatures = geneFeature.children
                else: # if this occurs, this gene feature IS the subfeature
                    mrnaFeatures = [geneFeature] # it's a sign of bad GFF3 formatting but there's a lot of crap GFF3s out there

            # Reduce our mrnas to only the representative entry if relevant
            """
            (representative == longest; note that this is with relation to CDS
            not TRANSCRIPT length since this maximises BUSCO score)
            """
            if args.locusSeqs == 'main':
                mrnaFeatures = longest_iso(mrnaFeatures)

                # If we failed to find an mRNA feature with CDS and exon attributes, we need to skip this feature
                if mrnaFeatures == None:
                    continue

            # Loop through mRNAs and produce relevant outputs
            for feature in mrnaFeatures:
                # Get nucleotide sequence(s)
                if args.seqType == "both" or args.seqType == "transcript":
                    if hasattr(feature, "exon"):
                        exon_FastASeq_obj, exon_featureType, exon_startingFrame = GFF3_obj.retrieve_sequence_from_FASTA(genomeRecords, feature.ID, "exon")
                    else: # a feature without even exon values cannot give us anything useful
                        continue # if it did have CDS and not exon values, then its formatted incredibly poorly and we'll end up missing it...

                if args.seqType == "both" or args.seqType == "cds":
                    if hasattr(feature, "CDS"):
                        cds_FastASeq_obj, cds_featureType, cds_startingFrame = GFF3_obj.retrieve_sequence_from_FASTA(genomeRecords, feature.ID, "CDS")
                    else:
                        cds_FastASeq_obj = None # if feature has no CDS attributes, it's not relevant for CDS output

                # Retrieve protein sequence if relevant
                if (args.seqType == 'cds' or args.seqType == 'both') and cds_FastASeq_obj != None: # feature needs CDS to have a protein associated with it
                    if feature.ID in GFF3_obj.pasa_prots:
                        prot = GFF3_obj.pasa_prots[feature.ID]
                    else:
                        try:
                            cds_startingFrame = int(cds_startingFrame)
                        except:
                            cds_startingFrame = 0
                        prot, _, _ = cds_FastASeq_obj.get_translation(strand=1, frame=cds_startingFrame) # _, _ == strand, frame

                # Output relevant values to file
                if args.geneIDs == True: # geneIDs being True necessitates that locusSeqs also == 'main'; enforced in validate_args()
                    seqID = geneFeature.ID
                else:
                    seqID = feature.ID

                if args.seqType == 'both' or args.seqType == 'transcript':
                    mainOut.write(">{0}\n{1}\n".format(seqID, exon_FastASeq_obj.seq))
                if (args.seqType == 'both' or args.seqType == 'cds') and cds_FastASeq_obj != None: # as above, if we have no CDS attributes, we can't do this
                    nuclOut.write(">{0}\n{1}\n".format(seqID, cds_FastASeq_obj.seq))
                    protOut.write(">{0}\n{1}\n".format(seqID, prot))

    # Done!
    print('Program completed successfully!')

if __name__ == "__main__":
    main()


# cook your dish here
import numpy as np

def compli(b):
    #function that computes bitwise not
    b=b[2:]
    compliment=""
    for c in b:
        if(c=='0'):
            compliment=compliment+"1"
        else:
            compliment=compliment+"0"

    return(compliment)

temp=[int(x) for x in input().strip().split()]
n=temp[0]
q=temp[1]
values=[int(x) for x in input().strip().split()]
compliments=[]
for i in values:
    compliments.append(compli(bin(i)))

common_length=len(max(compliments,key=len))
compliments2=[] #making sure all are of the same length of common_length

for c in compliments:
    to_add='1'*(common_length-len(c))
    c=to_add+c
    compliments2.append(c)

compliments2=[list(x) for x in compliments2]
compliments2=np.array(compliments2).astype(int).tolist()
prefixsum=np.cumsum(compliments2,axis=0)

while(q!=0):
    q=q-1
    temp=[int(x) for x in input().strip().split()]
    start=temp[0]
    end=temp[1]
    answer=""
    length=(end-start)+1
    sum_bits=[]
    decider=(length+1)//2
    if(start==1):
      L=[0]*common_length
      R=prefixsum[end-1]
    else:
      L=prefixsum[start-2]
      R=prefixsum[end-1]
    sum_bits=(R-L).tolist()

    for b in sum_bits:
        if(length%2==0):
            if(b<=decider):
                answer=answer+'0'
            else:
                answer=answer+'1'
        else:
            if(b<decider):
                answer=answer+'0'
            else:
                answer=answer+'1'
    answer='1'*(31-len(answer))+answer
    print(int(answer,2))


# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")

def solution(S):
    sum = 0
    parts = S.split(',')
    for part in parts:
        if part[0]=='0':
            continue
        elif part[0]=='-':
            sum-=int(part[1:])
        elif part[0]=='+':
            sum+=int(part[1:])
    # write your code in Python
    return sum


class Count_x:
    def __init__(self):
        self.myList=[]
        self.myCount=0
def count_and_places(listA,lenA,itemA):
    ind=[]
    count=0
    for x in range(lenA):
        if listA[x]==itemA:
            count+=1
            ind.append(x)
    ret=Count_x()
    ret.myList=ind
    ret.myCount=count
    return ret

if __name__=='__main__':
    n=int(input())
    l=list()
    g=list()
    h=list()

    for i in range(n):
        newWord=input()
        l.append(newWord)

    for i in range(len(l)):
        g.append(count_and_places(l,len(l),l[i]).myCount)
        h.append(count_and_places(l,len(l),l[i]).myList)

    y=0
    while y<len(g):
        if len(h[y])>1:
            z=0
            lenHy=len(h[y])
            while z+1<lenHy:
                g.pop(h[y][z+1]-z-y)
                h.pop(h[y][z+1]-z-y)
                z+=1
        y+=1
    #Sometimes outputs a wrong answer
    print(g)


# -*- coding: utf-8 -*-
"""
Python script to test AL on binary activity coefficient data by computing
VLE phase diagrams.

Sections:
    . Imports
    . Configuration
    . Ground Truth VLE
    . Active Learning VLE
    . Publication Plots

Last edit: 2022-10-27
Author: Dinis Abranches
"""

# =============================================================================
# Imports
# =============================================================================

# Specific
import numpy
from matplotlib import pyplot as plt

# Local
from lib import thermoAux as thermo
from lib import mlAux as ml

# =============================================================================
# Configuration
# =============================================================================

# System definition
components=['Acetone','Cyclohexane']

# GP Configuration
gpConfig={'kernel':'RQ',
          'useWhiteKernel':False,
          'doLogY':True,
          'indepDim':False,
          'trainLikelihood':False
          }

# VLE Pressure
P=101325

# =============================================================================
# Ground Truth VLE
# =============================================================================

# Get NRTL parameters
parameters=thermo.NRTL_Parameters(components[0],components[1])
# Define gamma functions
def F_Gamma_1_NRTL(x1,T):
    gammas=thermo.NRTL_Binary_getGamma(parameters,x1,T)
    return gammas[0]
def F_Gamma_2_NRTL(x1,T):
    gammas=thermo.NRTL_Binary_getGamma(parameters,x1,T)
    return gammas[1]
Fs_gamma_NRTL=[F_Gamma_1_NRTL,F_Gamma_2_NRTL]
# Get Antoine parameters
antoine1=thermo.antoineParameters(components[0])
antoine2=thermo.antoineParameters(components[1])
# Define Vapor Pressure Functions
def F_VP_1(T):
    P=thermo.antoineEquation(antoine1,T,getVar='P')
    return P
def F_VP_2(T):
    P=thermo.antoineEquation(antoine2,T,getVar='P')
    return P
def F_Inverse_VP_1(P):
    T=thermo.antoineEquation(antoine1,P,getVar='T')
    return T
def F_Inverse_VP_2(P):
    T=thermo.antoineEquation(antoine2,P,getVar='T')
    return T
Fs_VP=[F_VP_1,F_VP_2]
Fs_Inverse_VP=[F_Inverse_VP_1,F_Inverse_VP_2]
# Compute VLE
bubble_NRTL,dew_NRTL,gammas_NRTL=thermo.compute_Tx_VLE_Binary(Fs_gamma_NRTL,
                                              Fs_VP,
                                              Fs_Inverse_VP,
                                              P,
                                              z1_range=numpy.linspace(0,1,101),
                                              do_Bubble_Only=True)

# =============================================================================
# Active Learning VLE
# =============================================================================

# Testing Set Grid
x1_range=numpy.linspace(0,1,101)
# Perform AL
bubble_gp,dew_gp,gamma_gp,MAF_Vector,X_AL \
    =ml.AL_VLE_Binary_Type1(F_Gamma_1_NRTL,F_Gamma_2_NRTL,gpConfig,P,Fs_VP,
                            Fs_Inverse_VP,x1_range,maxIter=100,min_AF=0.01,
                            bubbleTruth=bubble_NRTL,dewTruth=dew_NRTL,
                            plot_VLE_GIF=r'C:\Users\dinis\Desktop\testes\vle.gif',
                            title=None)

# =============================================================================
# Pulbication Plots
# =============================================================================

# Plot Configuration
plt.rcParams['figure.dpi'] = 600
plt.rcParams['text.usetex'] = False
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = 'Times New Roman'
plt.rcParams['font.weight'] = 'bold'
plt.rcParams['font.size'] = 8
plt.rcParams['figure.titlesize'] = 8
plt.rcParams['figure.titleweight'] = 'bold'
plt.rcParams['axes.titlesize'] = 8
plt.rcParams['axes.titleweight'] = 'bold'
plt.rcParams['axes.labelsize'] = 8
plt.rcParams['axes.labelweight'] = 'bold'
plt.rcParams['xtick.labelsize'] = 7
plt.rcParams['ytick.labelsize'] = 7
plt.rcParams['mathtext.rm'] = 'serif'
plt.rcParams['mathtext.it'] = 'serif:italic'
plt.rcParams['mathtext.bf'] = 'serif:bold'
plt.rcParams['mathtext.fontset'] = 'custom'
plt.rcParams["savefig.pad_inches"] = 0.02
plt.rcParams['savefig.dpi'] = 600
# Create figure
plt.figure(figsize=(3,1.7))
# Plots
plt.plot(bubble_NRTL[:,0],bubble_NRTL[:,1],'-k',linewidth=1,
         label='Ground Truth')
plt.plot(dew_NRTL[:,0],dew_NRTL[:,1],'-k',linewidth=1)
plt.plot(bubble_gp[:,0],bubble_gp[:,1],'--r',linewidth=1,
         label='GP-Predicted')
plt.plot(dew_gp[:,0],dew_gp[:,1],'--r',linewidth=1)
plt.plot(X_AL[:,0],X_AL[:,1],'ob',markersize=2,label='AL Training Data')
plt.xlabel('$\mathregular{z_{'+components[0]+'}}$')
plt.ylabel('T /K',fontsize = 7)
# plt.text(0.18,0.05,'VLE (P = '+str(int(P/101325))+' atm)',
#          color='black',
#          horizontalalignment='center',
#          verticalalignment='center',
#          transform=plt.gca().transAxes)
plt.text(0.02,0.05,components[0]+'/'+components[1],
         color='black',
         horizontalalignment='left',
         verticalalignment='center',
         transform=plt.gca().transAxes)
plt.legend(prop={'size': 6})


import pygame
import numpy
import cv2

import math
import time
import os
import errno

class Video:
    """A video playback utility for pygame.

    Requires:
        pygame  (pip install pygame)
        numpy   (pip install numpy)
        cv2     (pip install opencv-python)

    This class streams the image data from a video file and provides it as a pygame Surface. There are methods that
    control video playback, such as play, pause, and set_frame, as well as methods that provide information about the
    video itself, like the dimensions and the FPS.

    The video playback tries to play in "real time", meaning that if you call play, and then call get_surface 5 seconds
    later, you'll get the video frame at the 5 second mark.

    However, this class is also lazy, meaning that video data is only processed when get_surface is called. There is
    no asynchronous background processing, and it doesn't cache any video data in memory besides the current frame.
    You don't need to advance frames manually or update the video each frame to keep it "going".

    This class does not provide sound from video files, only the images.

    Example Usage:

        import pygame
        import video

        pygame.init()

        screen = pygame.display.set_mode((1080, 720))
        clock = pygame.time.Clock()

        vid = video.Video("your_file_goes_here.mp4")
        vid.play()

        while True:
            for e in pygame.event.get():
                if e.type == pygame.QUIT:
                    raise SystemExit
            screen.fill((0, 0, 0))
            screen.blit(vid.get_surface(), (0, 0))

            pygame.display.flip()
            clock.tick(60)
    """

    class _PlaybackState:
        def __init__(self, start_frame, playing, t):
            self.frame = start_frame
            self.playing = playing
            self.t = t

    def __init__(self, filename, fps=0):
        """Inits a new Video.

        The video will be paused initially.

        filename: The path to the video file.
        fps: The playback framerate for the video. If 0, the native FPS will be used.
        """
        if not os.path.isfile(filename):
            raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), filename)

        self._filename = filename
        self._vid = cv2.VideoCapture(filename)
        self._vid_frame = 0  # the frame the next _vid.read() call will give.

        self._frame_count = int(self._vid.get(cv2.CAP_PROP_FRAME_COUNT))
        self._frame_width = int(self._vid.get(cv2.CAP_PROP_FRAME_WIDTH))
        self._frame_height = int(self._vid.get(cv2.CAP_PROP_FRAME_HEIGHT))
        self._fps = int(self._vid.get(cv2.CAP_PROP_FPS)) if fps <= 0 else fps

        self._buf = pygame.Surface((self._frame_width, self._frame_height))
        self._cur_frame = -1  # the frame that was last drawn to _buf

        self._playback_state = Video._PlaybackState(0, False, time.time())
        self._final_frame = float('inf')

    def __repr__(self):
        return f"{type(self).__name__}({self._filename})"

    def play(self, loops=0, maxtime=0):
        """Begins video playback.

        loops: How many times playback should loop. If 0, it will repeat forever.
        maxtime: How long in seconds the video should play. If 0, it will play forever.
        """
        if self.is_paused():
            self._playback_state.playing = True
            self._playback_state.t = time.time()
        self.frame = self._playback_state.frame % self.get_frame_count()  # go back to first loop
        self._final_frame = self._calc_final_frame(loops, maxtime)

    def set_frame(self, n):
        """Jumps to a specific frame."""
        self._playback_state.frame = n
        self._playback_state.t = time.time()

    def pause(self):
        """Pauses the video."""
        if not self.is_paused():
            self._playback_state.frame = self.get_current_frame(wrapped=False)
            self._playback_state.playing = False

    def is_paused(self):
        """Whether the video is paused.

        Note that if a video has finished (e.g. finished looping), it will still be considered unpaused.
        """
        return not self._playback_state.playing

    def is_finished(self) -> bool:
        """Whether the termination condition passed into play has been reached."""
        return self.get_current_frame() >= self._final_frame

    def get_surface(self) -> pygame.Surface:
        """Returns the video's image data for the current frame.

        This is where the bulk of this class's work is performed. This method calculates the current frame (based on the
        current time and other factors), and if the frame has changed since the last call to this method, it reads
        video data from the file and blits it onto a surface, which is returned.

        If the buffer surface is already up-to-date, this method returns it instantly.
        If the video has ended, (i.e. the termination condition passed into play() has been reached), a blank surface is returned.
        """
        cur_frame = self.get_current_frame(wrapped=False)
        if cur_frame >= self._final_frame:
            self._buf.fill((0, 0, 0))  # video is over, you get a black screen
            return self._buf
        else:
            self._draw_frame_to_surface_if_necessary(cur_frame)
            return self._buf

    def _draw_frame_to_surface_if_necessary(self, frame_n):
        frame_n %= self._frame_count
        if self._cur_frame == frame_n:
            return  # this frame is already drawn

        if self._vid_frame > frame_n:
            # we have to loop back to the beginning
            self._vid_frame = 0
            self._vid = cv2.VideoCapture(self._filename)

        success, frame_data = None, None
        for _ in range(frame_n - self._vid_frame + 1):
            success, next_frame_data = self._vid.read()
            if not success:
                # sometimes CAP_PROP_FRAME_COUNT will be straight-up wrong, indicating more or less frames
                # than there actually are. In that case we just... skip or freeze the final frames, I guess?
                continue
            else:
                frame_data = next_frame_data
                self._vid_frame += 1

        if frame_data is not None:
            pygame.surfarray.blit_array(self._buf, numpy.flip(numpy.rot90(frame_data[::-1])))
        self._cur_frame = self._vid_frame - 1

    def get_width(self) -> int:
        """The width of the video in pixels."""
        return self._frame_width

    def get_height(self) -> int:
        """The height of the video in pixels."""
        return self._frame_height

    def get_size(self) -> (int, int):
        """The dimensions of the video in pixels."""
        return self.get_width(), self.get_height()

    def get_current_frame(self, wrapped=True) -> int:
        """The current frame number.

        wrapped: if True, the result will be less than frame_count.
                 if False, the result may be greater or equal to frame_count, indicating the video has looped.
        """
        if self.is_paused():
            return self._playback_state.frame
        else:
            cur_time = time.time()
            start_time = self._playback_state.t
            elapsed_frames = int(self.get_fps() * (cur_time - start_time))
            cur_frame = self._playback_state.frame + elapsed_frames

            return cur_frame % self._frame_count if wrapped else cur_frame

    def get_fps(self) -> int:
        """The frames per second at which the video will play."""
        return self._fps

    def get_frame_count(self) -> int:
        """The number of frames in the video."""
        return self._frame_count

    def get_duration(self) -> float:
        """The duration of the video in seconds."""
        return self._frame_count / self._fps

    def _calc_final_frame(self, loops, maxtime):
        res = float('inf')
        if loops > 0:
            res = min(res, loops * self.get_frame_count())
        if maxtime > 0:
            res = min(res, math.ceil(self.get_fps() * maxtime))
        return res


from flask import Flask, request
from flask_restful import Resource, Api, reqparse
import time

from sudoku import solve
from utils import values2grid, check_sudoku_input

app = Flask(__name__)
app.config['PROPAGATE_EXCEPTIONS'] = True # To allow flask propagating exception even if debug is set to false on app
api = Api(app)

class Sudoku(Resource):
    parser = reqparse.RequestParser()
    parser.add_argument('sudoku',
        type=str,
        required=True,
        help="This field cannot be left blank!"
    )

    def get(self, sudoku):
        (ok, message) = check_sudoku_input(sudoku)
        if not ok:
            return {'message': message}, 400
        start = time.clock()
        result = solve(sudoku)
        t = time.clock()-start
        return {'solution': values2grid(result), 'time': t}

api.add_resource(Sudoku, '/sudoku/<string:sudoku>')

if __name__ == '__main__':
    app.run(debug=True)  # important to mention debug=True


from Bio import SeqIO, SeqFeature
from Bio.Seq import Seq
from Bio.SeqRecord import SeqRecord
from Bio.Alphabet import IUPAC
from Bio.SeqUtils import nt_search
import csv
import sys

# note that promoter positions resulting from this program are positions in pythonic indexing

def search_for_promoters(promoter_list, promoter_type, window_start, window_end, ref_seq, strand):
    unique_search_results = set()
    if strand == 'F':
        seq_to_search = ref_seq[window_start:window_end]
    elif strand == 'R':
        seq_to_search = ref_seq[window_start:window_end].reverse_complement()
    else: print('strand error')
    for promoter in promoter_list:
        search_results = nt_search(str(seq_to_search), promoter)
        num_promoters_found = len(search_results) - 1
        if num_promoters_found > 0:
            for pos in search_results[1:]:
                if strand == 'F':
                    promoter_pos = window_start + pos
                    if promoter_type == -10:
                        promoter_seq = str(ref_seq[(promoter_pos - 3):(promoter_pos + 6)])
                    elif promoter_type == -35:
                        promoter_seq = str(ref_seq[promoter_pos:(promoter_pos + 6)])
                elif strand == 'R':
# Need to subtract one because window end is not the last position of the promoter, but rather the position after that (end is not inclusive)
                    promoter_pos = window_end - 1 - pos
                    if promoter_type == -10:
                        promoter_seq = str(ref_seq[(promoter_pos - 6):(promoter_pos + 3)].reverse_complement())
                    elif promoter_type == -35:
                        promoter_seq = str(ref_seq[(promoter_pos - 6):promoter_pos].reverse_complement())
                else: print('strand error')
                unique_search_results.add((promoter_pos, promoter_seq))
    return sorted(unique_search_results)

def record_thirtyfive_ten_promoters(ref_seq, strand, min_len_gap, max_len_gap):
    # Promoter sequences to look for:
    ### In -10 promoters: A2 and T6 always conserved plus 2 out of 4 variable sites (total of 4/6).
    ### In -35 promoters: T1 and T2 always conserved plus 2 out of 4 variable sites (total of 4/6).
    ten_promoters = ['TATNNT', 'TANANT', 'TANNAT', 'NATANT', 'NATNAT', 'NANAAT']
    thirtyfive_promoters = ['TTGANN', 'TTGNCN', 'TTGNNA', 'TTNACN', 'TTNANA', 'TTNNCA']

    full_results = []
    # Since searching the whole genome for -10 promoters, start of window = 0 and end of window = length of genome.
    ten_promoter_results = search_for_promoters(ten_promoters, -10, 0, len(ref_seq), ref_seq, strand)
    if len(ten_promoter_results) > 0:
        for promoter_record in ten_promoter_results:
            ten_promoter_pos = promoter_record[0]
            ten_promoter_seq = promoter_record[1]
            if strand == 'F':
                thirtyfive_win_start = ten_promoter_pos - (max_len_gap + 6)
                thirtyfive_win_end = ten_promoter_pos - min_len_gap
            elif strand == 'R':
                thirtyfive_win_start = ten_promoter_pos + min_len_gap
                thirtyfive_win_end = ten_promoter_pos + (max_len_gap + 6)
            else: print('strand error')
            thirtyfive_promoter_results = search_for_promoters(thirtyfive_promoters, -35, thirtyfive_win_start, thirtyfive_win_end, ref_seq, strand)
            if len(thirtyfive_promoter_results) > 0:
                if ten_promoter_seq.startswith('TG'):
                    full_results.append((ten_promoter_pos, ten_promoter_seq, 'extended', thirtyfive_promoter_results))
                else:
                    full_results.append((ten_promoter_pos, ten_promoter_seq, ' ', thirtyfive_promoter_results))
            else:
                if ten_promoter_seq.startswith('TG'):
                    full_results.append((ten_promoter_pos, ten_promoter_seq, 'extended'))
                else:
                    full_results.append((ten_promoter_pos, ten_promoter_seq, ' '))
    return (full_results)

def find_35_10_promoters(gb_path, outpath):
    ref_record = SeqIO.read(open(gb_path), 'genbank')
    ref_sequence = ref_record.seq
    print('reference length: ', len(ref_sequence))
    # Where to search for -35 promoters relative to -10 promoters
    min_len_gap = 17
    max_len_gap = 21

    with open(outpath, 'w') as outfile:
        writer = csv.writer(outfile, delimiter = '\t')
        # Find and record promoters on the forward strand:
        forward_results = record_thirtyfive_ten_promoters(ref_sequence, 'F', min_len_gap, max_len_gap)
        if len(forward_results) > 0:
            for entry in forward_results:
                writer.writerow(['F', entry])
        else: print('no promoters found on forward strand')
        # Find and record promoters on the reverse strand:
        reverse_results = record_thirtyfive_ten_promoters(ref_sequence, 'R', min_len_gap, max_len_gap)
        if len(reverse_results) > 0:
            for entry in reverse_results:
                writer.writerow(['R', entry])
        else: print('no promoters found on forward strand')

if __name__ == '__main__':
    if len(sys.argv) == 3:
         find_35_10_promoters(sys.argv[1], sys.argv[2])
    else:
         print("Usage: full_genome_promoters.py reference_genbank.gb outfile.csv")
         sys.exit(0)


class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        '''
        # Divide and Conquer: T(n) = 2T(n/2) + 2O(n) => O(nlogn)
        def majorityCheck(lo, hi):
            if lo == hi:
                return nums[lo]

            mid = (lo + hi) // 2
            left_majority = majorityCheck(lo, mid)
            right_majority = majorityCheck(mid+1, hi)

            if left_majority == right_majority:
                return left_majority
            else:
                left_count, right_count = 0, 0
                for elem in nums[lo:mid+1]:
                    if elem == left_majority:
                        left_count += 1
                for elem in nums[mid+1:hi+1]:
                    if elem == right_majority:
                        right_count += 1
                if right_count == left_count:
                    return right_majority
                return right_majority if right_count > left_count else left_majority

        # return majorityCheck(0, len(nums) - 1)
        '''
        count = 0
        candidate = None
        for elem in nums:
            if count == 0:
                candidate = elem
                count += 1
            elif candidate == elem:
                count += 1
            else:
                count -= 1
        return candidate


#!/usr/bin/env python
""" Customizing and existing model """

import numpy as np
import matplotlib.pyplot as plt
# %matplotlib inline
# Imagenet!
# from tensorflow.keras.applications import VGG19
import tensorflow as tf
from tensorflow.keras.models import load_model
from tensorflow.keras.models import Model
import IPython.display as display
from PIL import Image
from tensorflow.keras.applications.vgg19 import preprocess_input
from tensorflow.keras.preprocessing import image

# Load the model
vgg_model = load_model('/HDD/Data/models/VGG19.h5')

# Get the input layers and display the summary
vgg_input = vgg_model.input
vgg_layers = vgg_model.layers
vgg_model.summary()

# Build the model to access the layer outputs
layer_outputs = [layer.output for layer in vgg_layers]
features = Model(
        inputs=vgg_input,
        outputs=layer_outputs)

# Plot the model
tf.keras.utils.plot_model(
        features,
        'vgg19_model.png',
        show_shapes=True)

# Noise image
noise_img = np.random.random((1, 224, 224, 3)).astype('float32')
extracted_features = features(noise_img)

# Display the original image
img_path = 'cool_cat.jpg'
display.display(Image.open(img_path))

# Preoprocess the image
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)

# Extract the features
extracted_features = features(x)

# Visualize the input channels
fl = extracted_features[0]
print('\n fl.shape:', fl.shape)

imgs = fl[0, :, :]
plt.figure(figsize=(15, 15))
for n in range(3):
    ax = plt.subplot(1, 3, n + 1)
    plt.imshow(imgs[:, :, n])
    plt.axis('off')

plt.subplots_adjust(wspace=0.01, hspace=0.01)
plt.savefig('cat.jpg')


import os
from math import ceil, floor
from multiprocessing.context import Process

import torch
from PIL import Image
from torch.utils.data import Dataset
from torchvision import transforms
from torchvision.utils import save_image

from tqdm import tqdm

class ResizeInputDataset(Dataset):
    def __init__(self, root, transform=None, split: float = 1.0):
        self.root = root
        self.transform = transform

        all_items = os.listdir(self.root)
        n = len(all_items)

        lower, upper = split

        self.items = all_items[floor(n*lower):min(ceil(n*upper), n)]

    def __len__(self):
        return len(self.items)

    def __getitem__(self, idx):
        if torch.is_tensor(idx):
            idx = idx.tolist()

        img_name = self.items[idx]
        image = Image.open(os.path.join(self.root, img_name)).convert('RGB')

        if self.transform is not None:
            image = self.transform(image)
        return image, img_name

def compose_transformations(width: int, height: int, center_crop: bool):
    """ Composes a transformation that keeps the size ratio.
    """
    transformations = [
        transforms.Resize(max(width, height), interpolation=Image.BICUBIC),
        transforms.CenterCrop((width, height)),
        transforms.ToTensor()
    ]

    if not center_crop:
        del transformations[1]

    return transforms.Compose(transformations)

def resize_images(input_folder: str, output_folder: str, overwrite: bool, resize_kwargs: dict,
                  split=(0.0, 1.0), index=0):
    ds = ResizeInputDataset(root=input_folder, transform=compose_transformations(**resize_kwargs), split=split)

    for img, img_name in tqdm(ds, desc="Resizing Images", disable=index != 0):
        if not os.path.exists(os.path.join(output_folder, img_name)) or overwrite:
            save_image(img, os.path.join(output_folder, img_name))

def resize_images_parallel(input_folder: str, output_folder: str, overwrite: bool, n_procs: int, resize_kwargs: dict):
    split = 1.0 / n_procs

    processes = []
    for m in range(n_procs):
        this_split = (split * m, split * (m+1))

        p = Process(target=resize_images,
                    args=(input_folder, output_folder, overwrite, resize_kwargs, this_split, m))
        p.daemon = True
        p.start()
        processes.append(p)

    for p in processes:
        p.join()
    print("Done Resizing!")


def prime_number(n):
    is_prime = True
    for i in range(2, n):
        if n % i == 0:
            is_prime = False
        if is_prime:
            return True
        else:
            return False

def next_prime(number):
    while True:
        number = number + 1
        if prime_number(number):
            print("Number", number, "is prime.")
            break
    return number

number = int(input("Type in a number: "))
print(next_prime(number))