# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='BotsRunning',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('pid', models.IntegerField()),
                ('started', models.DateTimeField(auto_now_add=True)),
                ('rpc', models.IntegerField()),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='CapturedUrls',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('timestamp', models.DateTimeField(auto_now_add=True)),
                ('nick', models.CharField(max_length=90)),
                ('room', models.CharField(max_length=60)),
                ('url', models.CharField(max_length=200)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='NetworkPermissions',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('network', models.TextField()),
            ],
            options={
                'permissions': (('bot_admin', 'Create user logins and assign permissions'), ('activate_plugins', 'Can activate/deactivate plugins network wide'), ('join_or_part_room', 'Join or part bot to rooms'), ('irc_cmd', 'Issue arbitrary command to bot'), ('set_pvt_version', 'Set bible version default in private chat window'), ('change_pvt_trigger', 'Set trigger used in private chat window'), ('change_nick', 'Can issue a bot nick change command'), ('warn_user', 'Warn a user of their behaviour')),
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='NetworkPlugins',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('network', models.TextField()),
                ('loaded', models.BooleanField(default=False)),
                ('enabled', models.BooleanField(default=True)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='OptionLabels',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('group', models.CharField(max_length=15)),
                ('display_order', models.PositiveSmallIntegerField()),
                ('label', models.CharField(max_length=40)),
                ('option_name', models.CharField(max_length=15)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Plugins',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('name', models.TextField(unique=True)),
                ('description', models.TextField()),
                ('system', models.BooleanField(default=False)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='ReportedTweets',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('network', models.CharField(max_length=60)),
                ('room', models.CharField(max_length=30)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='RoomOptions',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('network', models.TextField()),
                ('room', models.TextField()),
                ('option', models.TextField()),
                ('value', models.TextField(null=True, blank=True)),
            ],
            options={
                'db_table': 'room_options',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='RoomPermissions',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('network', models.TextField()),
                ('room', models.TextField()),
            ],
            options={
                'permissions': (('room_admin', 'Assign permissions to existing users of own room'), ('change_trigger', 'Change trigger'), ('set_default_translation', 'Set default room translation'), ('set_verse_limits', 'Set room verse limits'), ('set_greeting', 'Set room greeting message'), ('can_speak', 'Speak through bot'), ('enable_plugins', 'Can enable or disable room plugins'), ('kick_user', 'Can kick user'), ('ban_user', 'Can ban user'), ('room_op', 'Bot can op'), ('twitter_op', 'Can add or remove twitter follows')),
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='RoomPlugins',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('room', models.TextField()),
                ('enabled', models.BooleanField(default=False)),
                ('net', models.ForeignKey(to='logos.NetworkPlugins')),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Settings',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('option', models.TextField()),
                ('value', models.TextField(null=True, blank=True)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='TwitterFollows',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('network', models.CharField(max_length=60)),
                ('room', models.CharField(max_length=30)),
                ('screen_name', models.CharField(max_length=60)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='TwitterStatuses',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('twitter_id', models.DecimalField(unique=True, max_digits=25, decimal_places=0)),
                ('created_at', models.DateTimeField()),
                ('screen_name', models.CharField(max_length=60)),
                ('text', models.CharField(max_length=260)),
                ('url', models.CharField(max_length=200, null=True)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.AddField(
            model_name='reportedtweets',
            name='tweet',
            field=models.ForeignKey(to='logos.TwitterStatuses'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='networkplugins',
            name='plugin',
            field=models.ForeignKey(to='logos.Plugins'),
            preserve_default=True,
        ),
    ]


class BuildCalculationKey:
    __current_value: int
    cluster_count: int
    ensemble_count: int

    def __init__(self, ensemble_count: int, cluster_count: int) -> None:
        super().__init__()
        self.ensemble_count = ensemble_count
        self.cluster_count = cluster_count
        self.__current_value = 0

    def int2base(self, x):
        result = [0 for _ in range(self.ensemble_count)]
        digs = [value for value in range(self.cluster_count)]
        if x == 0:
            return result

        result_index = self.ensemble_count - 1

        while x:
            result[result_index] = digs[int(x % self.cluster_count)]
            x = int(x / self.cluster_count)
            result_index -= 1
        return result

    @property
    def current_value(self):
        return self.__current_value

    @property
    def current_array(self):
        return self.int2base(self.__current_value)

    def next(self) -> bool:
        if self.__current_value < (self.cluster_count ** self.ensemble_count - 1):
            self.__current_value += 1
            return True
        else:
            return False


import os, sys

# for use with Bash
# py -3.4 compare_md5_bash.py path1 path2

try:
    dir1path, dir2path = sys.argv[1], sys.argv[2]
except IndexError:
    print('\npython compare_md5_bash.py path1 path2\n')
    raise

dir1 = [os.path.join(dir1path, file) for file in os.listdir(dir1path)
        if os.path.isfile(os.path.join(dir1path, file))]
dir2 = [os.path.join(dir2path, file) for file in os.listdir(dir2path)
        if os.path.isfile(os.path.join(dir2path, file))]

duplicates = []

for file1 in dir1:
    pipe1 = os.popen('md5sum "%s"' % file1)
    hash1 = pipe1.read().split(' ')[0]
    pipe1.close()
    for file2 in dir2:
        pipe2 = os.popen('md5sum "%s"' % file2)
        hash2 = pipe2.read().split(' ')[0]
        pipe2.close()
        if hash1 == hash2:
            duplicates.append((file1, file2))

for pair in duplicates:
    print(pair)


from django.contrib import admin
from main.models import *
from django.utils.safestring import mark_safe

class CategoryAdmin(admin.ModelAdmin):
    list_display = ('id', 'title', 'is_published', 'views', 'photo', 'get_photo')
    list_display_links = ('id', 'title')
    search_fields = ('id', 'title')
    list_editable = ('is_published',)

    fields = ('title', 'is_published', 'views', 'slug', 'photo', 'get_photo')
    readonly_fields = ('views', 'get_photo')

    def get_photo(self, obj):
        if obj.photo:
            res = mark_safe(f'')
        else:
            res = "нет картинки"
        return res

    get_photo.short_description = 'Миниатюра'

class ImageGalleryInline(admin.TabularInline):
    model = ImageGallery
    extra = 1
    fields = ('additional_picture', 'created_at', 'get_photo')
    readonly_fields = ('get_photo', 'created_at')

    def get_photo(self, obj):
        if obj.additional_picture:
            res = mark_safe(f'')
        else:
            res = "нет картинки"
        return res

    get_photo.short_description = 'Доп. картинка'

class ProductAdmin(admin.ModelAdmin):
    inlines = [ImageGalleryInline, ]
    list_display = ('get_photo', 'title', 'article', 'is_published', 'category', 'price_unit', 'price_pack', 'views')
    list_display_links = ('title', 'article')
    search_fields = ('title', 'article', 'category')
    list_editable = ('price_unit', 'price_pack', 'is_published')
    fields = ('get_photo', 'main_image', 'title', 'article', 'category', 'is_published', 'description', 'price_unit',
              'price_pack', 'views', 'created_at', 'update_at')
    readonly_fields = ('get_photo', 'created_at', 'update_at', 'views')

    def get_photo(self, obj):
        if obj.main_image:
            res = mark_safe(f'')
        else:
            res = "нет картинки"
        return res

    get_photo.short_description = 'Фото'

admin.site.register(Category, CategoryAdmin)
admin.site.register(Product, ProductAdmin)

admin.site.site_title = "Админ панель"
admin.site.site_header = "Админ панель"


import os
import numpy as np
import face_alignment
import pickle
import cv2

fa = face_alignment.FaceAlignment(
    face_alignment.LandmarksType._2D,
    face_detector="sfd",
    flip_input=False,
    device="cpu"
)

def get_features(path_to_images):

    for image in path_to_images:
        img = cv2.imread(image)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

        try:
            preds, boxes = fa.get_landmarks(img)
        except:
            continue

        preds = preds[0] # 68 x 2
        with open(SAVE_DIR + 'path', 'wb') as handle:
            pickle.dump(preds, handle)

'''Directory:
    real image: ~/modidatasets/VoxCeleb2/preprocessed_data/test/ids/pose'
    synthesized images:
        ~/synthesized_images_pose/
                <id_1>/
                    <id_1_2>/
                        img_n
                    <id_1_3>/
                        img_n
                <id_2>/
                    <id_2_1>/
                        img_n
                    <id_2_3>/
                        img_n
    landmark files:
        ~/landmark_files/
            <id_1>/
                <driver>/
                    id_1_frame-number.pkl # driver - frame 32 -> 64
                    id_1-frame-number.pkl
                <driven>/
                    id_1_1_frame-number.pkl # synthesized using driver - frame 32 -> 64
                    id_1_1_frame-number.pkl
            <id_2>/
                <driver>/
                    id_2_frame-number.pkl
                <driven>/
                    id_2_2_frame-number.pkl

    Read from original images
    Read from synthesized directory
    Save to pickle folder
'''
LANDMARK_DIR = '/home/ubuntu/landmark'
REAL_DIR = '/home/ubuntu/modidatasets/VoxCeleb2/preprocessed_data/test/ids/pose'

ids = os.listdir(REAL_DIR)

for idx in ids:
    idx_path = os.path.join(REAL_DIR, idx)
    codes = os.listdir(idx_path)
    for code in codes:
        code_path = os.path.join(idx_path, code)
        mp4s = os.listdir(code_path)
        for mp4 in mp4s:
            mp4_path = os.path.join(code_path, mp4)
            images = sorted(os.listdir(mp4_path))
            images = [os.path.join(mp4_path, image) for image in images]
            frames = [image for image in images if 'random_frame' in image]
            masks = [image for image in images if 'random_mask' in image]

            for frame in frames:
                frame_number = frame.split('/')[-1].split('_')[0]
                mask_image = [
                    mask
                    for mask in masks
                    if frame_number in mask][0]

                img = cv2.imread(frame)
                img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
                img = cv2.resize(img, (128, 128))
                mask = cv2.imread(mask_image)
                mask = cv2.cvtColor(mask, cv2.COLOR_BGR2RGB)
                mask = cv2.resize(mask, (128, 128))
                mask = np.mean(mask, axis=-1, keepdims=True)
                mask = np.where(mask > 0.001, 1., 0.)
                img = img * mask
                try:
                    preds, boxes = fa.get_landmarks(img)
                except:
                    continue

                preds = preds[0] # 68 x 2
                save_dir = os.path.join(LANDMARK_DIR, '{}'.format(idx), 'driver')
                if not os.path.exists(save_dir):
                    os.makedirs(save_dir)

                frame_number = frame.split('/')[-1].split('_')[0]
                with open(os.path.join(save_dir, '{}_{}.pkl'.format(idx, frame_number)), 'wb') as handle:
                    pickle.dump(preds, handle)

print('Landmark for real images computed')

SYNTH_DIR = '/home/ubuntu/synthesized_images'
ids = os.listdir(SYNTH_DIR)

for idx in ids:
    idx_path = os.path.join(SYNTH_DIR, idx)
    sub_idx_path = os.path.join(idx_path, idx)

    frames = sorted(os.listdir(sub_idx_path))
    frames = [os.path.join(sub_idx_path, frame) for frame in frames]
    frames = [frame for frame in frames if 'random_frame' in frame]

    for frame in frames:
        img = cv2.imread(frame)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

        try:
            preds, boxes = fa.get_landmarks(img)
        except:
            continue

        preds = preds[0]
        save_dir = os.path.join(LANDMARK_DIR, '{}'.format(idx), 'driven')
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)

        frame_number = frame.split('/')[-1].split('_')[0]
        with open(os.path.join(save_dir, '{}_{}.pkl'.format(idx, frame_number)), 'wb') as handle:
            pickle.dump(preds, handle)

print('Landmark for synthesized images computed')


##############################################
#
# Solving Re-ionisation
# By DS 2017, updated by DS 2018
#
##############################################
from pylab import *
from scipy.integrate import odeint
import matplotlib
#matplotlib.rc('text', usetex=True)   # Commented out for iMAC
from math import *
from scipy.interpolate import interp1d
import pyfits as py
import pyfits
from scipy.integrate import quadpack
from scipy.integrate import quadrature
from scipy import special
import os

# Quick function to open fits catalogue and deliver it back
def fits_open(file_in):
    Open_C=pyfits.open(file_in)
    Fits_catalogue=Open_C[1].data
    return Fits_catalogue

#### LOAD SC4K RESULTS
def Load_SC4K(sample='SSC4K'):

    CAT='../Santos2017_SC4K/Analysis_Global_Lya_LF/MCMC_Results_11122017_vfinal2.fits'

    # Open the catalogue
    data=fits_open(CAT)
    # FIELDS with relevant information
    SUB_SET = data.field('Sub_set_condition') # Name of sub-set
    Alpha = data.field('Alpha') # Name of sub-set
    Upper_lum_fit = data.field('Fit_upp_luminosity')
    ALPHA_fixed = (Alpha==-1.8)

    #LOAD ALL info
    L_dens, Ldens_up, Ldens_down, SFRD_, SFRD_up, SFRD_down, Ldens_PL, Ldens_PL_up, Ldens_PL_down = data.field('Ldens'), data.field('Ldens_error_up'), data.field('Ldens_error_down'), data.field('Ldens'), data.field('Ldens_error_up'), data.field('Ldens_error_down'), data.field('Ldens_PL2'), data.field('Ldens_error_up_PL2'), data.field('Ldens_error_down_PL2')
    # SETUP ERRORS
    ####
    Ldens_up_log   =  np.log10(L_dens+Ldens_up)-np.log10(L_dens)
    Ldens_down_log = np.log10(L_dens)-np.log10(L_dens-Ldens_down)
    #
    Ldens_PL_up_log =  np.log10(Ldens_PL+Ldens_PL_up)-np.log10(Ldens_PL)
    Ldens_PL_down_log =  np.log10(Ldens_PL)-np.log10(Ldens_PL-Ldens_PL_down)

    # GET REDSHIFTS
    Redshift_c, Delta_redshift = (data.field('Redshift_min')+data.field('Redshift_max'))/2.,(data.field('Redshift_max')-data.field('Redshift_min'))/2.
    # Copy to each filter
    MASK_each_filter = Alpha>100000.0
    MASK_each_fil_DRAKE= Alpha>100000.0
    # Now get the conditions properly:
    FILTERS=['NB392','IA427','IA464','IA484','IA505','IA527','IA574','IA624','IA679','IA709','IA738','IA767','IA827']
    INTEGRAL_con = [43.3,43.3,43.3,43.3,43.3,43.3,44.5,44.5,44.5,44.5,44.5,44.5,44.5]
    #
    for i in range(len(FILTERS)):
        MASK_each_filter = MASK_each_filter+ ((SUB_SET == '%s'%FILTERS[i])*ALPHA_fixed*(Upper_lum_fit==INTEGRAL_con[i]))
        MASK_each_fil_DRAKE = MASK_each_fil_DRAKE+ ((SUB_SET == '%s_with_All_lit'%FILTERS[i])*(Upper_lum_fit==INTEGRAL_con[i]))

    # NOW for redshift bins
    FILTERS = ['z22_ALL','z25_ALL', 'z31_ALL', 'z39_ALL', 'z47_ALL', 'z54_ALL']
    INTEGRAL_con = [43.3,43.3,43.3,44.5,44.5,44.5]
    MASK_stacks = Alpha>100000.0
    MASK_stacks_DRAKE= Alpha>100000.0
    #
    for i in range(len(FILTERS)):
        MASK_stacks = MASK_stacks+ ((SUB_SET == '%s'%FILTERS[i])*ALPHA_fixed*(Upper_lum_fit==INTEGRAL_con[i]))
        MASK_stacks_DRAKE = MASK_stacks_DRAKE+ ((SUB_SET == '%s_with_All_lit'%FILTERS[i])*(Upper_lum_fit==INTEGRAL_con[i]))

    # Now for full stack
    # NOW for redshift bins
    FILTERS = ['FULL_SC4K','FULL_SC4K']
    INTEGRAL_con = [43.3,43.5]
    FULL_SC4K = Alpha>100000.0
    FULL_SSC4K = Alpha>100000.0
    #
    for i in range(len(FILTERS)):
        FULL_SC4K = FULL_SC4K+ ((SUB_SET == '%s'%FILTERS[i])*ALPHA_fixed*(Upper_lum_fit==INTEGRAL_con[i]))
        FULL_SSC4K = FULL_SSC4K+ ((SUB_SET == '%s_with_All_lit'%FILTERS[i])*(Upper_lum_fit==INTEGRAL_con[i]))

    if sample=='SSC4K':
        return Redshift_c[MASK_each_fil_DRAKE],np.log10(L_dens[MASK_each_fil_DRAKE]), Ldens_down_log[MASK_each_fil_DRAKE],Ldens_up_log[MASK_each_fil_DRAKE]

############################################
# Return condicence levels
def plot_confidence_Lya(x_in,ysample,colour='g'):
    lower = percentile(ysample,16,axis=0)  # Equivalent to 1 sigma
    upper = percentile(ysample,84,axis=0) # Equivalent to 1 sigma
    lower2 = percentile(ysample,100-97.72,axis=0)  #, Equivalent to 2 sigma
    upper2 = percentile(ysample,97.72,axis=0) # Equivalent to 2 sigma
    lower3 = percentile(ysample,0.15,axis=0)  #, Equivalent to 3 sigma
    upper3 = percentile(ysample,99.85,axis=0) # Equivalent to 3 sigma
    return x_in,lower,upper, lower2, upper2, lower3, upper3

####################################
# Gaussian Function
def gaussian(x,x0,sigma):
    return np.exp(-(x-x0)**2/(2*sigma**2))

####################################
# Double gaussian, asymmetric
# phi_dummy generates the space of values to pick from
# phi_probs generates the PDF for a 1sigma error around each phi
def double_normal(phi,err_down,err_up,size):
   phi_dummy = np.linspace(phi-5.*err_down,phi+5.*err_up,100000) #generate list from -5 to +5 error
   phi_probs = np.append(gaussian(phi_dummy[phi_dummy<phi],phi,err_down),gaussian(phi_dummy[phi_dummy>=phi],phi,err_up))
   return np.random.choice(phi_dummy,size,p=phi_probs/np.sum(phi_probs))

##################################
def dQ_dt (Q,t): #HII_fraction

    z = t_to_z(t)
    trec = 1./(C*alpha_B*n_e*(1.+z)**(3.)) # s
    nion = f_esc0*xi_ion*p(z)/ (2.938e+73) # (2.938e+73) converts from Mpc^-3 to cm^-3  - full units s^-1 Mpc^-3
    return ((nion)/n_H-Q/trec)*3.1536e+16 # Conversion to time in seconds

##################################
def dQ_dt_Lya (Q,t): #HII_fraction

    z = t_to_z(t)
    trec = 1./(C*alpha_B*n_e*(1.+z)**(3.)) # s
    cHa_K98 = 1.36*pow(10.,-12.)

    #Q_ionLya =  LLya/(cHa_K98*(1-f_esc0)(0.042*EW0)) # Equation 5 Sobral & Matthee 2018
    nion = f_esc0*(pLya(z)/(cHa_K98*(1.-f_esc0)*(0.042*EW(z))))/ (2.938e+73) # From Sobral & Matthee 2018
    #nion = f_esc0*xi_ion*p(z)/ (2.938e+73) # (2.938e+73) converts from Mpc^-3 to cm^-3  - full units s^-1 Mpc^-3
    return ((nion)/n_H-Q/trec)*3.1536e+16 # Conversion to time in seconds

##################################
def dQ_dt_direct (Q,t): #HII_fraction

    z = t_to_z(t)
    trec = 1./(C*alpha_B*n_e*(1.+z)**(3.)) # s
    cHa_K98 = 1.36*pow(10.,-12.)

    nion = pLyC(z)/ (2.938e+73) # (2.938e+73) converts from Mpc^-3 to cm^-3  - full units s^-1 Mpc^-3
    return ((nion)/n_H-Q/trec)*3.1536e+16 # Conversion to time in seconds

##################################
def tau (z):

    return sigma_T*n_e*(1.+z)*(1.+z)*Q(z)*c/(H)/z   # Units:
    # sigma_T  = cm^2
    # c km/s
    # H km/s/Mpc => now km/s/cm
    # Q(z) - unitless
    #n_e per cm^3
    # cm^2 * cm  / cm^3 = unitless

def compute_tau_z(Q,zmin=0.6,zmax=14.,dz=0.3):
    z_integrate = arange(zmin,zmax,dz)
    taus_plot = []
    for i in z_integrate:
        taus_plot.append(quadpack.quad(tau,0.3,i)[0])

    return z_integrate, taus_plot

###########################
# Main properties/constants
#####################################################################################
Omega_b = 0.04 #baryon_density
h = 0.7 # hubble constant / 100
X_p = 0.75 #hydrogen_mass_fraction
T = 20000. #IGM_temperature [K]
C = 3.  #clumping_factor
Y_p = (1.-X_p) # Helium mass
alpha_B = 2.6*pow(10,-13.)*(T/10.**(4.))**(-0.76)  #case_B_recombination_coefficient
n_H = 1.67*pow(10,-7.) * ((Omega_b * h* h)/0.02) * (X_p/0.75) # per cm^3
c = 299792.458  # Speed of light km/s

#### For getting Tau (z)
sigma_T = 6.65*pow(10,-25) # Thomson scattering cross section   cm^2  - from Mayer et al.
n_e = (1.+Y_p/(4.*X_p))*n_H   # comoving number density of electrons (assuming singly ionized He)
H = h*100. *(3.24077929*pow(10,-25.)) # Hubble parameter == hubble constant conversion per cm from per Mpc

#######################################################################################

##################################################################
# GET redshift - time conversion
######
# F737 Cosmology
F737 = 'Redshift_time_F737_cosmology.fits'
# PLanck cosmology
FPlanck = 'Redshift_time_FPlanck_cosmology.fits'

# Which Cosmology to use:
USING_NOW = FPlanck

#LOAD Redshift-time dependence
A=py.open(USING_NOW)
NOW=A[1].data
#LOAD GENERAL PROPERTIES - what will be plotted
Redshift = NOW.field('Redshift')
Time =  NOW.field('Time_Gyr')
# time to redshift relation
t_to_z = interp1d(Time,Redshift,kind='linear',bounds_error=None)

############################################################
# Integration limits and conversion z to time
#
ts = np.linspace(0.25,13.4,60000)  # Produce time grid  - 50000 steps seems to be a good minimum for convergence
zs= t_to_z(ts)
t0 = 0.0
###############################################################

#################################

#### START PLOT

# DEFINE the sub-plots to make them side by side and share Y axis
f, (ax1,ax2) = plt.subplots(2,1, sharex=True, figsize=(9,9))
plt.subplots_adjust(wspace = -0.04)  # adjust spacing between sub-figures
# setting up the font style throughout
matplotlib.rcParams.update({'font.size': 18, 'font.weight': 'bold'}) # change for diff style

###### QHII PLOT NOW ######
########################################
# Plot end of re-ionisation
za = [6.0,6.0000001]
zp = [-0.5,5.0]
Reionisation = plot(za,zp,'k--')

## PLOT REIONISATION EPOCH
za = [8.8,8.80001]
zp = [-0.5,5.0]
Reionisation = plot(za,zp,linestyle='-',color ='0.40', linewidth=8, zorder=-8)
Reionisation = ax1.plot(za,zp,linestyle='-',color ='0.60', linewidth=8, zorder=-18)

# Extra integration limit
extra_int = 0.45

########################################
# UV luminosity densities
B=py.open('RHO_UV.fits')
NOWB=B[1].data
Red_z = NOWB.field('Redshift')
rho_UV =  10.**(NOWB.field('p_UV_12')) # 'p_UV_12  p_UV_13', 'p_UV_17' - other integration limits
rho_UV_log = (NOWB.field('p_UV_12')) # 'p_UV_12  p_UV_13', 'p_UV_17' - other integration limits
p = interp1d(Red_z,rho_UV,kind='linear',bounds_error=None) # p is rho UV(z)

# LOAD Lyman-alpha luminosity density, from S-SC4K
z_Lya, logLumLya, err_downLya, err_upLya=Load_SC4K(sample='SSC4K')
# Convert to list so can be appended
z_Lya, logLumLya, err_downLya, err_upLya= list(z_Lya), list(logLumLya+extra_int), list(err_downLya), list(err_upLya)

##############################################################
# Add z=6.6, z=7.0, z=7.3 from Matthee+, Zheng+, Konno+
z_others = [6.6,7.0,7.3]
pLya_others = [39.4,38.92,38.55]
err_others = [0.3,0.4,0.3]
# Best linear fit
Bfit = [-0.21, 40.9+extra_int]
# Best linear fit is given by: A=-1.21351351,  B=47.41081081   in log10
# Add higher redshift data - underestimation likely due to reionisaiton effects
"""
for i in range(len(z_others)):
    z_Lya.append(z_others[i])
    logLumLya.append(pLya_others[i])
    err_downLya.append(err_others[i])
    err_upLya.append(err_others[i])
"""

# Linking Lya with UV assuming rho_Lya actually declines as UV - this should be a conservative assumption

# Add higher redshift extrapolated data
for i in [6.0,6.5,7.0,7.5,8.0,8.5,9.0,10.0,10.5,11.0,12.,13.0,14.,16.0,17.0,18.0]:
    z_Lya.append(i)
    logLumLya.append(i*Bfit[0]+Bfit[1])
    err_downLya.append(0.4)
    err_upLya.append(0.3)

z_Lya[0]=0.0

# Convert back to arrays
z_Lya, logLumLya, err_downLya, err_upLya= array(z_Lya), array(logLumLya), array(err_downLya), array(err_upLya)
# Fit higher redshift to extrapolate:

Q_storing, Tau_storing = [], []

iterations = 10000

xi_ions = [25.5,0.2,0.6] # central value, 1 sigma down, 1 sigma up
xi_ion_lya = [25.5,0.2,0.4]
f_esc0_lya = [0.15,0.05,0.05]

EW_0_dist = [80.0,5.,15.]

f_esc0s = [0.15,0.05,0.1]
pUV_uncert = [0.1,0.05]
##### TRY MCMC quick

for i in range(iterations):#### Draw from normal distribution

            rho_lya_new = logLumLya-logLumLya # create new array with zeros
            for j in range(len(logLumLya)): # Go through each one
                rho_lya_new[j]=pow(10.,double_normal(logLumLya[j],err_downLya[j],err_upLya[j],1)[0])

            #print rho_lya_new
            pLya = interp1d(z_Lya,rho_lya_new,kind='linear',bounds_error=None)

            #print pLya(2.22), z_Lya
            # for now assume EW fixed
            EW_pick_now = double_normal(EW_0_dist[0],EW_0_dist[1],EW_0_dist[2],1)[0]
            EW_fixed =rho_lya_new-rho_lya_new+EW_pick_now
            EW = interp1d(z_Lya,EW_fixed,kind='linear',bounds_error=None)

            # Now pick and f_esc LyC
            f_esc0 = double_normal(f_esc0s[0],f_esc0s[1],f_esc0s[2],1)[0]

            # Solve equation
            Q = odeint(dQ_dt_Lya,t0,ts)  # SOLVE NOW

            # SET boundary conditions
            Q[Q>1.0] = 1.0 # boundary condition up
            Q[Q<0.0] = 0.0 # boundary condition down

            # Make it an actual function - rder values
            Q_not = []
            z_not = []
            zs = array(zs)
            for i in range(len(Q)):
                Q_not.append(Q[len(Q)-i-1][0])
                z_not.append(zs[len(zs)-i-1])

            # now interpolate
            Q = interp1d(array(z_not),array(Q_not),kind='linear') # p is rho UV(z)
            Q_storing.append(Q(zs))

            # NOW TAU:
            z_plot, taus_plot = compute_tau_z(Q)

            Tau_storing.append(taus_plot)

            #plot(z_not,Q(z_not),'g-',linewidth=0.4,zorder=-1)

# FIND AND PLOT COUNTOURS FOR Fraction of Ionised Hydrogen
xi,lower,upper, lower2, upper2, lower3, upper3 = plot_confidence_Lya(zs,Q_storing,colour='#ff8080')
SHADE = fill_between(xi,lower,upper,lw=1,color='#0066ff',alpha=0.4,zorder = 90)

#SHADE = fill_between(xi,lower2,upper2,lw=1,color='#e6e6ff',alpha=0.8,zorder = 80)
#SHADE = fill_between(xi,lower3,upper3,lw=1,color='#cce6ff',alpha=0.4,zorder = -100)

# FIND AND PLOT CONTOUNRS FOR Tau - CMB optical depth to compare with Planck

xi,lower,upper, lower2, upper2, lower3, upper3 = plot_confidence_Lya(z_plot,Tau_storing,colour='#ff8080')
SHADE = ax1.fill_between(xi,lower,upper,lw=1,color='#0066ff',alpha=0.4,zorder = 90)

LABEL_contours = plot([-20,-10],[-20,-10],lw=8,alpha=0.4,color='#0066ff')

### FOR UV LBG formalism
"""
rho_UV_new = rho_UV_log-rho_UV_log # create array with zeros
for j in range(len(rho_UV_log)): # Go through each one
    rho_UV_new[j]=pow(10.,double_normal(rho_UV_log[j],pUV_uncert[0],pUV_uncert[1],1)[0])
p = interp1d(Red_z,rho_UV_new,kind='linear',bounds_error=None)

# Pick an x_ion - in log10
xi_ion=pow(10.,double_normal(xi_ions[0],xi_ions[1],xi_ions[2],1)[0]) ###ASYMETRIC
"""

p = interp1d(Red_z,rho_UV,kind='linear',bounds_error=None)

######

# Solve equation
Q = odeint(dQ_dt_Lya,t0,ts)  # SOLVE NOW

# SET boundary conditions
Q[Q>1.0] = 1.0 # boundary condition up
Q[Q<0.0] = 0.0 # boundary condition down

# Make it an actual function - rder values
Q_not = []
z_not = []
zs = array(zs)
for i in range(len(Q)):
    Q_not.append(Q[len(Q)-i-1][0])
    z_not.append(zs[len(zs)-i-1])

# now interpolate
Q = interp1d(array(z_not),array(Q_not),kind='linear') # p is rho UV(z)

########################################
# UV luminosity densities
B=py.open('RHO_UV.fits')
NOWB=B[1].data
Red_z = NOWB.field('Redshift')
rho_UV =  10.**(NOWB.field('p_UV_13')) # 'p_UV_12  p_UV_13', 'p_UV_17' - other integration limits
rho_UV_log = (NOWB.field('p_UV_13')) # 'p_UV_12  p_UV_13', 'p_UV_17' - other integration limits
p = interp1d(Red_z,rho_UV,kind='linear',bounds_error=None) # p is rho UV(z)

#################################################################
# ALL - Robertson+ like
xi_ion = 10.**(25.2) #production_efficiency [Hz erg**(-1.)]
f_esc0 = 0.20

Q = odeint(dQ_dt,t0,ts)  # SOLVE NOW
Q_LAE=Q
Q[Q>1.0] = 1.0 # boundary condition up
Q[Q<0.0] = 0.0 # boundary condition down

# Make it an actual function - rder values
Q_not = []
z_not = []
zs = array(zs)
for i in range(len(Q)):
    Q_not.append(Q[len(Q)-i-1][0])
    z_not.append(zs[len(zs)-i-1])

# now interpolate
Q = interp1d(array(z_not),array(Q_not),kind='linear') # p is rho UV(z)

##################################################################################
### NOW TAU PLOT

# SOLVE TAU:
z_plot, taus_plot = compute_tau_z(Q)

TOTAL = plot(z_not,Q(z_not),'g-',linewidth=3,zorder=-1)
Prediction = ax1.plot(z_plot, taus_plot,'g-',linewidth=3,zorder=-1)

#################################################################
# LAEs
xi_ion = 10.**(25.6) #production_efficiency [Hz erg**(-1.)]
f_esc0 = 0.10

Q = odeint(dQ_dt,t0,ts)  # SOLVE NOW
Q_LAE=Q
Q[Q>1.0] = 1.0 # boundary condition up
Q[Q<0.0] = 0.0 # boundary condition down

# Make it an actual function - rder values
Q_not = []
z_not = []
zs = array(zs)
for i in range(len(Q)):
    Q_not.append(Q[len(Q)-i-1][0])
    z_not.append(zs[len(zs)-i-1])

# now interpolate
Q = interp1d(array(z_not),array(Q_not),kind='linear') # p is rho UV(z)
LAEs = plot(z_not,Q(z_not),'b-.',linewidth=6,zorder=-1)

##################################################################################
### NOW TAU PLOT

# SOLVE TAU:
z_plot, taus_plot = compute_tau_z(Q)
Prediction = ax1.plot(z_plot, taus_plot,'b-.',linewidth=6,zorder=-1)

#################################################################
# LBGs z~3
xi_ion = 10.**(25.3) #production_efficiency [Hz erg**(-1.)]
f_esc0 = 0.03

Q = odeint(dQ_dt,t0,ts)  # SOLVE NOW
Q_LAE=Q
Q[Q>1.0] = 1.0 # boundary condition up
Q[Q<0.0] = 0.0 # boundary condition down

# Make it an actual function - rder values
Q_not = []
z_not = []
zs = array(zs)
for i in range(len(Q)):
    Q_not.append(Q[len(Q)-i-1][0])
    z_not.append(zs[len(zs)-i-1])

# now interpolate
Q = interp1d(array(z_not),array(Q_not),kind='linear') # p is rho UV(z)
LBGs_real = plot(z_not,Q(z_not),'r--',linewidth=3,zorder=-1)

##################################################################################
### NOW TAU PLOT

# SOLVE TAU:
z_plot, taus_plot = compute_tau_z(Q)
Prediction = ax1.plot(z_plot, taus_plot,'r--',linewidth=3,zorder=-1)

#### PLOT Planck
########################################
# Plot Planck optical depth
za = [-2.0,19.0000001]
zp = [0.066,0.06600001]
Reionisation = ax1.plot(za,zp,'k--',linewidth=3)
Reionisation = ax1.plot(za,zp,'k-',linestyle='-',color ='0.90', linewidth=50, zorder=-20) # INCLUDES ERROR
#Reionisation = ax1.plot(za,array(zp)+0.012,'k-',linewidth=3)
#Reionisation = ax1.plot(za,array(zp)-0.012,'k-',linewidth=3)

# LEGEND
I1=legend((LABEL_contours[0],TOTAL[0],LAEs[0],LBGs_real[0]),(r'S-SC4K+SM18 MCMC',r'R+13,15',r'LAEs $z\sim2-3$',r'LBGs $z\sim2-3$'), shadow = True, loc=3,numpoints=1)
ltext = gca().get_legend().get_texts()
setp(ltext[0], fontsize = 19, color='0.1')
setp(ltext[1], fontsize = 19, color='k')
frame=I1.get_frame()
frame.set_linewidth(0)
frame.set_visible(False)

# Define the axis
axis([0,13.1,-0.05,1.05])
ax1.axis([0,13.1,-0.01,0.11])

# Label axis - quantities and units
ax2.set_xlabel(r'Redshift ($\bf z$)', {'color':'k', 'fontsize': 23})
ax2.set_ylabel(r'Ionised H Fraction (\%)', {'color':'k', 'fontsize': 23})
ax1.set_ylabel(r'$\bf \tau (z)$', {'color'    : 'k', 'fontsize'   :24 })

# SET AXIS - labelling
ax2.set_xticks((0,2,4,6,8,10,12),(0,2,4,6,8,10,12))
ax2.set_yticks((0.0,0.2,0.4,0.6,0.8,1.0),(0,20,40,60,80,100))
ax1.set_yticks((0.0,0.02,0.04,0.06,0.08,0.10),(0.0,0.02,0.04,0.06,0.08,0.10))

savefig('Q_HII_and_Tau_evolution.pdf')
show()


import gym
import numpy as np
import torch
from policy_backward import PolicyBackward
from vcritic import VCritic
from config import Config
import random
import time

# Logging stuff
from tensorboardX import SummaryWriter

env = gym.make('InvertedPendulum-v1')
seed = random.randint(1,10000)
env.seed(seed); torch.manual_seed(seed);

config = Config()

writer = SummaryWriter(f'score/backward-{config.critic_lr}-{config.policy_lr}-{config.normalize_advantages}-BS{config.batch_size}-learnStd={config.learn_std}-{seed}-{int(time.time())}')

vcritic = VCritic(env, config)
policy = PolicyBackward(env, config, writer)

policy.train()

for batch in range(4000):

    states = []
    actions = []
    rewards = []

    total_steps = 0

    # while total_steps < config.batch_size:

    observation = env.reset()
    done = False
    ep_length = 0

    ep_states = [observation]
    ep_actions = []
    ep_rewards = []

    while not done:
        # env.render()
        action = policy.get_action(observation)
        observation, reward, done, info = env.step(action)
        ep_states.append(observation)
        ep_actions.append(action)
        ep_rewards.append(reward)
        ep_length += 1
        if(len(ep_actions) >= 2):
            vcritic.apply_gradient(ep_states[-3], ep_actions[-2], ep_rewards[-2], ep_states[-2])

    states.append(ep_states)
    actions.append(ep_actions)
    rewards.append(ep_rewards)
    total_steps += ep_length

    policy.apply_gradient_batch(states, actions, rewards, batch, vcritic)

    policy_std = np.exp(policy.log_std.detach().numpy())
    print(f"Policy std: {policy_std}")

    # Compute evaluation reward (last episode of batch).
    # total_reward = np.sum(rewards[-1])
    total_reward = np.mean([np.sum(ep) for ep in rewards])
    print(f"Average score in batch: {total_reward}")

    writer.add_scalar("total_reward", total_reward, batch)
    writer.add_scalar("policy_std", policy_std, batch)
    writer.add_scalar("ep_length", ep_length, batch)


import os
import torch
import torchvision
from dataset import CarvanaDataset
from torch.utils.data import DataLoader

CHECKPOINTS = 'checkpoints/'

def check_env():
    """
    Check PyTorch version and CUDA availability
    """
    print(f'CUDA: {torch.cuda.is_available()} - PyTorch: {torch.__version__}')

def save_checkpoint(state, epoch, verbose=0):
    """
    Save checkpoints
    """
    try:
        os.mkdir(CHECKPOINTS)
        print('Created checkpoint directory')
    except OSError:
        pass
    torch.save(state, CHECKPOINTS + f'BEST_CP_epoch{epoch + 1}.pth')
    if verbose == 1:
        print(f'Best checkpoint {epoch + 1} saved !')

def load_checkpoint(filename, model, verbose=0):
    """
    Load checkpoints
    """
    checkpoint = torch.load(CHECKPOINTS + filename)
    model.load_state_dict(checkpoint["state_dict"])
    if verbose == 1:
        print(f'Checkpoint {epoch + 1} loaded !')

def get_loaders(
    train_dir,
    train_maskdir,
    val_dir,
    val_maskdir,
    batch_size,
    train_transform,
    val_transform,
    num_workers=4,
    pin_memory=True,
):
    train_ds = CarvanaDataset(
        image_dir=train_dir,
        mask_dir=train_maskdir,
        transform=train_transform,
    )

    train_loader = DataLoader(
        train_ds,
        batch_size=batch_size,
        num_workers=num_workers,
        pin_memory=pin_memory,
        shuffle=True,
    )

    val_ds = CarvanaDataset(
        image_dir=val_dir,
        mask_dir=val_maskdir,
        transform=val_transform,
    )

    val_loader = DataLoader(
        val_ds,
        batch_size=batch_size,
        num_workers=num_workers,
        pin_memory=pin_memory,
        shuffle=False,
    )

    return train_loader, val_loader

def check_dice_score(loader, model, device="cuda"):
    """
    Compute the dice score
    """
    dice_score = 0
    model.eval()

    with torch.no_grad():
        for x, y in loader:
            x = x.to(device)
            y = y.to(device).unsqueeze(1)
            preds = torch.sigmoid(model(x))
            preds = (preds > 0.5).float()
            dice_score += (2 * (preds * y).sum()) / (
                (preds + y).sum() + 1e-8
            )
    dice_score = dice_score / len(loader)
    model.train()

    return dice_score

def evaluate(loader, model, loss_fn, device="cuda"):
    loss = 0
    model.eval()
    for idx, (x, y) in enumerate(loader):
        x = x.to(device=device)
        y = y.float().unsqueeze(1).to(device=device)
        with torch.no_grad():
            predictions = model(x)
            loss = loss + loss_fn(predictions, y).item()

    model.train()

    return loss / len(loader)

def save_predictions_to_tensorboard(loader, model, epoch, writer, device="cuda"):
    model.eval() #https://stackoverflow.com/questions/60018578/what-does-model-eval-do-in-pytorch
    for idx, (x, y) in enumerate(loader):
        x = x.to(device=device)
        y = y.to(device=device)
        with torch.no_grad():
            preds = torch.sigmoid(model(x))
            preds = (preds > 0.5).float()

        writer.add_images('images', x, epoch)
        writer.add_images('masks/true', y.float().unsqueeze(1), epoch)
        writer.add_images('masks/pred', preds, epoch)

    model.train()

def save_results(loader, jeu, model, epoch, writer, device="cuda"):
    """
    Save results (Dice score and prdictions)
    """
    dice_score = 0
    model.eval()

    for idx, (x, y) in enumerate(loader):
        x = x.to(device)
        y = y.to(device).unsqueeze(1)
        with torch.no_grad():
            preds = torch.sigmoid(model(x))
            preds = (preds > 0.5).float()

        dice_score += (2 * (preds * y).sum()) / (
            (preds + y).sum() + 1e-8)
        writer.add_images(f'images/{jeu}', x, idx)
        writer.add_images(f'masks/{jeu}/true', y.float(), idx)
        writer.add_images(f'masks/{jeu}/pred', preds, idx)

    dice_score = dice_score / len(loader)
    writer.add_scalar(f'dice/{jeu}', dice_score, epoch)

    model.train()


from forumDB.functions.database import exec_insert_update_delete_query, exec_select, Database
from forumDB.functions.common import RequestError
from forumDB.functions.database import  exec_select
from forumDB.functions.thread.getters import get_thread_details
import MySQLdb as mDB

def create_thread(required_params, optional_params):
    info = {
        'forum': required_params['forum'],
        'title': required_params['title'],
        'isClosed': required_params['isClosed'],
        'user': required_params['user'],
        'date': required_params['date'],
        'message': required_params['message'],
        'slug': required_params['slug']
    }
    db = mDB.connect(Database.host, Database.user, Database.password, Database.database, init_command='SET NAMES UTF8')
    cursor = db.cursor()

    cursor.execute('select id from Forums where short_name = %s',(required_params['forum'],))
    f_id = cursor.fetchone()[0]

    cursor.execute('select id from Users where email = %s',(required_params['user'],))
    u_id = cursor.fetchone()[0]

    query = 'insert into Threads (forum , title , isClosed , user , date , message , slug , f_id, u_id'
    values = '(%s, %s, %s, %s, %s, %s, %s, %s, %s '
    query_params = [required_params['forum'], required_params['title'], required_params['isClosed'],
                    required_params['user'], required_params['date'], required_params['message'],
                    required_params['slug'], f_id, u_id]
    if optional_params['isDeleted'] is not None:
        query += ' , isDeleted '
        values += ' , %s '
        query_params.append(optional_params['isDeleted'])
        info['isDeleted'] = optional_params['isDeleted']
    query += ') values ' + values + ' )'

    cursor.execute(query, query_params)
    info['id'] = cursor.lastrowid
    db.commit()
    cursor.close()
    db.close()
    return info

def subscribe_thread(required_params):

    db = mDB.connect(Database.host, Database.user, Database.password, Database.database, init_command='SET NAMES UTF8')
    cursor = db.cursor()

    cursor.execute('select id from Users where email = %s', (required_params['user'],))
    result = cursor.fetchone()

    #######
    if result is None:
        raise RequestError("No such thread or user exists", 1)
    #######

    id = result[0]

    exists = exec_select('select * from Subscriptions where u_id = %s AND thread = %s', ( id, required_params['thread'], ))
    if (len(exists) == 0):
        cursor.execute('insert into Subscriptions (user , thread, u_id) values (%s , %s, %s)',
                                    (required_params['user'], required_params['thread'], id, ))
    db.commit()
    cursor.close()
    db.close()
    return {
        'thread': required_params['thread'],
        'user': required_params['user']
    }

def unsubscribe_thread(required_params):

    db = mDB.connect(Database.host, Database.user, Database.password, Database.database, init_command='SET NAMES UTF8')
    cursor = db.cursor()

    cursor.execute('select id from Users where email = %s', (required_params['user'],))
    id = cursor.fetchone()[0]

    cursor.execute('delete from Subscriptions where u_id = %s and thread = %s',
                                    (id, required_params['thread'], ))
    db.commit()
    cursor.close()
    db.close()

    return {
        'thread': required_params['thread'],
        'user': required_params['user']
    }

def thread_vote(required_params):

    db = mDB.connect(Database.host, Database.user, Database.password, Database.database, init_command='SET NAMES UTF8')
    cursor = db.cursor()

    if required_params['vote'] == 1:
        cursor.execute(
            'update Threads set likes = likes + 1 , points = points + 1 where id = %s',
            (required_params['thread'],))
    if required_params['vote'] == -1:
        cursor.execute(
            'update Threads set dislikes = dislikes + 1, points = points - 1 where id = %s',
            (required_params['thread'],))
    db.commit()
    info = get_thread_details(required_params['thread'], None, cursor)
    cursor.close()
    db.close()
    return info

def close_or_open(type, thread):
    id = 0
    if type == 'open':
        id = exec_insert_update_delete_query('update Threads set isClosed = 0 where id = %s', (thread,))
    if type == 'close':
        id = exec_insert_update_delete_query('update Threads set isClosed = 1 where id = %s', (thread,))
    return {
        'id': id
    }

def thread_update(required_params):
    db = mDB.connect(Database.host, Database.user, Database.password, Database.database, init_command='SET NAMES UTF8')
    cursor = db.cursor()
    cursor.execute("update Threads set message = %s , slug = %s where id = %s",
                                    (required_params['message'], required_params['slug'], required_params['thread'],))
    db.commit()
    info = get_thread_details(required_params['thread'], None, cursor)
    cursor.close()
    db.close()
    return info

def thread_remove_restore(required_params, type):
    id = required_params['thread']
    if type == 'remove':
        result = exec_select("select isDeleted from Threads where id = %s", (id,))
        if (result is None or len(result) == 0):
            raise RequestError("No such thread exists.", 1)
        #if (result[0][0] == 0):
        exec_insert_update_delete_query("update Threads set isDeleted = 1, posts = 0 where id = %s", (id,))
        exec_insert_update_delete_query("update Posts p inner join Threads t on p.thread = t.id set p.isDeleted = 1 where t.id = %s", (id,))
    if type == 'restore':
        result = exec_select("select isDeleted from Threads where id = %s", (id,))
        if (result is None or len(result) == 0):
            raise RequestError("No such thread exists.", 1)
        posts_num = len(exec_select("select id from Posts where thread = %s", (id,)))
        exec_insert_update_delete_query("update Threads set isDeleted = 0, posts = %s where id = %s", (posts_num, id,))
        #exec_insert_update_delete_query("update Threads set isDeleted = 1 where id = %s", (id,))
        exec_insert_update_delete_query("update Posts p inner join Threads t on p.thread = t.id set p.isDeleted = 0 where t.id = %s", (id,))
    return {'thread': id}


import numpy as np
import matplotlib.pyplot as plt
from models.model import Model

class HyperbolicModel(Model):

    def train(self):
        x_1 = 1 / self.x_train
        x_1_2 = x_1 * x_1
        x_1_y = x_1 * self.y_train
        x_1_avg = np.average(x_1)
        x_1_2_avg = np.average(x_1_2)
        x_1_y_avg = np.average(x_1_y)
        eq_left_side = np.array([[1, x_1_avg], [x_1_avg, x_1_2_avg]])
        eq_right_side = np.array([self.y_avg, x_1_y_avg])
        params = np.linalg.solve(eq_left_side, eq_right_side)
        self.a = params[0]
        self.b = params[1]

    def test(self):
        y_t = self.a + self.b * (1 / self.x_test)
        e = y_t - self.y_test
        e_pos_avg = np.average(e[e > 0])
        e_neg_avg = np.average(e[e < 0])
        y_t_e_pos = y_t + e_pos_avg
        y_t_e_neg = y_t + e_neg_avg

        plt.plot(self.x_test, y_t, 'b')
        plt.plot(self.x_test, y_t_e_pos, 'r--')
        plt.plot(self.x_test, y_t_e_neg, 'r--')
        r = np.corrcoef(self.y_test, y_t)[0, 1]
        self.r_2 = r * r
        print("Hyperbolic Model:\nCorrelation coefficient: ", r, "\nDetermination coefficient: ", self.r_2)

    def calculate_mse(self, x, y):
        y_t = self.a + self.b * (1 / x)
        self.mse = sum((y - y_t)**2)
        self.predictions = zip(x, y, y_t)


import pickle
import os
import numpy as np
import matplotlib.pyplot as plt
import torch.utils.data as Data
from tqdm import tqdm
from config import config
from datetime import datetime

import torch
import torch.nn as nn
import torch.nn.functional as F
# BATCH_SIZE=64
# LR=0.01
# EPOCH=100
init_seed = 1222
torch.manual_seed(init_seed)
# torch.cuda.manual_seed(init_seed)
np.random.seed(init_seed) # 用于numpy的随机数

data_dir='./cifar-10-batches-py'
meta_path=os.path.join(data_dir,'batches.meta')
test_path=os.path.join(data_dir,'test_batch')
train_pathname='data_batch_'
log_path='./log/log'
train_path = os.path.join(data_dir, train_pathname )
now=0
def metric(y_true,pred):
    # print(y_true)
    # print(pred)
    TP=torch.tensor([0.]*2)
    FP=torch.tensor([0.]*2)
    FN=torch.tensor([0.]*2)
    for y,p in zip(y_true,pred):
        if(y==p):
            TP[y]+=1
        else:
            FP[p]+=1
            FN[y]+=1
    # print(TP,FP,FN)
    # print(TP+FP)
    precision=TP/(TP+FP+1e-4)
    recall=TP/(TP+FN+1e-4)
    # print(precision,recall)
    F1=2*precision*recall/(precision+recall+1e-4)
    mean_F1=torch.mean(F1)
    return F1,mean_F1

def unpickle(file):
    with open(file,'rb') as f:
        dict=pickle.load(f,encoding='bytes')
    return dict

def pickle_save(file,t):
    with open(file,'wb') as f:
        dict=pickle.dump(t,f)
    return dict

# print(labellist)
def get_img(data,label):
    img = np.reshape(data, (3, 32, 32))
    img = img.transpose((1, 2, 0))
    plt.imshow(img)
    if(label==0):
        plt.title('cat' )
    else:
        plt.title('dog')
    plt.show()
def get_catdog():
    train=[]
    cat_id=3
    dog_id=5
    for i in range(5):
        # train_path=os.path.join(data_dir,train_pathname+str(i+1))
        t=unpickle(train_path+str(i + 1)+'_catdog')
        # print(t[b'labels'])
        t[b'labels']=np.array(t[b'labels'])
        index=np.where((t[b'labels']==cat_id) | (t[b'labels']==dog_id))
        # print(index)
        # t[b'labels'][(t[b'labels']==cat_id) | (t[b'labels']==dog_id)])
        t[b'labels']=t[b'labels'][index]
        t[b'labels'][t[b'labels'] == cat_id] = 0
        t[b'labels'][t[b'labels'] == dog_id] = 1
        t[b'labels']= t[b'labels'].tolist()
        t[b'data']=t[b'data'][index]
        # print(t[b'labels'].shape, t[b'data'].shape)
        # t[b'labels']=[1 if x==cat_id else 2 if x==dog_id else 0 for x in t[b'labels']]
        # print(t[b'labels'])
        # print(np.where(t[b'labels']>3 ))
        new_t = {}
        new_t['labels'] = t[b'labels']
        new_t['data'] = t[b'data']
        pickle_save(train_path+'_catdog',new_t)
        train.append(t)
    meta=unpickle(meta_path)
    test=unpickle(test_path)
    # print(t)
    # print(test)
    # labellist=meta[b'label_names']
    # get_img(test['data'].reshape(-1,3,32,32)[3],test['labels'][3])
    test[b'labels']=np.array(test[b'labels'])
    index=np.where((test[b'labels']==cat_id) | (test[b'labels']==dog_id))
    test[b'labels']=test[b'labels'][index]
    test[b'labels'][test[b'labels']==cat_id]=0
    test[b'labels'][test[b'labels']==dog_id]=1
    test[b'labels']= test[b'labels'].tolist()
    test[b'data']=test[b'data'][index]

    new_test={}
    new_test['labels']=test[b'labels']
    new_test['data']=test[b'data']
    pickle_save(test_path+'_catdog',new_test)
    print(len(test[b'labels']))
# print(test)

# print(test[b'labels'].shape,test[b'data'].shape)
# print(train[0][b'data'].shape)
# print(type(train[0][b'labels']))
# get_img(test[0]['data'].reshape(-1,3,32,32)[3],test[0]['labels'][3])
# print(Data.TensorDataset(torch.from_numpy(i[b'data'].reshape(10000,3,32,32)),torch.tensor(i[b'labels'])))
# train_loaders=[Data.DataLoader(dataset= Data.TensorDataset(torch.from_numpy(i[b'data'].reshape(-1,3,32,32)),torch.FloatTensor(i[b'labels'])),batch_size=BATCH_SIZE,shuffle=True,num_workers=0) for i in train[:-1]]
# val_loader=Data.DataLoader(dataset= Data.TensorDataset(torch.from_numpy(train[-1][b'data'].reshape(-1,3,32,32)),torch.FloatTensor(train[-1][b'labels'])),batch_size=train[-1][b'data'].shape[0],shuffle=True,num_workers=0)
# test_loader=Data.DataLoader(dataset=Data.TensorDataset(torch.from_numpy(test[b'data'].reshape(-1,3,32,32)),torch.FloatTensor(test[b'labels'])),batch_size=test[b'data'].shape[0],shuffle=True,num_workers=0)
def predict(model):
    with torch.no_grad():
        accuracy = 0.0
        l = 0.0
        test = unpickle(test_path + '_catdog')
        test_loader = Data.DataLoader(
            dataset=Data.TensorDataset(torch.from_numpy(test['data'].reshape(-1, 3, 32, 32)),
                                       torch.FloatTensor(test['labels'])), batch_size=test['data'].shape[0], shuffle=False,
            num_workers=0)
        for x, y in test_loader:
            test_output = model(x)
            # p_y = torch.argmax(test_output, -1)
            test_output = test_output.squeeze(-1)
            test_output[test_output > 0] = 1
            test_output[test_output <= 0] = 0
            p_y=test_output
            # print(pred_y.shape)
            accuracy = accuracy + float((p_y == y).sum())
            l += float(y.size(0))
        accuracy /= l
        print("test accuracy：%.4f" % accuracy)

# def get_label_data(train,label):
#     data={"data":[],"label":[]}
#     for t in train:
#         for img,l in zip(t[b'data'],t[b'labels']):
#             if(labellist[l]==label):
#
# # get_img(train[-1][b'data'][0],train[-1][b'labels'][0])
#
# get_label_data(train, b'cat')
class cifar10_classify(nn.Module):
    def __init__(self,config):
        super(cifar10_classify,self).__init__()

        def pool(x):
            if (x == 'M'):
                return nn.MaxPool2d(kernel_size=2)
            elif (x == 'A'):
                return nn.AvgPool2d(kernel_size=2)
            else:
                return nn.MaxPool2d(kernel_size=config.dim*2)

        def activate(x):
            if x == 'relu':
                return nn.ReLU()
            elif x == 'tanh':
                return nn.Tanh()

        self.convs2 = \
            nn.ModuleList([
                nn.ModuleList([
                    nn.Sequential(
                        nn.Conv2d(
                            in_channels=config.conv_struct[i - 1][-1] * len(config.kernel_size[i - 1]),
                            out_channels=config.conv_struct[i][-1],
                            kernel_size=k,
                            stride=1,
                            padding=(k - 1) // 2  # padding=(kernel_size-stride)/2
                        ),
                        activate(config.conv_struct[i][1]),
                        nn.BatchNorm2d(config.conv_struct[i][-1]),
                        pool(config.conv_struct[i][0])
                    )  # 2*2的窗口
                    for k in config.kernel_size[i]
                ])
                for i in range(1,len(config.conv_struct))
            ] )#输出为[batch,32，8,8]
        self.dropout=nn.ModuleList([nn.Dropout(i) for i in config.conv_dropout])
        # print(config.fc)
        self.fc=nn.ModuleList(
            [
                    nn.Sequential(
                        nn.Linear(config.fc[i-1],config.fc[i]),
                        activate(config.fc_act[i]),
                        nn.Dropout(config.fc_dropout[i]))
                    if i+2<len(config.fc)
                    else
                    nn.Linear(config.fc[i - 1], config.fc[i])
                for i in range(1,len(config.fc))
            ]
        )

    def forward(self,x):
        # print(x.shape)
        # print(x)

        i=0
        x=x.float()/255.
        for i,modulse in enumerate(self.convs2):
            x=[conv(x) for conv in modulse]
            # print(x.shape)
            # xs=[]
            # for conv in modulse:
            #     # print(conv)
            #     xs +=[conv(x) ]
                # print(xs[-1].shape)

            x=torch.cat(x, 1)
            x = self.dropout[i](x)

        x = x.view(x.size(0), -1)
        # print(x.shape)
        for f in self.fc:
            x=f(x)
        # x=self.dropout1(x)
        # x=self.bn1(x)
        # print(x.shape)
        # x = self.conv1(x.float()/255.)
        # x=self.conv2(x)
        # x = self.dropout2(x)
        # x = self.conv3(x)
        # x = self.conv4(x)
        # x = self.dropout3(x)

        # print(x.shape)
        # x=self.fc1(x)
        # output=self.fc2(x)
        # output=self.prediction(x)
        return x

def one_fold(opt):
    opt.time=str(now)+'_'+str(datetime.now())
    print("---------------------------------------------------------------------------------------------------------------------------")
    print(opt.string())
    print("---------------------------------------------------------------------------------------------------------------------------")
    BATCH_SIZE=opt.BATCH_SIZE
    model=cifar10_classify(opt)
    #大数据常用Adam优化器，参数需要model的参数，以及学习率
    optimizer = torch.optim.Adam(model.parameters(), opt.LR)
    scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=1, gamma=opt.gamma)
    #定义损失函数，交叉熵
    loss_func = nn.BCEWithLogitsLoss()
    val_id=opt.val_id
    max_val_acc=0.
    max_train_acc=0.
    early_stopping=opt.early_stopping
    # print(opt.EPOCH)
    for epoch in range(opt.EPOCH):
        scheduler.step()
        i=0
        for i in range(0,5):
            if(i+1==val_id):
                continue
            train = unpickle(train_path+str(i + 1)+'_catdog')
            train_loader=Data.DataLoader(dataset= Data.TensorDataset(torch.from_numpy(train['data'].reshape(-1,3,32,32)),torch.FloatTensor(train['labels'])),batch_size=BATCH_SIZE,shuffle=False,num_workers=0)
            i+=1
            total_loss=0.0
            train_accuracy=0.0
            step=0
            total_mean_F1=0.0
            for step,(batch_x,batch_y) in enumerate(train_loader):

                output = model(batch_x)
                # print(output)

                output=output.squeeze(-1)
                # print(output.shape)
                # print(batch_y.shape)
                loss = loss_func(output, batch_y)
                total_loss+=loss.data
                optimizer.zero_grad()
                loss.backward()
                optimizer.step()
                # print(output)
                output[output>0]=1
                output[output <= 0] = 0
                pred_y=output
                # print(pred_y.shape)
                # print(pred_y)
                train_accuracy=train_accuracy+ float((pred_y == batch_y).sum()) / float(batch_y.size(0))
                F1, mean_F1 = metric(batch_y.long(), pred_y.long())
                # print(F1,mean_F1)
                total_mean_F1= total_mean_F1+mean_F1
            with torch.no_grad():
                accuracy = 0.0
                l = 0.0
                val_loss=0.0
                # val_path = os.path.join(data_dir, train_pathname + str(5) + '_catdog')
                val = unpickle(train_path+str(val_id)+'_catdog')
                val_loader = Data.DataLoader(
                    dataset=Data.TensorDataset(torch.from_numpy(val['data'].reshape(-1, 3, 32, 32)),
                                               torch.FloatTensor(val['labels'])), batch_size=val['data'].shape[0], shuffle=False,
                    num_workers=0)

                for x, y in val_loader:
                    val_output = model(x)
                    val_output = val_output.squeeze(-1)
                    val_output[val_output > 0] = 1
                    val_output[val_output <= 0] = 0
                    p_y = val_output

                    # print(pred_y.shape)
                    t_loss = loss_func(val_output, y)
                    val_loss=val_loss+t_loss.data
                    accuracy = accuracy + float((p_y == y).sum())
                    F1,mean_F1=metric(y.long(), p_y.long())
                    l += float(y.size(0))
                accuracy /= l
                # print("epoch:", epoch, "| step:", step, "|val accuracy：%.4f" % accuracy)
                train_accuracy/=step
                total_mean_F1/=step
                if(train_accuracy>max_train_acc):
                    max_train_acc=train_accuracy
                if(accuracy>max_val_acc):
                    max_val_acc=accuracy
                    early_stopping = opt.early_stopping
                else:
                    early_stopping-=1
                print("| epoch:", epoch,  "| filename:",i,"| train loss:%.4f" % total_loss,
                      "|train accuracy：%.4f" % train_accuracy,"|train mean_F1：%.4f" % total_mean_F1.data, "|max val accuracy：%.4f" %  max_val_acc,"| val loss:%.4f" % val_loss, "|val accuracy：%.4f" % accuracy,"|val F1：" , F1.data,"|val mean_F1：%.4f" % mean_F1.data," |")
        if(early_stopping<=0):
            print("early_stopping")
            break
    return max_val_acc,max_train_acc
def cross_validate(opt):
    mean_acc=0.
    for i in range(0,5):
        opt.val_id=i+1
        max_acc,train_acc=one_fold(opt)
        mean_acc=mean_acc+max_acc
        opt.write_string(log_path,train_acc,max_acc,mean_acc/(i+1.))
    return mean_acc

def fc_grid(opt1):
    global now
    for i in range(1, 3):  # fc
        ll = []
        # print(opt1.string())
        opt1.change_conv()
        l = (opt1.fc[0] - opt1.fc[-1]) // i
        # print(l)
        # print(opt1.fc[0],opt1.fc[1])
        for j in range(i):
            ll.append(opt1.fc[0] - j * l)
            # print(ll)
        ll.append(opt1.fc[-1])
        opt1.fc = ll
        if(now<13):#4
            now += 1
            continue
        cross_validate(opt1)
        now += 1

def main():
    global now
    now = 38
    opt = config()
    for lr in [0.01,0.001,1e-4,1e-5]:
        opt.LR=lr
        for dropout in [0,0.2,0.5]:
            opt.conv_dropout=[dropout]*4
            for gamma in [0,0.5,0.9,1]:
                opt.gamma=gamma

    cross_validate(opt)
    # opt=config()
    # # with open(log_path, 'w', encoding='utf-8') as f:
    # #     f.write(opt.get_title())
    # kernel = [3, 5, 7]
    # pool=['M','A','G']
    #
    # # cross_validate(opt)
    # print('###########################################################################################')
    # print('实验1：前馈层的层数+多尺寸+卷积层数+不同类型的池化')
    # print('###########################################################################################')
    #
    # # opt1.fc=[opt.fc[0],opt.fc[-1]]
    # # [feature,1]
    # # cross_validate(opt1)
    # # [feature,64,1]
    # global now
    # now=0
    #
    # for k in range(2, 4):#卷积深度
    #     opt1 = config()
    #     opt1.kernel_size = opt.kernel_size[:k]
    #     opt1.conv_struct = opt.conv_struct[:k]
    #     for z in range(1, 3):  # 第一层卷积的宽度
    #         opt1.kernel_size[1] = kernel[:z]  #
    #         # print(opt1.string())
    #         if (len(opt1.conv_struct) == 3):  # pool
    #             for a in range(2):
    #                 opt1.conv_struct[1][0] = pool[a]
    #                 for b in range(3):
    #                     opt1.conv_struct[2][0] = pool[b]
    #                     fc_grid(opt1)
    #         elif (len(opt1.conv_struct) == 4):
    #             for a in range(2):
    #                 opt1.conv_struct[1][0] = pool[a]
    #                 for b in range(2):
    #                     opt1.conv_struct[2][0] = pool[b]
    #                     for c in range(3):
    #                         opt1.conv_struct[3][0] = pool[c]
    #                         fc_grid(opt1)
    #         else:
    #             for a in range(3):
    #                 opt1.conv_struct[1][0] = pool[a]
    #                 fc_grid(opt1)
    #
    #
    # print('###########################################################################################')
    # print('实验2：前馈层的层数+多尺寸+卷积层数')
    # print('###########################################################################################')
    # opt1 = config()
    # # opt1.fc=[opt.fc[0],opt.fc[-1]]
    # # [feature,1]
    # # cross_validate(opt1)
    # # [feature,64,1]
    # for i in range(1, 3):
    #     ll = []
    #     l = (opt.fc[-1] - opt.fc[0]) // i
    #     for j in range(i):
    #         ll.append(opt.fc[0] + i * l)
    #     ll.append(opt.fc[-1])
    #     opt1.fc = ll
    #     for k in range(1, 3):
    #         opt1.kernel_size = opt.kernel_size[:k]
    #         opt1.conv_struct = opt.conv_struct[:k]
    #         for z in range(1,3):
    #             opt1.kernel_size[0] = kernel[:z]
    #             cross_validate(opt1)
    #
    # print('###########################################################################################')
    # print('实验3：前馈层的层数+多尺寸+卷积层数')
    # print('###########################################################################################')
    # opt1 = config()
    # # opt1.fc=[opt.fc[0],opt.fc[-1]]
    # # [feature,1]
    # # cross_validate(opt1)
    # # [feature,64,1]
    # for i in range(1, 3):
    #     ll = []
    #     l = (opt.fc[-1] - opt.fc[0]) // i
    #     for j in range(i):
    #         ll.append(opt.fc[0] + j * l)
    #     ll.append(opt.fc[-1])
    #     opt1.fc = ll
    #     for k in range(1, 3):
    #         opt1.kernel_size[0] = kernel[:k]
    #         cross_validate(opt1)
    # print('###########################################################################################')
    # print('实验4：前馈层的层数+卷积层数')
    # print('###########################################################################################')
    # opt1 = config()
    # # opt1.fc=[opt.fc[0],opt.fc[-1]]
    # # [feature,1]
    # # cross_validate(opt1)
    # # [feature,64,1]
    # for i in range(1, 3):
    #     ll = []
    #     l = (opt.fc[-1] - opt.fc[0]) // i
    #     for j in range(i):
    #         ll.append(opt.fc[0] + j * l)
    #     ll.append(opt.fc[-1])
    #     opt1.fc = ll
    #     for k in range(1, 3):
    #         opt1.kernel_size = opt.kernel_size[:k]
    #         opt1.conv_struct = opt.conv_struct[:k]
    #         cross_validate(opt1)
    #     # cross_validate(opt1)
    # print('###########################################################################################')
    # print('实验5：前馈层的层数')
    # print('###########################################################################################')
    # opt1=config()
    # # opt1.fc=[opt.fc[0],opt.fc[-1]]
    # # [feature,1]
    # # cross_validate(opt1)
    # #[feature,64,1]
    # for i in range(1,3):
    #     ll=[]
    #     l=(opt.fc[-1]-opt.fc[0])//i
    #     for j in range(i):
    #         ll.append(opt.fc[0]+i*l)
    #     ll.append(opt.fc[-1])
    #     opt1.fc=ll
    #     cross_validate(opt1)
    # print('###########################################################################################')
    # print('实验6：卷积核层+深')
    # print('###########################################################################################')
    # # kernel = [3, 5, 7]
    # for i in range(1, 3):
    #     for j in range(1,3):
    #         opt1 = config()
    #         opt1.kernel_size = opt.kernel_size[:i]
    #         opt1.conv_struct = opt.conv_struct[:i]
    #         opt1.kernel_size[0] = kernel[:i]
    #         cross_validate(opt1)
    # ##第一个实验：卷积层数的影响
    # print('###########################################################################################')
    # print('实验7：卷积层数的影响')
    # print('###########################################################################################')
    # for i in range(1,3):
    #     opt1 = config()
    #     opt1.kernel_size=opt.kernel_size[:i]
    #     opt1.conv_struct=opt.conv_struct[:i]
    #     cross_validate(opt1)
    # print('###########################################################################################')
    # print('实验8：多尺寸卷积核的影响')
    # print('###########################################################################################')
    # for i in range(1,3):
    #     opt1 = config()
    #     opt1.kernel_size[0]=kernel[:i]
    #     cross_validate(opt1)
    # print('###########################################################################################')
    # print('实验9：不同激活层的影响')
    # print('###########################################################################################')
    # for i in range(1, 3):
    #     opt1 = config()
    #     opt1.kernel_size[0] = kernel[:i]
    #     cross_validate(opt1)

if __name__=='__main__':

    main()


import turtle
import time
import os

def draw_triangle(self):
    self.color('green')

    for i in range(4):
        self.fd(50)
        self.lt(120)
        self.begin_fill()
        for j in range(3):
            self.fd(25)
            self.lt(120)
        self.end_fill()

def draw_turtle():

    window = turtle.Screen()
    window.bgcolor('white')
    brad = turtle.Turtle()
    for a in range(3):
        brad.fd(100)
        for b in range(4):
            brad.fd(50)
            draw_triangle(brad)

draw_turtle()


#!/usr/bin/env python3

"""
Usage: ./day4-lunch.py <threshold> <ctab_file1> <ctab_file2> ... <ctab_filen>
"""

import sys
import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

threshold = int(sys.argv[1])
ctab_variable = len(sys.argv)
d_fpkm = {}

for i in range(2,(ctab_variable)):

	name1 = sys.argv[i].split(os.sep)[-2]
	fpkm = pd.read_csv(sys.argv[i], sep = "\t", index_col = "t_name").loc[:, "FPKM"]
	d_fpkm[name1] = fpkm

fpkms_df = pd.DataFrame(d_fpkm)
fpkms_df.to_csv(sys.stdout)

sum_fpkms = fpkms_df.sum(axis = 1)
with_threshold = sum_fpkms > threshold
results = sum_fpkms.index[with_threshold == True]

print(sum_fpkms)
print(with_threshold)
print(results)


#! /usr/bin/python
"""Multiplies all numeric values in a column file by a constant."""
import sys
import getopt

from .mathfamily import arithmetic as a

__all__ = ['mult_const']

def mult_const(infile, outfile, constant):
    # Multiplies all values in infile by constant and writes the result
    # to outfile.
    a.arithmetic(infile, outfile, constant, lambda x, y: x*y,
                 lambda x, y: False)

def parse_args(args):
    def help():
        print('mult_const.py -i <input file> -o <output file> -n <number>')

    infile = None
    outfile = None
    constant = None

    options = ('i:o:n:',
               ['input', 'output', 'constant'])
    readoptions = zip(['-'+c for c in options[0] if c != ':'],
                      ['--'+o for o in options[1]])

    try:
        (vals, extras) = getopt.getopt(args, *options)
    except getopt.GetoptError as e:
        print(str(e))
        help()
        sys.exit(2)

    for (option, value) in vals:
        if (option in readoptions[0]):
            infile = value
        elif (option in readoptions[1]):
            outfile = value
        elif (option in readoptions[2]):
            constant = float(value)

    if (any(val is None for val in [infile, outfile, constant])):
        help()
        sys.exit(2)

    return infile, outfile, constant

#                 PERFORM FUNCTION USING COMMAND-LINE OPTIONS                 #
if (__name__ == '__main__'):
    args = parse_args(sys.argv[1:])

    mult_const(*args)


#!/usr/bin/env python3

import pytest

from metplus.util.system_util import *

@pytest.mark.parametrize(
    'filename, expected_result', [
        # file does not exist
        ('filedoesnotexist.tcst', []),
        # file is empty
        ('empty_filter.tcst', []),
        # file has STORM_ID column with 4 values
        ('fake_filter_20141214_00.tcst', ['ML1201072014',
                                          'ML1221072014',
                                          'ML1241072014',
                                          'ML1251072014']),
        # file does not have STORM_ID column
        ('test_20190101.stat', []),
    ]
)
@pytest.mark.util
def test_get_storm_ids(metplus_config, filename, expected_result):
    config = metplus_config
    filepath = os.path.join(config.getdir('METPLUS_BASE'),
                            'internal', 'tests',
                            'data',
                            'stat_data',
                            filename)

    assert get_storms(filepath, id_only=True) == expected_result

@pytest.mark.parametrize(
    'filename, expected_result', [
        # file does not exist
        ('filedoesnotexist.tcst', []),
        # file is empty
        ('empty_filter.tcst', []),
        # file has STORM_ID column with 4 values
        ('fake_filter_20141214_00.tcst', ['header',
                                          'ML1201072014',
                                          'ML1221072014',
                                          'ML1241072014',
                                          'ML1251072014']),
        # file does not have STORM_ID column
        ('test_20190101.stat', []),
    ]
)
@pytest.mark.util
def test_get_storms(metplus_config, filename, expected_result):
    storm_id_index = 4
    config = metplus_config
    filepath = os.path.join(config.getdir('METPLUS_BASE'),
                            'internal', 'tests',
                            'data',
                            'stat_data',
                            filename)

    storm_dict = get_storms(filepath)
    print(storm_dict)
    assert list(storm_dict.keys()) == expected_result
    for storm_id in expected_result[1:]:
        for storm_line in storm_dict[storm_id]:
            # ensure storm_id_index matches storm ID
            assert storm_line.split()[storm_id_index] == storm_id

    # ensure header matches expected format
    if storm_dict:
        assert storm_dict['header'].split()[storm_id_index] == 'STORM_ID'

@pytest.mark.util
def test_get_storms_mtd(metplus_config):
    index = 23
    expected_result = [
        'header',
        'CF001',
        'CO001'
    ]
    sort_column = 'OBJECT_CAT'
    config = metplus_config
    filepath = os.path.join(config.getdir('METPLUS_BASE'),
                            'internal', 'tests',
                            'data',
                            'mtd',
                            'fake_mtd_2d.txt')

    storm_dict = get_storms(filepath, sort_column=sort_column)
    print(storm_dict)
    assert list(storm_dict.keys()) == expected_result
    for storm_id in expected_result[1:]:
        for storm_line in storm_dict[storm_id]:
            # ensure index matches storm ID
            assert storm_line.split()[index] == storm_id

    # ensure header matches expected format
    if storm_dict:
        assert storm_dict['header'].split()[index] == sort_column

@pytest.mark.parametrize(
    'filename, ext', [
        ('internal/tests/data/zip/testfile.txt', '.gz'),
        ('internal/tests/data/zip/testfile2.txt', '.bz2'),
        ('internal/tests/data/zip/testfile3.txt', '.zip'),
        ('internal/tests/data/zip/testfile4.txt', ''),
    ]
)
@pytest.mark.util
def test_preprocess_file_stage(metplus_config, filename, ext):
    conf = metplus_config
    metplus_base = conf.getdir('METPLUS_BASE')
    stage_dir = conf.getdir('STAGING_DIR',
                            os.path.join(conf.getdir('OUTPUT_BASE'),
                                         'stage'))
    filepath = os.path.join(metplus_base,
                            filename+ext)
    if ext:
        stagepath = stage_dir + os.path.join(metplus_base,
                                             filename)
        if os.path.exists(stagepath):
            os.remove(stagepath)
    else:
        stagepath = filepath

    outpath = preprocess_file(filepath, None, conf)
    assert stagepath == outpath and os.path.exists(outpath)

@pytest.mark.parametrize(
    'filename, data_type, allow_dir, expected', [
        # filename is None or empty string - return None
        (None, None, False, None),
        ('', None, False, None),
        # python data types - pass through full filename value
        ('some:set:of:words', 'PYTHON_NUMPY', False, 'some:set:of:words'),
        ('some:set:of:words', 'PYTHON_XARRAY', False, 'some:set:of:words'),
        ('some:set:of:words', 'PYTHON_PANDAS', False, 'some:set:of:words'),
        # allow directory - pass through full dir path
        ('dir', None, True, 'dir'),
        # base filename is python embedding type - return python embed type
        ('/some/path/PYTHON_NUMPY', None, False, 'PYTHON_NUMPY'),
        ('/some/path/PYTHON_XARRAY', None, False, 'PYTHON_XARRAY'),
        ('/some/path/PYTHON_PANDAS', None, False, 'PYTHON_PANDAS'),
    ]
)
@pytest.mark.util
def test_preprocess_file_options(metplus_config,
                                 filename,
                                 data_type,
                                 allow_dir,
                                 expected):
    config = metplus_config
    if filename == 'dir':
        filename = config.getdir('METPLUS_BASE')
        expected = filename
    result = preprocess_file(filename, data_type, config, allow_dir)
    assert result == expected


from datetime import timedelta

from django.core.management.base import BaseCommand
from django.utils.timezone import now
from social_django.models import UserSocialAuth

from drchrono.endpoints import (
    PatientEndpoint,
    AppointmentEndpoint,
)
from drchrono.forms.webhook import WebhookPatientForm, WebhookAppointmentForm

class Command(BaseCommand):
    def handle(self, *args, **options):
        access_token = UserSocialAuth.objects.first().extra_data['access_token']
        self.load_patients(access_token)
        self.load_appointments(access_token)

    def load_patients(self, access_token):
        patient_endpoint = PatientEndpoint(access_token)
        patients = patient_endpoint.list()
        for data in patients:
            form = WebhookPatientForm(data=data)
            print(form)
            if form.is_valid():
                form.save()
            else:
                print(form.errors)

    def load_appointments(self, access_token):
        api = AppointmentEndpoint(access_token)
        start = (now() - timedelta(days=1)).day
        end = (now() + timedelta(days=1)).day
        appointments = api.list(start=start, end=end)

        for data in appointments:
            form = WebhookAppointmentForm(data=data)
            print(form)
            if form.is_valid():
                form.save()
            else:
                print(form.errors)


from django.urls import path, include
from products.api.views import (
    StoreProductCreateAPIView,
    StoreProductUpdateAPIView,
    StoreProductStatusUpdateAPIView
)

app_name = 'api_product'

urlpatterns = [
    path('owner/store/', include([
        path('products/<int:list>/', StoreProductCreateAPIView.as_view()),
        path('product/<uuid:product_id>/',
             StoreProductUpdateAPIView.as_view(),
             name="product_detail_api_view"),
        path('product/status/<uuid:product_id>/',
             StoreProductStatusUpdateAPIView.as_view(),
             name="product_status_detail_api_view")
    ]))
]


#!/usr/bin/env python
import rospy
from geometry_msgs.msg import PointStamped
from sawyer_control.srv import *

def set_target_to(point):
    rospy.wait_for_service('set_target')
    try:
        execute_action = rospy.ServiceProxy('set_target',set_target,persistent=True)
        ret = execute_action(point)

        return ret.data
    except rospy.ServiceException as e:
        print(e)

if __name__ == "__main__":
    point = [1.0,1.0,0.0]
    print(set_target_to(point))


import flask
from flask import session
from smtplib import SMTP
from flask import Flask, Blueprint, render_template, request, Response, redirect, url_for, jsonify
from app.api.models import datasets, UserModel, _runSql
import numpy

module = Blueprint('dataset_search', __name__)

@module.route("/samples_grid", methods=['GET', 'POST'])
def samples_grid():
    data = request.get_json()
    dataset_id = data['dataset_id']
    ds = datasets.Dataset(dataset_id)
    sampleTable = ds.sampleTable()
    jsonSampleTable = sampleTable.to_json(orient="split")

    if session["loggedIn"] == True:
        if jsonSampleTable != None:
            return jsonSampleTable
        else:
            return {"Message": "No samples found for dataset_id: " + dataset_id}
    else:
        return "Access Denied"

@module.route("/atlas_samples_grid", methods=['GET', 'POST'])
def atlas_samples_grid():

    data = request.get_json()
    atlas_type = data['atlas_type']
    atlas_model = atlas_type['atlas_model']
    atlas_project = atlas_type['tierModel']
    update_column = atlas_model + '_' + atlas_project
    dataset_id = data['dataset_id']
    ds = datasets.Dataset(dataset_id)
    atlasSampleTable = ds.atlasSampleTable()

    newdf = atlasSampleTable[['sample_id'] + [update_column] + ['annotator', 'evidence', 'phenotype', 'activation_status', 'display_metadata', 'include_blood', 'include_imac'] ]    # construct a dataframe with the selected tier included in it.

    include_blood = newdf['include_blood'].unique()
    include_imac = newdf['include_imac'].unique()

    if include_blood[0] == False:
        print("drop all blood tier data")

        # finaldf = atlasSampleTable[['sample_id'] + [update_column] + ['annotator', 'evidence', 'phenotype', 'activation_status', 'display_metadata', 'include_blood', 'include_imac'] ]

    elif include_imac[0] == False:
        print("drop all imac tier data")

    elif include_blood[0] and include_imac[0] == False:
        print("drop all tier data")

    elif include_blood[0] and include_imac[0] == True:
        print("include all tier data")

    jsonSampleTable = newdf.to_json(orient="split")

    if session["loggedIn"] == True:
        return jsonSampleTable
    else:
        return "Access Denied"


#!/usr/bin/python
# -*- coding: utf-8 -*-
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.properties import ObjectProperty
from kivy.utils import get_color_from_hex
from hebrew_management import HebrewManagement
from kivy_communication.logged_widgets import *
from kivy.storage.jsonstore import JsonStore
from kivy.uix.screenmanager import Screen

class ConsentScreen(Screen):

    def add_widget(self, widget, index=0):
        super(Screen, self).add_widget(widget, index)

class ConsentCheckBox(LoggedCheckBox):
    the_form = None

    def on_press(self, *args):
        super(ConsentCheckBox, self).on_press(*args)
        if self.the_form:
            self.the_form.mark_checkbox()

class ConsentButton(LoggedButton):
    the_form = None

    def on_press(self, *args):
        super(ConsentButton, self).on_press(*args)
        if self.the_form:
            self.the_form.contin()

class ConsentForm(BoxLayout):
    title=ObjectProperty()
    body=ObjectProperty()
    checkbox_agree=ObjectProperty()
    checkbox_txt=ObjectProperty()
    button=ObjectProperty()
    the_app = None
    dict = None
    body_labels = None

    def __init__(self, the_app):
        super(ConsentForm, self).__init__()
        self.the_app = the_app
        self.dict = {'title':self.title,
                'body':self.body,
                'checkbox_txt':self.checkbox_txt,
                'button':self.button}
        store = JsonStore('consent_form.json').get('agreement')
        for key, value in store.items():
            self.dict[key].text = value[::-1]

        self.body_labels = []
        txt = self.dict['body'].text
        new_lines = HebrewManagement.multiline(txt, 50)
        for nl in new_lines[::-1]:
            self.body_labels.append(Label(text=nl,
                      font_name="fonts/the_font",
                      font_size=36,
                      color=[0,0,0,1]))
            self.dict['body'].add_widget(self.body_labels[-1])

    def start(self, the_app):
        self.button.disabled = True
        self.checkbox_agree.active = False
        self.button.background_color = (0, 0.71, 1, 1)
        for l in self.dict['body'].children:
            l.font_size = int(36.0 * float(self.the_app.sm.size[0]) / float(self.the_app.original_size[0]))

    def contin(self):
        if self.checkbox_agree.active:
            self.the_app.sm.current = self.the_app.sm.next()
        else:
            print("pls mark checkbox")

    def mark_checkbox(self):
        if self.checkbox_agree.active:
            self.button.background_color = (0, 0.71, 1, 1)
            # self.button.background_color = (0.71, 0, 1., 1)
            self.button.disabled = False
        else:
            self.button.disabled = True

    def get_color_from_hex(self, color):
        return get_color_from_hex(color)


import tensorflow as tf

def trim_zeros_graph(boxes, name='trim_zeros'):
    """Often boxes are represented with matrices of shape [N, IMAGE_SOURCES?, 4] and
    are padded with zeros. This removes zero boxes.

    boxes: [N, 4] matrix of boxes.
    non_zeros: [N] a 1D boolean mask identifying the rows to keep
    """
    master_boxes = boxes
    if len(boxes.shape) == 3:
        master_boxes = boxes[:, 0, :]
    non_zeros = tf.cast(tf.reduce_sum(tf.abs(master_boxes), axis=1), tf.bool)
    boxes = tf.boolean_mask(boxes, non_zeros, name=name)
    return boxes, non_zeros

def batch_pack_graph(x, counts, num_rows):
    """Picks different number of values from each row
    in x depending on the values in counts.
    """
    outputs = []
    for i in range(num_rows):
        outputs.append(x[i, :counts[i]])
    return tf.concat(outputs, axis=0)

def norm_boxes_graph(boxes, shape):
    """Converts boxes from pixel coordinates to normalized coordinates.
    boxes: [..., (y1, x1, y2, x2)] in pixel coordinates
    shape: [..., (height, width)] in pixels

    Note: In pixel coordinates (y2, x2) is outside the box. But in normalized
    coordinates it's inside the box.

    Returns:
        [..., (y1, x1, y2, x2)] in normalized coordinates
    """
    h, w = tf.split(tf.cast(shape, tf.float32), 2)
    scale = tf.concat([h, w, h, w], axis=-1) - tf.constant(1.0)
    shift = tf.constant([0., 0., 1., 1.])
    return tf.divide(boxes - shift, scale)

def denorm_boxes_graph(boxes, shape):
    """Converts boxes from normalized coordinates to pixel coordinates.
    boxes: [..., (y1, x1, y2, x2)] in normalized coordinates
    shape: [..., (height, width)] in pixels

    Note: In pixel coordinates (y2, x2) is outside the box. But in normalized
    coordinates it's inside the box.

    Returns:
        [..., (y1, x1, y2, x2)] in pixel coordinates
    """
    h, w = tf.split(tf.cast(shape, tf.float32), 2)
    scale = tf.concat([h, w, h, w], axis=-1) - tf.constant(1.0)
    shift = tf.constant([0., 0., 1., 1.])
    return tf.cast(tf.round(tf.multiply(boxes, scale) + shift), tf.int32)

def parse_image_meta_graph(meta):
    """Parses a tensor that contains image attributes to its components.
    See compose_image_meta() for more details.

    meta: [batch, meta length] where meta length depends on NUM_CLASSES

    Returns a dict of the parsed tensors.
    """
    image_id = meta[:, 0]
    original_image_shape = meta[:, 1:4]
    image_shape = meta[:, 4:7]
    window = meta[:, 7:11]  # (y1, x1, y2, x2) window of image in in pixels
    scale = meta[:, 11]
    return {
        "image_id": image_id,
        "original_image_shape": original_image_shape,
        "image_shape": image_shape,
        "window": window,
        "scale": scale
    }

def box_refinement_graph(box, gt_box):
    """Compute refinement needed to transform box to gt_box.
    box and gt_box are [N, (y1, x1, y2, x2)]
    """
    box = tf.cast(box, tf.float32)
    gt_box = tf.cast(gt_box, tf.float32)

    height = box[:, 2] - box[:, 0]
    width = box[:, 3] - box[:, 1]
    center_y = box[:, 0] + 0.5 * height
    center_x = box[:, 1] + 0.5 * width

    gt_height = gt_box[:, 2] - gt_box[:, 0]
    gt_width = gt_box[:, 3] - gt_box[:, 1]
    gt_center_y = gt_box[:, 0] + 0.5 * gt_height
    gt_center_x = gt_box[:, 1] + 0.5 * gt_width

    dy = (gt_center_y - center_y) / height
    dx = (gt_center_x - center_x) / width
    dh = tf.log(gt_height / height)
    dw = tf.log(gt_width / width)

    result = tf.stack([dy, dx, dh, dw], axis=1)
    return result

def apply_box_deltas_graph(boxes, deltas):
    """Applies the given deltas to the given boxes.
    boxes: [N, (y1, x1, y2, x2)] boxes to update
    deltas: [N, IMAGE_SOURCES, (dy, dx, log(dh), log(dw))] refinements to apply
    """
    # Convert to y, x, h, w
    height = (boxes[:, 2] - boxes[:, 0])[:, None]
    width = (boxes[:, 3] - boxes[:, 1])[:, None]
    center_y = boxes[:, 0:1] + 0.5 * height
    center_x = boxes[:, 1:2] + 0.5 * width
    # Apply deltas
    cy = center_y + deltas[:, :, 0] * height # [N, IMAGE_SOURCES]
    cx = center_x + deltas[:, :, 1] * width # [N, IMAGE_SOURCES]
    ch = height * tf.exp(deltas[:, :, 2])
    cw = width * tf.exp(deltas[:, :, 3])
    # Convert back to y1, x1, y2, x2
    y1 = cy - 0.5 * ch
    x1 = cx - 0.5 * cw
    y2 = y1 + ch
    x2 = x1 + cw
    result = tf.stack([y1, x1, y2, x2], axis=2, name="apply_box_deltas_out")
    return result

def clip_boxes_graph(boxes, window):
    """
    boxes: [N, IMAGE_SOURCES, (y1, x1, y2, x2)]
    window: [4] in the form y1, x1, y2, x2
    """
    n = boxes.shape[0]
    n_image_sources = boxes.shape[1]
    # Split
    wy1, wx1, wy2, wx2 = tf.split(window, 4)
    y1, x1, y2, x2 = tf.split(boxes, 4, axis=2)
    # Clip
    y1 = tf.maximum(tf.minimum(y1, wy2), wy1)
    x1 = tf.maximum(tf.minimum(x1, wx2), wx1)
    y2 = tf.maximum(tf.minimum(y2, wy2), wy1)
    x2 = tf.maximum(tf.minimum(x2, wx2), wx1)
    clipped = tf.concat([y1, x1, y2, x2], axis=2, name="clipped_boxes")
    clipped.set_shape((n, n_image_sources, 4))
    return clipped

# ## Batch Slicing
# Some custom layers support a batch size of 1 only, and require a lot of work
# to support batches greater than 1. This function slices an input tensor
# across the batch dimension and feeds batches of size 1. Effectively,
# an easy way to support batches > 1 quickly with little code modification.
# In the long run, it's more efficient to modify the code to support large
# batches and getting rid of this function. Consider this a temporary solution
def batch_slice(inputs, graph_fn, batch_size, names=None, constants=[]):
    """Splits inputs into slices and feeds each slice to a copy of the given
    computation graph and then combines the results. It allows you to run a
    graph on a batch of inputs even if the graph is written to support one
    instance only.

    inputs: list of tensors. All must have the same first dimension length
    graph_fn: A function that returns a TF tensor that's part of a graph.
    batch_size: number of slices to divide the data into.
    names: If provided, assigns names to the resulting tensors.
    """
    if not isinstance(inputs, list):
        inputs = [inputs]

    outputs = []
    for i in range(batch_size):
        inputs_slice = [x[i] for x in inputs] + constants
        output_slice = graph_fn(*inputs_slice)
        if not isinstance(output_slice, (tuple, list)):
            output_slice = [output_slice]
        outputs.append(output_slice)
    # Change outputs from a list of slices where each is
    # a list of outputs to a list of outputs and each has
    # a list of slices
    outputs = list(zip(*outputs))

    if names is None:
        names = [None] * len(outputs)

    result = [tf.stack(o, axis=0, name=n)
              for o, n in zip(outputs, names)]
    if len(result) == 1:
        result = result[0]

    return result


"""
Ask the user for their name
Tell them how many vowels are in their name
Example output

Name: Bobby McAardvark
Out of 16 letters, Bobby McAardvark has 4 vowels

Use the str.format() method for the last print.
"""

name = input("Enter a name:")
number_of_vowels = 0
for letter in name:
    if letter.lower() in 'aeiou':
        number_of_vowels += 1
print("Out of {} letters, {} has {} vowels".format(len(name), name, number_of_vowels))


##############################################################################
# Copyright 2016-2017 Rigetti Computing
#
#    Licensed under the Apache License, Version 2.0 (the "License");
#    you may not use this file except in compliance with the License.
#    You may obtain a copy of the License at
#
#        http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.
##############################################################################
"""Module for Grover's algorithm.
"""

import numpy as np
import pyquil.quil as pq
from pyquil.gates import H
from pyquil.quilbase import Qubit

from grove.amplification.amplification import amplification_circuit

class Grover(object):
    """This class contains an implementation of Grover's algorithm using pyQuil. See `these notes`_
     by Dave Bacon for more information.

    .. _these notes: https://courses.cs.washington.edu/courses/cse599d/06wi/lecturenotes12.pdf
    """
    def __init__(self):
        self.unitary_function_mapping = None
        self.n_qubits = None
        self.qubits = None
        self.grover_circuit = None
        self.bit_map = None

    @staticmethod
    def _compute_grover_oracle_matrix(bitstring_map):
        """Computes the unitary matrix that encodes the oracle function for Grover's algorithm

        :param bitstring_map: dict with string keys corresponding to bitstrings,
         and integer values corresponding to the desired phase on the output state.
        :type bitstring_map: Dict[String, Int]
        :return: a numpy array corresponding to the unitary matrix for oracle for the given
         bitstring_map
        :rtype: numpy.ndarray
        """
        n_bits = len(list(bitstring_map.keys())[0])
        oracle_matrix = np.zeros(shape=(2 ** n_bits, 2 ** n_bits))
        for b in range(2 ** n_bits):
            pad_str = np.binary_repr(b, n_bits)
            phase_factor = bitstring_map[pad_str]
            oracle_matrix[b, b] = phase_factor
        return oracle_matrix

    def _construct_grover_circuit(self):
        """Contructs an instance of Grover's Algorithm, using initialized values.

        :return: None
        :rtype: NoneType
        """
        oracle = pq.Program()
        oracle_name = "GROVER_ORACLE"
        oracle.defgate(oracle_name, self.unitary_function_mapping)
        oracle.inst(tuple([oracle_name] + self.qubits))
        self.grover_circuit = self.oracle_grover(oracle, self.qubits)

    def _init_attr(self, bitstring_map):
        """Initializes an instance of Grover's Algorithm given a bitstring_map.

        :param bitstring_map: dict with string keys corresponding to bitstrings, and integer
         values corresponding to the desired phase on the output state.
        :type bitstring_map: Dict[String, Int]
        :return: None
        :rtype: NoneType
        """
        self.bit_map = bitstring_map
        self.unitary_function_mapping = self._compute_grover_oracle_matrix(bitstring_map)
        self.n_qubits = self.unitary_function_mapping.shape[0]
        self.qubits = list(range(int(np.log2(self.n_qubits))))
        self._construct_grover_circuit()

    def find_bitstring(self, cxn, bitstring_map):
        """
        Runs Grover's Algorithm to find the bitstring that is designated by ``bistring_map``.

        In particular, this will prepare an initial state in the uniform superposition over all bit-
        strings, an then use Grover's Algorithm to pick out the desired bitstring.

        :param JobConnection cxn: the connection to the Rigetti cloud to run pyQuil programs.
        :param bitstring_map: a mapping from bitstrings to the phases that the oracle should impart
            on them. If the oracle should "look" for a bitstring, it should have a ``-1``, otherwise
            it should have a ``1``.
        :type bitstring_map: Dict[String, Int]
        :return: Returns the bitstring resulting from measurement after Grover's Algorithm.
        :rtype: str
        """
        self._init_attr(bitstring_map)
        sampled_bitstring = cxn.run_and_measure(self.grover_circuit, self.qubits)[0]
        return ''.join([str(b) for b in sampled_bitstring])

    @staticmethod
    def oracle_grover(oracle, qubits, num_iter=None):
        r"""Implementation of Grover's Algorithm for a given oracle.

        :param Program oracle: An oracle defined as a Program. It should send :math:`\ket{x}`
            to :math:`(-1)^{f(x)}\ket{x}`, where the range of f is {0, 1}.
        :param qubits: List of qubits for Grover's Algorithm.
        :type qubits: list[int or Qubit]
        :param int num_iter: The number of iterations to repeat the algorithm for.
                             The default is the integer closest to :math:`\frac{\pi}{4}\sqrt{N}`,
                             where :math:`N` is the size of the domain.
        :return: A program corresponding to the desired instance of Grover's Algorithm.
        :rtype: Program
        """
        if num_iter is None:
            num_iter = int(round(np.pi * 2 ** (len(qubits) / 2.0 - 2.0)))
        uniform_superimposer = pq.Program().inst([H(qubit) for qubit in qubits])
        amp_prog = amplification_circuit(uniform_superimposer, oracle, qubits, num_iter)
        return amp_prog


# Create a program that lets the user input an integer, lets call it size. This integer should
# denote the size of a list. Next you should let the user input size many values to a list. Next the
# program should print the highest value in the list.
# You can solve this with built in functions but I recommend trying to solve this without using
# builtin functions as well (excluding .append())

def input_size():
    size=int(input('Enter size: '))
    return size

def input_values(input_size):
    value_list=[]
    for i in range(0,input_size):
        value=int(input('Enter a value: '))
        value_list.append(value)
    return value_list

def highest_value(value_list):
    highest=0
    for value in value_list:
        if value>highest:
            highest=value
    return highest

size=input_size()
value_list=input_values(size)
highest=highest_value(value_list)
print('The highest value is',highest)