import os
import re
import sys
import shutil
import subprocess
from argparse import ArgumentParser

_SUPPORT_OS = ['android', 'ios', 'macosx', 'windows']
_SUPPORT_ARCHES_ANDROID = ['all', 'armeabi-v7a', 'arm64-v8a']
_SUPPORT_ARCHES_IOS = ['all', 'arm64', 'x86_64']
_SUPPORT_ARCHES_MAC = ['x86_64']

# 编译变量
_BUILD_OS: str = ''
_BUILD_ARCH: str = ''
_BUILD_ARCCHES: list = []
_IS_REBUILD: bool = False

_LIB_NAME = 'voltron_core'
_ORIGIN_PATH: str = os.path.abspath(os.path.dirname(__file__))
_SRC_TOP_PATH: str = os.path.join(_ORIGIN_PATH, '../core')
_CMAKE_PATH: str = os.path.join(_SRC_TOP_PATH)
_OUTPUT_DIR: str = os.path.join(_ORIGIN_PATH, '../build')
_IOS_FRAMEWORK_DIR: str = os.path.join(_ORIGIN_PATH, '../ios')

def main():
    parser = ArgumentParser(description='Build the crossing lib for android|ios|macosx')
    parser.add_argument('-os', metavar='os', type=str, help='Select one of android|ios|macosx',
                        choices=_SUPPORT_OS, required=True)
    parser.add_argument('-arch', metavar='arch', type=str, help='''
        Specify the CPU architecture.
        For Android, available architectures are: all, x86, armeabi-v7a, arm64-v8a.
        For iOS, available architectures are: all, armv7, armv7s, arm64, i386, x86_64, mac_catalyst_x86_64.
        When you specify all, libraries for all the architectures will be built, and then combined into a fat library.
        For MacOSX, you don't need to specify it. It's default to x86_64.
    ''', default='', required=False)
    parser.add_argument('-rebuild', action='store_true', help='Clean before building',
                        required=False)
    args = parser.parse_args()
    check_args(args)
    check_env(args)
    start_build(args)

def start_build(args):
    print_info('start build, args: {}'.format(args))
    if args.arch == 'all':
        if args.os == 'android':
            _BUILD_ARCCHES.extend(['armeabi-v7a', 'arm64-v8a'])
        elif args.os == 'ios':
            _BUILD_ARCCHES.extend(['arm64', 'x86_64'])
    else:
        _BUILD_ARCCHES.append(args.arch)

    # 创建输出目录
    if os.path.exists(_OUTPUT_DIR) is False:
        os.makedirs(_OUTPUT_DIR)

    if _BUILD_OS == 'android':
        build_android(args)
    elif _BUILD_OS == 'ios':
        build_ios(args)
    elif _BUILD_OS == 'macosx':
        build_macosx(args)
    else:
        print_error('Unknown target os: {}'.format(build_ios), True)
    pass

def build_android(args):
    project_dir = os.path.abspath('../example/android')
    subprocess.run([f'{project_dir}/gradlew', 'clean'],
                   stdout=sys.stdout, stderr=sys.stderr, cwd=project_dir,
                   check=True)
    subprocess.run([f'{project_dir}/gradlew', 'build'],
                   stdout=sys.stdout, stderr=sys.stderr, cwd=project_dir,
                   check=True)

def build_ios(args):
    lib_output_dir_base = os.path.join(_OUTPUT_DIR, _BUILD_OS)
    for arch in _BUILD_ARCCHES:
        cmake_build_dir = os.path.join(_OUTPUT_DIR, 'CMakeOutput/{}/{}'.format(_BUILD_OS, arch))
        if _IS_REBUILD:
            shutil.rmtree(cmake_build_dir, ignore_errors=True)
        os.makedirs(cmake_build_dir, exist_ok=True)

        lib_output_dir = os.path.join(lib_output_dir_base, arch)
        os.makedirs(lib_output_dir, exist_ok=True)
        cmake_args = f'-H{_CMAKE_PATH} ' \
                     f'-B{cmake_build_dir} ' \
                     '-G\"Xcode\" ' \
                     '-DCMAKE_SYSTEM_NAME=iOS ' \
                     '-DV8_WITHOUT_INSPECTOR=1 ' \
                     '-DENABLE_INSPECTOR=1 ' \
                     f'-DCMAKE_TOOLCHAIN_FILE={_ORIGIN_PATH}/ios.toolchain.cmake ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET=12.0 ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_VALID_ARCHS=\"armv7 arm64 x86_64\" ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC=YES ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE=NO ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_WEAK=YES ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS=YES ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_DEPLOYMENT_POSTPROCESSING=NO ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_STRIP_INSTALLED_PRODUCT=NO ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_DEFINES_MODULE=YES ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_DYLIB_COMPATIBILITY_VERSION=1 ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_DYLIB_CURRENT_VERSION=1 ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION=1 ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_SKIP_INSTALL=YES ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER=com.tencent.VoltronCore ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_DYLIB_INSTALL_NAME_BASE=@rpath ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS=' \
                     '\"@executable_path/../Frameworks @loader_path/Frameworks\" ' \
                     f'-DCMAKE_XCODE_ATTRIBUTE_GCC_PREFIX_HEADER={_ORIGIN_PATH}' \
                     f'/../VoltronCore/VoltronCore/PrefixHeader.pch ' \
                     '-DCMAKE_XCODE_LINK_BUILD_PHASE_MODE=BUILT_ONLY ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_STRIP_STYLE=\"Debugging Symbols\" ' \
                     f'-DENABLED_UNIT_TEST=OFF ' \
                     f'-DCMAKE_LIBRARY_NAME={_LIB_NAME} '
        check_result(os.system(f'cmake {cmake_args}'))
        os.chdir(cmake_build_dir)
        sdk = 'iphoneos'
        if arch == 'x86_64':
            sdk = 'iphonesimulator'
        check_result(os.system(f'xcodebuild '
                               f'-target {_LIB_NAME} '
                               f'-configuration RelWithDebInfo -arch {arch} '
                               f'-sdk {sdk} CONFIGURATION_BUILD_DIR={lib_output_dir}'))
    # 合并为xcframework
    os.chdir(lib_output_dir_base)
    os.system(f'rm -rf {lib_output_dir_base}/{_LIB_NAME}.xcframework ')
    frameworks = ''
    for arch in _BUILD_ARCCHES:
        lib_output_dir = os.path.join(lib_output_dir_base, arch)
        frameworks += f' -framework {lib_output_dir}/{_LIB_NAME}.framework '
    check_result(os.system(f'xcodebuild -create-xcframework '
                           f'{frameworks} '
                           f'-output {lib_output_dir_base}/{_LIB_NAME}.xcframework '))

    dstdir = os.path.join(_IOS_FRAMEWORK_DIR, '{}.xcframework'.format(_LIB_NAME))
    if os.path.exists(dstdir) is True:
      shutil.rmtree(dstdir)
    shutil.copytree(os.path.join(lib_output_dir_base, '{}.xcframework'.format(_LIB_NAME)), dstdir, symlinks=True)

def build_macosx(args):
    lib_output_dir_base = os.path.join(_OUTPUT_DIR, _BUILD_OS)
    for arch in _BUILD_ARCCHES:
        cmake_build_dir = os.path.join(_OUTPUT_DIR, 'CMakeOutput/{}/{}'.format(_BUILD_OS, arch))
        if _IS_REBUILD:
            shutil.rmtree(cmake_build_dir, ignore_errors=True)
        os.makedirs(cmake_build_dir, exist_ok=True)

        lib_output_dir = os.path.join(lib_output_dir_base, arch)
        os.makedirs(lib_output_dir, exist_ok=True)
        cmake_args = f'-H{_CMAKE_PATH} ' \
                     f'-B{cmake_build_dir} ' \
                     '-G\"Xcode\" ' \
                     '-DCMAKE_SYSTEM_NAME=Darwin ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET=10.15 ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC=YES ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_WEAK=YES ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS=YES ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_DEPLOYMENT_POSTPROCESSING=NO ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_STRIP_INSTALLED_PRODUCT=NO ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_DEFINES_MODULE=YES ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_DYLIB_COMPATIBILITY_VERSION=1 ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_DYLIB_CURRENT_VERSION=1 ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION=1 ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_SKIP_INSTALL=YES ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER=' \
                     'com.tencent.VoltronCore ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_DYLIB_INSTALL_NAME_BASE=@rpath ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS=' \
                     '\"@executable_path/../Frameworks @loader_path/Frameworks\" ' \
                     f'-DCMAKE_XCODE_ATTRIBUTE_GCC_PREFIX_HEADER={_ORIGIN_PATH}' \
                     f'/../VoltronCore/VoltronCore/PrefixHeader.pch ' \
                     '-DCMAKE_XCODE_LINK_BUILD_PHASE_MODE=BUILT_ONLY ' \
                     '-DCMAKE_XCODE_ATTRIBUTE_STRIP_STYLE=\"Debugging Symbols\" ' \
                     f'-DCMAKE_LIBRARY_NAME={_LIB_NAME} '
        print(f'cmake_args: ${cmake_args}')
        check_result(os.system(f'cmake {cmake_args}'))
        os.chdir(cmake_build_dir)
        configuration = 'RelWithDebInfo'
        check_result(os.system(f'xcodebuild '
                               f'-target {_LIB_NAME} '
                               f'-configuration {configuration} '
                               '-sdk macosx'))
        subdir = _LIB_NAME + '.framework'
        dstdir = os.path.join(lib_output_dir, subdir)
        if os.path.exists(dstdir) is True:
            shutil.rmtree(dstdir)
        shutil.copytree(os.path.join(cmake_build_dir, configuration, subdir), dstdir, symlinks=True)

def check_env(args):
    if not shutil.which('cmake'):
        print_error('Could not find cmake! Please check your env!', True)
    if args.os == 'android':
        if 'ANDROID_NDK_HOME' not in os.environ:
            print_error('ANDROID_NDK_HOME env not set!', True)
        if 'ANDROID_HOME' not in os.environ:
            print_error('ANDROID_HOME env not set! Ignore build aar library!')
        if 'JAVA_HOME' not in os.environ:
            print_error('JAVA_HOME env not set! Ignore build aar library!')

def check_args(args):
    global _BUILD_OS, _BUILD_ARCH, _IS_REBUILD
    _IS_REBUILD = args.rebuild
    _BUILD_OS = args.os
    _BUILD_ARCH = args.arch
    # check os
    if args.os not in _SUPPORT_OS:
        print_error('args: os is invalid! Must be one of: {}'.format(str(_SUPPORT_OS)))
    # check arch
    if args.os == 'android':
        support_arches = _SUPPORT_ARCHES_ANDROID
    elif args.os == 'ios':
        support_arches = _SUPPORT_ARCHES_IOS
    else:
        if args.arch == '':
            args.arch = 'x86_64'
        support_arches = _SUPPORT_ARCHES_MAC
    if args.arch not in support_arches:
        print_error("args: arch is invalid! Must be one of: {} on {} platform."
                    .format(str(support_arches), args.os), True)

def print_info(info):
    print("\033[1;32m{}\033[0m".format(info))

def print_error(error, exit_build=False):
    print("\033[1;31m{}\033[0m".format(error))
    if exit_build:
        exit(1)

def check_result(status_code):
    if status_code != 0:
        print_error('Check result failed!', True)

if __name__ == '__main__':
    main()


from progressbar import ProgressBar, Percentage, Bar, Timer

class AdaptiveETA(Timer):
    """
    """
    TIME_SENSITIVE = True
    NUM_SAMPLES = 20

    def _update_samples(self, currval, elapsed):
        sample = (currval, elapsed)
        if not hasattr(self, 'samples'):
            self.samples = [sample] * (self.NUM_SAMPLES + 1)
        else:
            self.samples.append(sample)
        return self.samples.pop(0)

    def _eta(self, maxval, currval, elapsed):
        return elapsed * maxval / float(currval) - elapsed

    def update(self, pbar):
        """
        """
        if pbar.currval == 0:
            return 'ETA: --:--:--'
        elif pbar.finished:
            return 'Time: %s' % self.format_time(pbar.seconds_elapsed)
        else:
            elapsed = pbar.seconds_elapsed
            currval1, elapsed1 = self._update_samples(pbar.currval, elapsed)
            eta = self._eta(pbar.maxval, pbar.currval, elapsed)
            if pbar.currval > currval1:
                etasamp = self._eta(pbar.maxval - currval1, pbar.currval -
                        currval1, elapsed - elapsed1)
                weight = (pbar.currval / float(pbar.maxval)) ** 0.5
                eta = (1 - weight) * eta + weight * etasamp
            return 'ETA: %s' %  self.format_time(eta)

ophaal_progress = ProgressBar(widgets=['Opgehaald: ', Percentage(), ' ', Bar(),
    ' ', AdaptiveETA()])


# -*- coding: utf-8 -*-
"""
Created on Sun May 10 22:21:36 2020

@author: TheKa
"""

n = int(input())
roses = list(map(int,input().strip().split(" ")))
sequences = []
seqence = 1
for i in range(1,n):
    if roses[i]>roses[i-1]:
        seqence+=1
    else:
        sequences.append(seqence)
        seqence=1
max_smell = max(sequences)
for i in range(2,len(sequences)):
    if sequences[i-1]==1 and sequences[i]+sequences[i-2]>max_smell:
        max_smell = sequences[i]+sequences[i-2]
print(max_smell)


import numpy as np
import tensorflow as tf
import util

DTYPE = "float64"
tf.keras.backend.set_floatx(DTYPE)
if DTYPE == "float64":
    NP_DTYPE = np.float64
elif DTYPE == "float32":
    NP_DTYPE = np.float32
else:
    raise ValueError("Unknown dtype.")

class ValueTrainer():
    def __init__(self, config):
        self.config = config
        self.value_config = config["value_config"]
        d_in = config["n_basic"] + config["n_fm"] + config["n_gm"]
        self.model = util.FeedforwardModel(d_in, 1, self.value_config, name="v_net")
        if config["n_gm"] > 0:
            # TODO generalize to multi-dimensional agt_s
            self.gm_model = util.GeneralizedMomModel(1, config["n_gm"], config["gm_config"], name="v_gm")
        self.train_vars = None
        self.optimizer = tf.keras.optimizers.Adam(
            learning_rate=self.value_config["lr"], epsilon=1e-8,
            beta_1=0.99, beta_2=0.99
        )

    @tf.function
    def prepare_state(self, input_data):
        if self.config["n_fm"] == 2:
            k_var = tf.math.reduce_variance(input_data["agt_s"], axis=-2, keepdims=True)
            k_var = tf.tile(k_var, [1, input_data["agt_s"].shape[-2], 1])
            state = tf.concat([input_data["basic_s"], k_var], axis=-1)
        elif self.config["n_fm"] == 0:
            state = tf.concat([input_data["basic_s"][..., 0:1], input_data["basic_s"][..., 2:]], axis=-1)
        elif self.config["n_fm"] == 1:  # so far always add k_mean in the basic_state
            state = input_data["basic_s"]
        if self.config["n_gm"] > 0:
            gm = self.gm_model(input_data["agt_s"])
            state = tf.concat([state, gm], axis=-1)
        return state

    @tf.function
    def value_fn(self, input_data):
        state = self.prepare_state(input_data)
        value = self.model(state)
        return value

    @tf.function
    def loss(self, input_data):
        y_pred = self.value_fn(input_data)
        y = input_data["value"]
        loss = tf.reduce_mean(tf.square(y_pred - y))
        loss_dict = {"loss": loss}
        return loss_dict

    def grad(self, input_data):
        with tf.GradientTape(persistent=True) as tape:
            loss = self.loss(input_data)["loss"]
        train_vars = self.model.trainable_variables
        if self.config["n_gm"] > 0:
            train_vars += self.gm_model.trainable_variables
        self.train_vars = train_vars
        grad = tape.gradient(
            loss,
            train_vars,
            unconnected_gradients=tf.UnconnectedGradients.ZERO,
        )
        del tape
        return grad

    @tf.function
    def train_step(self, train_data):
        grad = self.grad(train_data)
        self.optimizer.apply_gradients(
            zip(grad, self.train_vars)
        )

    def train(self, train_dataset, valid_dataset, num_epoch=None, batch_size=None):
        train_dataset = train_dataset.batch(batch_size)

        for epoch in range(num_epoch+1):
            for train_data in train_dataset:
                self.train_step(train_data)
            if epoch % 20 == 0:
                for valid_data in valid_dataset:
                    val_loss = self.loss(valid_data)
                    print(
                        # "Epoch: %d, validation loss: %g" % (epoch, val_loss["loss"])
                        "Value function learning epoch: %d" % (epoch)
                    )

    def save_model(self, path="value_model.h5"):
        self.model.save_weights(path)
        if self.config["n_gm"] > 0:
            self.gm_model.save_weights(path.replace(".h5", "_gm.h5"))

    def load_model(self, path):
        self.model.load_weights_after_init(path)
        if self.config["n_gm"] > 0:
            self.gm_model.load_weights_after_init(path.replace(".h5", "_gm.h5"))


import ROOT

from plotMass import file_names, get_tree

ROOT.gROOT.LoadMacro("GeoFitCorr_C.so")

samp = "ggh18bsr_hadded"
file_name = file_names[samp]
tree = get_tree(file_name)

var_name = "corr-geofit-bs" #"ptcorr-geofit-bs"
var_dic = {"corr-geofit-bs":"(muons[0].pt_bs/muons[0].pt):(GeoFit::PtCorrGeoFit(muons[0].d0_BS*muons[0].charge, muons[0].pt_Roch, muons[0].eta, 2018)/muons[0].pt)",
           "ptcorr-geofit-pf":"muons[0].pt:GeoFit::PtCorrGeoFit(muons[0].d0_BS*muons[0].charge, muons[0].pt_Roch, muons[0].eta, 2018)" ,
           "ptcorr-geofit-bs":"muons[0].pt_bs:GeoFit::PtCorrGeoFit(muons[0].d0_BS*muons[0].charge, muons[0].pt_Roch, muons[0].eta, 2018)"}

muon_selection = "(muons.pt > 20 & abs(muons.eta)<2.4 & muons.isMediumID==1 & muons.relIso < 0.25)"
event_selection = "muons.pt>20" # dummy
#event_selection = "(muons.pt>30 && ( muons[0].isHltMatched[2]==1 || muons[0].isHltMatched[3]==1 || muons[1].isHltMatched[2]==1 || muons[1].isHltMatched[3]==1 ) )"
weightstring = "(GEN_wgt * PU_wgt)"

cut_string = "muons.pt>20" # dummy

variable = var_dic[var_name]

c1 = ROOT.TCanvas("c1","c1",600,600)
histo_name = "h2_{0}".format(var_name)
histo_title = "GeoFit - BS correction correlation"
th2 = ROOT.TH2F(histo_name,histo_title,100,0.98,1.02,100,0.98,1.02)
th2.GetXaxis().SetTitle("p_{T} (BS)/ p_{T} (PF)")
th2.GetYaxis().SetTitle("p_{T} (GeoFit)/ p_{T} (PF)")
th2.GetYaxis().SetTitleOffset(1.2)

tree.Draw("{0}>>{1}".format(variable,histo_name),"{0} * ({1} & {2} & {3})".format(weightstring,event_selection,muon_selection,cut_string),"COLZ")

#th2.SetLineColor(ROOT.kRed)
th2.Draw("COLZ")
ROOT.gPad.Update()
stat_th2 = th2.FindObject("stats")
print(th2.GetRMS(1))
print(th2.GetRMS(2))
ROOT.gPad.Update()
#ROOT.gStyle.SetOptStat(1111)
stat_th2.SetY1NDC(.3)
stat_th2.SetY2NDC(.5)
stat_th2.SetX1NDC(.9)
stat_th2.SetX2NDC(.7)
stat_th2.Draw("same")

c1.SaveAs("{0}.pdf".format(histo_name))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jul  2 15:36:54 2018

@author: sadra
"""
# External imports
import numpy as np
import sys
sys.path.append('../..')

# Internal imports
from main.ana_system import system,state
from main.auxilary_methods import vertices_cube
from main.polytope import polytope,anchor_point

# Code:
s=system(2,1)
s.modes=[0,1]
dt=0.02

K=1000
g=9.8
xmax=1.2
vmax=5
umax=3
dmax=vmax*dt
y_p=1 # I want to get into this height

s.A[0]=np.array([[1,dt],[0,1]])
s.A[1]=np.array([[1,dt],[-K*dt,1]])
s.A[1]=np.array([[-1,0],[0,-1]])

s.B[0]=np.array([[0,dt]]).T
s.B[1]=np.array([[0,dt]]).T
s.c[0]=np.array([[0,-g*dt]]).T
s.c[1]=np.array([[0,-g*dt]]).T
s.c[1]=np.array([[0.01*dt,0]]).T
s.B[1]=np.array([[0,0]]).T

s.H[0]=np.array([[1,0],[0,1],[-1,0],[0,-1]])
s.h[0]=np.array([[xmax,vmax,0,vmax]]).T

s.H[1]=np.array([[1,0],[0,1],[-1,0],[0,-1]])
s.h[1]=np.array([[0,vmax,dmax,vmax]]).T

s.F[0]=np.array([[1,-1]]).T
s.f[0]=np.array([[umax,umax]]).T

s.F[1]=np.array([[1,-1]]).T
s.f[1]=np.array([[umax,umax]]).T

s.Pi=np.array([[1,0],[0,1],[-1,0],[0,-1]])

s.l[0]=np.array([0,-vmax]).reshape(2,1)
s.u[0]=np.array([y_p,vmax]).reshape(2,1)

s.l[1]=np.array([-dmax,-vmax]).reshape(2,1)
s.u[1]=np.array([0,vmax]).reshape(2,1)

s.vertices=vertices_cube(2)

"""
These are polytopes for each mode
"""
s.mode_polytope={}
for mode in s.modes:
    p=polytope(s.H[mode],s.h[mode])
    p.anchor=anchor_point(p)
    s.mode_polytope[mode]=p

s.weight={}
s.weight[0]=4
s.weight[1]=1

s.goal=state(np.array([(xmax+y_p)/2,0]).reshape(2,1),np.array([[(xmax-y_p)/2,0],[0,1]]),0,0,0,10)


from typing import List

class Solution:
    def fourSumCount(self, A: List[int], B: List[int], C: List[int], D: List[int]) -> int:

        res = 0
        for a in A:
            for b in B:
                for c in C:
                    for d in D:
                        if a + b + c + d == 0: res += 1
        return res

print(Solution.fourSumCount())


from django.http import HttpResponse
from django.template import loader
from django.conf import settings
from django.contrib.sessions.models import Session

from easy_thumbnails.files import get_thumbnailer

from rest_framework.permissions import AllowAny
from rest_framework.views import APIView
from rest_framework.generics import ListCreateAPIView
from rest_framework.response import Response as RestResponse
from rest_framework.generics import RetrieveUpdateDestroyAPIView

from shop.models.customer import CustomerModel

from dshop.models import ProductVariableVariant, ProductDefault
from dshop.transition import quotation_new_notification
from .models import dmQuotation, dmQuotationItem
from .serializers import dmQuotationSerializer, dmQuotationItemSerializer

class dmQuotationCartMergeAPI(APIView):

    def get(self, request, *args, **kwargs):
        cookie = request.GET.get('cookie', None)
        session = Session.objects.filter(
            session_key=request.session.session_key
        )
        customer = None
        if session.count() > 0:
            session = session[0].get_decoded()
            user_id = session.get("_auth_user_id")
            if user_id:
                customer = CustomerModel.objects.get(user__id=user_id)

        if cookie and customer:
            cookie_quotation = dmQuotation.objects.filter(
                cookie=cookie,
                status=1,
                customer=None
            )
            for quot in cookie_quotation:
                quot.customer = customer
                quot.save()
            check_quotation = dmQuotation.objects.filter(
                customer=customer, status=1
            )
            if check_quotation.count() > 1:
                first_quotation = check_quotation.order_by('id').first()
                check_quotation = check_quotation.exclude(
                    id=first_quotation.id
                )
                for quot in check_quotation:
                    for item in dmQuotationItem.objects.filter(quotation=quot):
                        item.quotation = first_quotation
                        item.save()
                    quot.delete()
        return HttpResponse('Ok')

class dmQuotationCartCreateAPI(APIView):

    def post(self, request, *args, **kwargs):    # noqa: C901
        variant = request.GET.get('variant', None)
        product = request.GET.get('product', None)
        quantity = request.GET.get('quantity', '')
        cookie = request.GET.get('cookie', '')
        try:
            if product is not None:
                product_obj = ProductDefault.objects.get(product_code=product)
            elif variant is not None:
                product_obj = ProductVariableVariant.objects.get(product_code=variant)   # noqa
        except Exception as e:
            print(e)
            return RestResponse({"valid": False})

        customer = None

        if not request.user.is_anonymous:
            customer = CustomerModel.objects.get(user=request.user)

        if not customer:
            session = Session.objects.filter(
                session_key=request.session.session_key
            )
            if session.count() > 0:
                session = session[0].get_decoded()
                user_id = session.get('_auth_user_id')
                if user_id:
                    customer = CustomerModel.objects.get(user__id=user_id)

        # Check for Quotation
        quotation = []
        if customer:
            quotation = dmQuotation.objects.filter(
                customer=customer,
                status=1
            ).last()
        if not quotation:
            quotation = dmQuotation.objects.filter(
                cookie=cookie,
                status=1
            ).last()

        if not quotation:
            # To generate Quotation Number
            existing_q = dmQuotation.objects.all().order_by('-id')
            if existing_q:
                number = existing_q.first().number
                number = int(number) + 1
            else:
                number = "00001"
            if len(str(number)) < 5:
                num = '0'
                for i in range(1, 5-len(str(number))):
                    num = str(num) + '0'
                number = num + str(number)
            quotation = dmQuotation.objects.create(
                cookie=cookie,
                customer=customer,
                number=number
            )
        else:
            if customer:
                quotation.customer = customer
                quotation.save()
                '''if cookie:
                    cookie_quotation = dmQuotation.objects.filter(
                        cookie=cookie,
                        status=1,
                        customer=None
                    )
                    for quot in cookie_quotation:
                        quot.customer = customer
                        quot.save()
            check_quotation = dmQuotation.objects.filter(
                customer=customer, status=1
            )
            if check_quotation.count() > 1:
                first_quotation = check_quotation.order_by('id').first()
                check_quotation = check_quotation.exclude(
                    id=first_quotation.id
                )
                for quot in check_quotation:
                    for item in dmQuotationItem.objects.filter(quotation=quot):
                        item.quotation = first_quotation
                        item.save()
                    quot.delete()
                quotation = first_quotation'''

        if product is not None:
            quotation_items = dmQuotationItem.objects.filter(
                quotation=quotation,
                product_code=product_obj.product_code
            )
        if variant is not None:
            quotation_items = dmQuotationItem.objects.filter(
                quotation=quotation,
                variant_code=product_obj.product_code
            )
        if quotation_items:
            # Update Item
            quotation_items[0].quantity += int(quantity)
            quotation_items[0].save()
        else:
            # Create Item
            data = {
                'quotation': quotation,
                'quantity': quantity,
            }
            if variant is not None:
                attributes = ",".join([attr.value for attr in product_obj.attribute.all()])  # noqa
                data['product_type'] = 2
                data['variant_code'] = product_obj.product_code
                data['variant_attribute'] = attributes
                data['product_code'] = product_obj.product.square_id
                data['product_name'] = product_obj.product.product_name
            else:
                attributes = ''
                data['product_type'] = 1
                data['product_code'] = product_obj.product_code
                data['product_name'] = product_obj.product_name
            dmQuotationItem.objects.create(**data)
        return RestResponse({"valid": True})

class dmQuotationListCreateAPI(ListCreateAPIView):

    serializer_class = dmQuotationSerializer
    queryset = dmQuotation.objects.all()
    permission_classes = [AllowAny, ]

    def get_queryset(self):
        if not self.request.user.is_anonymous:
            user = self.request.user
            queryset = self.queryset.filter(customer__user=user)
            return queryset
        return dmQuotation.objects.none()

class dmQuotationRetrieve(RetrieveUpdateDestroyAPIView):

    serializer_class = dmQuotationSerializer
    permission_classes = [AllowAny, ]
    lookup_field = 'pk'
    # queryset = dmQuotation.objects.all()

    def get_queryset(self):
        cust = CustomerModel.objects.get(user=self.request.user)
        query = dmQuotation.objects.filter(
            customer=cust
        )
        return query

    def get(self, request, *args, **kwargs):    # noqa: C901
        cookie = request.GET.get('cookie', None)
        quotation = None
        if not request.user.is_anonymous:
            quotation = dmQuotation.objects.filter(
                pk=kwargs['pk'],
                customer=request.user.customer
            ).last()
        elif cookie is not None:
            quotation = dmQuotation.objects.filter(
                pk=kwargs['pk'],
                cookie=cookie,
                status=1
            ).last()
        else:
            session = Session.objects.filter(
                session_key=request.session.session_key
            ).last()
            if session and session.count() > 0:
                session = session[0].get_decoded()
                user_id = session.get('_auth_user_id')
                if user_id:
                    customer = CustomerModel.objects.get(user__id=user_id)
                    quotation = dmQuotation.objects.filter(
                        pk=kwargs['pk'],
                        customer__user=customer,
                        status=1
                    ).last()
        if quotation is None:
            context = {'quotations': [], 'count': 0}
        else:
            quot = {
                'id': quotation.id,
                'number': quotation.number,
                'status': dmQuotation.CHOICE_STATUS[int(quotation.status)-1][0],  # noqa
                'created_at': quotation.created_at,
                'updated_at': quotation.updated_at
            }
            items = []
            for item in dmQuotationItem.objects.filter(
                quotation=quotation
            ).order_by("product_name"):
                if item.product_type == 1:
                    current_item = ProductDefault.objects.filter(
                        product_code=item.product_code
                    ).first()
                    if current_item.main_image:
                        current_item_image = current_item.main_image
                    elif current_item.images.first():
                        current_item_image = current_item.images.first()
                    else:
                        current_item_image = None
                    if current_item_image is not None:
                        try:
                            current_image = get_thumbnailer(
                                current_item_image
                            ).get_thumbnail({
                                'size': (80, 80),
                                'upscale': True,
                                'background': "#ffffff"
                            }).url
                        except Exception:
                            current_image = None
                    else:
                        current_image = None
                    itm = {
                        'id': item.id,
                        'product_name': item.product_name,
                        'product_code': item.product_code,
                        'product_url': current_item.get_absolute_url(),
                        'product_image': current_image,
                        'variant_attribute': None,
                        'quantity': item.quantity,
                        'price': (
                            item.quantity * item.unit_price
                        ) if item.unit_price else None
                    }
                elif item.product_type == 2:
                    # ===---
                    current_item = ProductVariableVariant.objects.filter(
                        product_code=item.variant_code
                    ).first()
                    if current_item.product.main_image:
                        current_item_image = current_item.product.main_image
                    elif current_item.product.images.first():
                        current_item_image = current_item.product.images.first()  # noqa
                    else:
                        current_item_image = None
                    if current_item_image is not None:
                        try:
                            current_image = get_thumbnailer(
                                current_item_image
                            ).get_thumbnail({
                                'size': (80, 80),
                                'upscale': True,
                                'background': "#ffffff"
                            }).url
                        except Exception:
                            current_image = None
                    else:
                        current_image = None
                    # ===---
                    itm = {
                        'id': item.id,
                        'product_name': item.product_name,
                        'product_code': item.variant_code,
                        'product_url': current_item.product.get_absolute_url(),
                        'product_image': current_image,
                        'variant_attribute': item.variant_attribute,
                        'quantity': item.quantity,
                        'price': (
                            item.quantity * item.unit_price
                        ) if item.unit_price else None
                    }
                items.append(itm)
            quot["items"] = items
            context = {"quotation": quot}
        return RestResponse(context)

    def patch(self, request, *args, **kwargs):
        status = request.data.get("status", None)
        email = request.data.get("customer", None)
        if status is not None and email is not None:
            customer = CustomerModel.objects.filter(
                email=email
            ).last()
            if customer and status == 2:
                quotation = dmQuotation.objects.get(id=kwargs['pk'])
                quotation.customer = customer
                quotation.status = 2
                quotation.save()
                quotation_new_notification(quotation)
                return RestResponse({"valid": True})
        return RestResponse({"valid": False})

class dmQuotationItemListCreateAPI(ListCreateAPIView):

    serializer_class = dmQuotationItemSerializer
    permission_classes = [AllowAny, ]
    queryset = dmQuotationItem.objects.all()

class dmQuotationItemRetrieve(RetrieveUpdateDestroyAPIView):

    serializer_class = dmQuotationItemSerializer
    permission_classes = [AllowAny, ]
    lookup_field = 'pk'
    queryset = dmQuotationItem.objects.all()

def dmQuotationPage(request):
    cookie = request.GET.get('cookie', '')
    template = loader.get_template(
        "theme/{}/pages/quotation.html".format(settings.THEME_SLUG)
    )

    if request.user:
        quotations = dmQuotation.objects.filter(customer__user=request.user)
    elif cookie:
        quotations = dmQuotation.objects.filter(cookie=cookie)
    else:
        return HttpResponse(template.render({}, request))

    if not quotations:
        context = {'quotations': [], 'count': 0}
    else:
        data = []
        for quotation in quotations:
            quot = {
                'id': quotation.id,
                'number': quotation.number,
                'status': dmQuotation.CHOICE_STATUS[int(quotation.status)-1][1],  # noqa
                'created_at': quotation.created_at,
                'updated_at': quotation.updated_at
            }
            items = []
            for item in dmQuotationItem.objects.filter(quotation=quotation):
                itm = {
                    'id': item.id,
                    'product_name': item.product_name,
                    'product_code': item.product_code,
                    'variant_code': item.variant_code,
                    'variant_attribute': item.variant_attribute,
                    'quantity': item.quantity,
                }
                items.append(itm)
            quot["items"] = items
            data.append(quot)
        context = {'quotations': data, 'count': len(data)}
    return HttpResponse(template.render(context, request))

class dmQuotationCurrent(APIView):
    def get(self, request, *args, **kwargs):    # noqa: C901
        cookie = request.GET.get('cookie', None)
        quotation = None
        if not request.user.is_anonymous:
            quotation = dmQuotation.objects.filter(
                customer__user=request.user,
                status=1
            ).last()
        elif cookie is not None:
            quotation = dmQuotation.objects.filter(
                cookie=cookie,
                status=1
            ).last()
        else:
            session = Session.objects.filter(
                session_key=request.session.session_key
            )
            if session:
                session = session[0].get_decoded()
                user_id = session['_auth_user_id']
                customer = CustomerModel.objects.get(user__id=user_id)
                quotation = dmQuotation.objects.filter(
                    customer__user=customer,
                    status=1
                ).last()
        if quotation is None:
            context = {'quotations': [], 'count': 0}
        else:
            quot = {
                'id': quotation.id,
                'number': quotation.number,
                'status': dmQuotation.CHOICE_STATUS[int(quotation.status)-1][1],  # noqa
                'created_at': quotation.created_at,
                'updated_at': quotation.updated_at
            }
            items = []
            for item in dmQuotationItem.objects.filter(
                quotation=quotation
            ).order_by("product_name"):
                if item.product_type == 1:
                    current_item = ProductDefault.objects.filter(
                        product_code=item.product_code
                    ).first()
                    if current_item.main_image:
                        current_item_image = current_item.main_image
                    elif current_item.images.first():
                        current_item_image = current_item.images.first()
                    else:
                        current_item_image = None
                    if current_item_image is not None:
                        try:
                            current_image = get_thumbnailer(
                                current_item_image
                            ).get_thumbnail({
                                'size': (80, 80),
                                'upscale': True,
                                'background': "#ffffff"
                            }).url
                        except Exception:
                            current_image = None
                    else:
                        current_image = None
                    itm = {
                        'id': item.id,
                        'product_name': item.product_name,
                        'product_code': item.product_code,
                        'product_url': current_item.get_absolute_url(),
                        'product_image': current_image,
                        'variant_attribute': None,
                        'quantity': item.quantity,
                    }
                elif item.product_type == 2:
                    # ===---
                    current_item = ProductVariableVariant.objects.filter(
                        product_code=item.variant_code
                    ).first()
                    if current_item.product.main_image:
                        current_item_image = current_item.product.main_image
                    elif current_item.product.images.first():
                        current_item_image = current_item.product.images.first()  # noqa
                    else:
                        current_item_image = None
                    if current_item_image is not None:
                        try:
                            current_image = get_thumbnailer(
                                current_item_image
                            ).get_thumbnail({
                                'size': (80, 80),
                                'upscale': True,
                                'background': "#ffffff"
                            }).url
                        except Exception:
                            current_image = None
                    else:
                        current_image = None
                    # ===---
                    itm = {
                        'id': item.id,
                        'product_name': item.product_name,
                        'product_code': item.variant_code,
                        'product_url': current_item.product.get_absolute_url(),
                        'product_image': current_image,
                        'variant_attribute': item.variant_attribute,
                        'quantity': item.quantity,
                    }
                items.append(itm)
            quot["items"] = items
            context = {"quotation": quot}
        return RestResponse(context)


import gradio as gr
import numpy as np
import torch
from train import GAN
from utils import *
from torchvision.utils import save_image
import os
import argparse

def get_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument('--config', type=str, default='./infogan/config.yaml', help='Base config') # do not change

    args = parser.parse_args()
    src_config_dir = os.path.join(os.getcwd(), args.config)
    cfg = load_config(src_config_dir)

    # concat args & config
    dict_args = vars(args)
    dict_args.update(cfg)
    args = argparse.Namespace(**dict_args)
    args.DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    return args

def infogan(discrete_num , c_continuous_1,c_continuous_2):
    z = torch.randn(1,62)
    c_discrete = to_onehot(discrete_num)
    c_continuous = torch.Tensor([[c_continuous_1,c_continuous_2]])
    c = torch.cat((c_discrete.float(), c_continuous), 1)

    model = GAN()
    model = model.load_from_checkpoint(checkpoint_path='example.ckpt')
    model.eval()
    result = model(z, c)

    save_image(result, "result.png", normalize=True)

    return "result.png"

if __name__ =='__main__':
    args = get_parser()
    torch.manual_seed(42)
    iface = gr.Interface(fn=infogan,
                        inputs=[gr.inputs.Slider(0,9,step=1),gr.inputs.Slider(-1.,1.0),gr.inputs.Slider(-1.,1.0)],
                        outputs="image")
    iface.launch()


"""classes and methods for different model architectures
"""
#python packages
import numpy as np

# Machine Learning from Scratch packages
from Layers import FullyConnected
from utils.optimizers import *

class NeuralNet():
    """
    Linear stack of layers.
    """
    def __init__(self, layers=None):
        # Add any layers passed into constructor to the model
        if layers:
            for layer in layers:
                self.layers.append(layer)
        else:
            self.layers = []
        self.output = None

    def add_layer(self, layer_type=None,
                     input_shape=None,
                     output_shape=None,
                     activation=None,
                     dropout=1.,
                     lambd=0,):
        """Adds a Layer class to model
        """
        #only FullyConnected layer type supported right now
        if layer_type=="FullyConnected":
            layer = FullyConnected(input_shape=input_shape,
                                output_shape=output_shape,
                                activation=activation,
                                dropout=dropout,
                                lambd=lambd
                         )
        #append layer to model Class
        self.layers.append(layer)

    def model_forward(self,X,training=False):
        """ Perform forward evaluation of model on given data
        Inputs:
            X -- input data to be evaluated by model vector shape=(len(Wl_1), number of examples)
            training -- training flag, no layer dropout if True
        Outputs:
            predictions -- model prediction(s) for given data
        """
        layer_inputs = X
        for layer in self.layers:
            if training==False: #only use dropout when training
                layer.dropout=1.
            #loop over all layers, using the output of previous layer as input
            layer.layer_forward(layer_inputs=layer_inputs)
            #update "layer_inputs" for next iteration
            layer_inputs = layer.outputs
        #predictions will be layer.output of the last layer
        predictions = layer_inputs
        return predictions

    def model_backprop(self,Y):
        """ Perform back-prop. of prediction error through model
        Inputs:
            Y -- truth "label" vector shape=(n_y, number of examples)
        Outputs:
            None -- updates Layer properties
        """
        # output_layer = self.layers[-1]
        dZ = self.compute_loss_grad(Y)
        #backprop output layer results through the network
        for layer in reversed(self.layers):
            #loop over all layers, using following layerdZ
            layer.layer_backprop(dZ)
            #update "dZ" for next iteration, set to current layer's Activation gradient
            dZ = layer.dA

    def compute_cost(self,predictions,Y):
        """ compute "cost" for given predictions/truth
        Inputs:
            predictions -- model predictions vector shape=(n_y, number of examples)
            Y -- truth "label" vector shape=(n_y, number of examples)
        Outputs:
            cost - gradient of output layer's activation
        """
        m = Y.shape[1]
        # Compute loss from predictions and y.
        predictions = np.clip(predictions, 1e-13, 1 - 1e-13)
        if self.loss == 'binary-crossentropy':
            cost = np.multiply(-np.log(predictions),Y) + np.multiply(-np.log(1 - predictions), 1 - Y)
        elif self.loss == 'categorical-crossentropy':
            #Categorical Crossentropy
            cost =  np.sum(np.multiply(Y, -np.log(predictions)),axis=0,keepdims=False)
        else:
            return None
        return cost

    def compute_loss_grad(self,Y):
        """
        Inputs:
            Y -- truth "label" vector shape=(n_y, number of examples)
        Outputs:
            dZ - gradient of output layer's loss
        """
        output_layer = self.layers[-1]
        # outputs = output_layer.outputs
        predictions = np.clip(output_layer.outputs, 1e-13, 1 - 1e-13)
        if self.loss == 'binary-crossentropy':
            #gradient of sigmoid (for now)
            # print("outputs: ", output_layer.outputs)
            # print(1 - output_layer.outputs)
            dZ = - (np.divide(Y, predictions) - np.divide(1 - Y, 1 - predictions))

        elif self.loss == 'categorical-crossentropy':
            #gradient of softmax
            dZ = predictions - Y
        return dZ

    def predict(self, X):
        predictions = self.model_forward(X,training=False)
        return predictions

    def train(self, X, Y,
              optimizer="gd",
              loss=None,
              learning_rate = 0.007,
              mini_batch_size = [],
              num_epochs = 100,
              print_cost=True):
        """
        Inputs:
            X -- input data, of shape=(n_x, number of examples)
            Y -- truth "label" vector shape=(n_y, number of examples)
            loss -- loss function to use
            optimizer -- optimizer to use to update trainable params.
            learning_rate -- the learning rate, scalar.
            mini_batch_size -- the size of each dataset mini batch
            num_epochs -- number of epochs
            print_cost -- True to print the cost every 1000 epochs

        """

        self.loss = loss

        if print_cost:
            #print at every 1% of training completion, or at every epoch if num_epoch <= 100
            print_interval = np.max([1,int(0.01*num_epochs)])

        m = X.shape[1]                   # number of training examples
        if not mini_batch_size:
            mini_batch_size = m #make the mini-batch the entire dataset

        costs = []                       # to keep track of the cost
        accuracy_lst = []                # keep track of acc. for multi-class problems
        seed = 10

        # Initialize layers (weights & bias vectors)
        for layer in self.layers:
            layer.initialize_layer()
            if layer.dropout > 1.: #check that inputs make sense
                layer.dropout = 1.
            #if true, dropout was requested, override/ignore user's L2 reg. request (as of this commit)
            if layer.dropout < 1.:
                layer.lambd = 0

        # Initialize the optimizer
        if optimizer == "gd":
            pass # no initialization needed
        elif optimizer == "momentum":
            initialize_velocity(self.layers)
            beta = 0.90
        elif optimizer == "adam":
            t = 0 #counter required for Adam update
            #use values from the ADAM paper
            beta1 = 0.9
            beta2 = 0.999
            epsilon = 1e-7
            learning_rate = 0.01
            initialize_adam(self.layers)

        # Optimization loop
        for i in range(num_epochs):

            # Define the random minibatches, change seed each time
            seed = seed + 1
            minibatches = make_sub_batches(X, Y, mini_batch_size, seed)

            #init cost summation variable
            cost_total = 0.
            #init accuracy summation variable
            training_correct = 0.

            for minibatch in minibatches:
                # Select a minibatch
                (minibatch_X, minibatch_Y) = minibatch

                # Forward prop
                predictions = self.model_forward(minibatch_X, training=True)

                # Compute cost (for printing) and add to the running total
                cost_total += np.nansum(self.compute_cost(predictions, minibatch_Y))

                #compute train set acc. for multi-class class. problems
                if (predictions.shape[0] > 1) | (self.loss == ('categorical-crossentropy')):
                    #compute number of examples correctly classified, assuming only one class can present right now
                    training_correct += np.sum(np.argmax(predictions,axis=0)==np.argmax(minibatch_Y,axis=0),keepdims=False)

                # Backprop
                self.model_backprop(Y=minibatch_Y)

                # Update weights/bias
                if optimizer == "gd":
                    update_layers_with_gradient_descent(self.layers, learning_rate)
                elif optimizer == "momentum":
                    update_parameters_with_momentum(self.layers, beta, learning_rate)
                elif optimizer == "adam":
                    t = t + 1 # Adam counter
                    update_parameters_with_adam(self.layers, t, learning_rate, beta1, beta2,  epsilon)

            #compute training stats. for this epoch
            cost_avg = cost_total / m
            if predictions.shape[0] > 1: #for multi-class class. problems show accuracy
                accuracy_percent = 100.*(training_correct/m)

            # Print the cost every epoch
            # if print_cost and i % print_interval == 0:
            if print_cost and i % 1 == 0:
                if predictions.shape[0] > 1: #for multi-class class. problems show accuracy
                    print("Cost after epoch %i: %f, Acc.: %f" %(i, cost_avg, accuracy_percent))
                    accuracy_lst.append(accuracy_percent)
                else:
                    print(("Cost after epoch %i: %f" %(i, cost_avg)))
                costs.append(cost_avg)

            #will need to implement better convergence detection..
            if self.loss == ('categorical-crossentropy'):
                pass
            elif cost_avg < 0.17:
                break


from flask import Flask, render_template, request, session
import win32evtlog
import csv
from datetime import datetime
import openai
import time

app = Flask(__name__)
import secrets

# Generate a random secret key
secret_key = secrets.token_hex(16)

# Print the generated secret key
print(secret_key)

app.secret_key = secret_key
hand = None
flags = None
total_records = None

# Get the current date and time to include in the CSV file name
current_datetime = datetime.now().strftime("%Y%m%d_%H%M%S")

# Specify the CSV file name with the date and time format
csv_file = f"{current_datetime}_syslog.csv"

# Define the column headers for the CSV file
field_names = ["Timestamp", "Hostname", "Log Level", "Log Message", "Suggestion"]

# Helper function to get a suggestion for an error message using the GPT-3.5 API with retry
def get_suggestion_with_retry(error_message, retry_attempts=3):
    for i in range(retry_attempts):
        try:
            prompt = f"Error message: {error_message}\nSuggestion:"
            response = openai.Completion.create(engine="text-davinci-002", prompt=prompt, max_tokens=50, api_key=session.get("openapi_key"))
            return response.choices[0].text.strip()
        except openai.error.RateLimitError:
            # Wait for 20 seconds before retrying
            time.sleep(20)
    # If retries fail, return an empty suggestion
    return ""

@app.route("/", methods=["GET", "POST"])
def index():
    global hand, flags, total_records

    # Code for loading log names and types (if applicable)
    log_names = ["Application", "System", "Security"]  # Replace with the actual log names
    log_types = ["Information", "Error", "Warning", "Unknown"]  # Replace with the actual log types

    filtered_logs = []  # Initialize filtered_logs as an empty list

    if request.method == "POST":
        # Get user input from the form
        openapi_key = request.form["openapi_key"]
        log_name = request.form["log_name"]
        log_type = request.form["log_type"]
        filter_range = request.form["filter_range"]
        filter_date = request.form["filter_date"]
        filter_time = request.form["filter_time"]

        # Combine date and time to form the timestamp
        filter_timestamp = f"{filter_date} {filter_time}"

        # Store OpenAI API key in the session
        session["openapi_key"] = openapi_key

        # Set the Flask app secret key to the OpenAI API key
        app.secret_key = openapi_key

        # Set the OpenAI API key for making API calls
        openai.api_key = openapi_key

        # Initialize the event log if it's not already initialized
        if hand is None:
            hand = win32evtlog.OpenEventLog(None, log_name)
            flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
            total_records = win32evtlog.GetNumberOfEventLogRecords(hand)

        # Filter logs based on the user's input
        filtered_logs = []
        while True:
            events = win32evtlog.ReadEventLog(hand, flags, 0)
            if not events:
                break
            for event in events:
                timestamp = event.TimeGenerated.Format(" %b %d %Y %H:%M:%S")
                hostname = event.ComputerName

                # Map event type to log level
                event_type = event.EventType
                log_level_mapping = {
                    win32evtlog.EVENTLOG_SUCCESS: "Information",
                    win32evtlog.EVENTLOG_ERROR_TYPE: "Error",
                    win32evtlog.EVENTLOG_WARNING_TYPE: "Warning",
                    win32evtlog.EVENTLOG_INFORMATION_TYPE: "Information",
                }
                log_level = log_level_mapping.get(event_type, "Unknown")

                log_message = event.StringInserts

                # Apply filters based on user input
                if filter_range == "all" or filter_timestamp == timestamp:
                    filtered_logs.append({
                        "Timestamp": timestamp,
                        "Hostname": hostname,
                        "Log Level": log_level,
                        "Log Message": log_message,
                    })

        # Generate ChatGPT suggestions for each log message
        for log in filtered_logs:
            log_message = log["Log Message"]
            suggestion = get_suggestion_with_retry(log_message)
            log["Suggestion"] = suggestion

        # Write the filtered logs to the CSV file
        with open(csv_file, "w", newline="", encoding="utf-8") as csvfile:
            csv_writer = csv.DictWriter(csvfile, fieldnames=field_names)
            csv_writer.writeheader()
            for log in filtered_logs:
                csv_writer.writerow(log)

    return render_template("index.html", log_names=log_names, log_types=log_types, logs_data=filtered_logs)

if __name__ == "__main__":
    app.run(debug=True)


# -*- Coding: utf-8 -*-

class RepositoryParser:
    def __init__(self):
        print()

    # from HTML
    def get_author_list(self, soup):
        titleElem = soup.find("h1")
        title = titleElem.get_text()
        print(title)
        divElem = titleElem.parent
        a_list = divElem.find_all("a")

        return a_list


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- pdpost_docx_update_fields
"""

import argparse
import logging
import time
from pathlib import Path as path

import win32com.client

from .docxprod_helper import (DOCXPROD_ROOT, logger_init)

logger = logging.getLogger(__name__)

def update_fields(filepath: path):
    extension = filepath.suffix
    acceptable_ext = ['.doc','.docx']
    #word = comtypes.client.CreateObject('Word.Application') # opens the word application
    word = win32com.client.Dispatch('Word.Application')

    if extension not in acceptable_ext:
        logger.error(f'Error: Incorrect Filetype {extension}')
    else:
        doc = word.Documents.Open(str(filepath)) # opens the specified file
        #doc.SelectAll()
        for field in doc.Fields:
            if field.Type != 37 and field.Type != 88:
                response = field.UpdateSource()
                logger.info(f'Success with {field.Code()}')
                time.sleep(1)
            #break
        response = doc.Fields.Update() # updates field, returns 0 if successful ->  Invaildate action
        if response != 0:
            logger.error(f'Error with {filepath} on field at Index {str(response)} ')
        if response == 0:
            #doc.Save(NoPrompt=True, OriginalFormat=1)
            doc.Save()
            logger.info(f'Success with {filepath}')
        doc.Close()
    word.Quit()

def main(doc=None):

    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--debug", action="store_true", help="Print additional debugging information"
    )
    parser.add_argument(
        '--output',
        '-o',
        type=path,
        help='The path for the output docx file')
    parser.add_argument(
        '--input',
        '-i',
        type=path,
        help='The path to the input docx file')
    parser.add_argument(
        '--verbose',
        '-v',
        action='store_true',
        help='Show the verbose output to the terminal')
    args = parser.parse_args()
    logger_init(args)

    try:
        update_fields(args.input)
    except Exception as e:
        print(e)
    logger.info(f"Updated fields done")

if __name__ == '__main__':
    main()


''' A number consisting entirely of ones is called a repunit. We shall define
R(k) to be a repunit of length k. Given that n is a positive integer and
GCD(n, 10) = 1, it can be shown that there always exists a value, k, for which
R(k) is divisible by n, and let A(n) be the least such value of k; for example.
Find the least value of n for which A(n) first exceeds one-million. '''

from itertools import count

def main():
    ''' The solution must be > 1000000 as A(n) < n. This function iterates over
    valid values of 'n' (not divisible by 2 or 5) starting at 1000000 until a
    solution is found '''
    for n in count(1000000):
        if n % 2 and n % 5 and brute_check(n) > 1000000:
            print(n)
            break

def brute_check(n):
    ''' Finding 'k' given 'n' is equivalent to solving 10^k mod 9*n = 1. This
    function tests possible values of 'k' starting at 1 until a solution is
    found. It returns the solution, which is the lowest value of 'k' that
    satisfies the above equation '''
    cur = 10
    for k in count(1):
        if cur == 1:
            return k
        cur = cur*10 % (9*n)

if __name__ == "__main__":
    main()


from .base import *

import dj_database_url

DEBUG = True

TEMPLATES[0]['OPTIONS']['debug'] = DEBUG

WSGI_APPLICATION = 'wsgi.local.application'

MIDDLEWARE += ('debug_toolbar.middleware.DebugToolbarMiddleware', )

INSTALLED_APPS += ('debug_toolbar', )

SECRET_KEY = 'ui9hb!-_0shivrh1xtztinys)ya$lm$0xvh*_zbdydc-pdn3$y'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
}

# DATABASE_URL = os.environ['DATABASE_URL']
# DATABASES = {
#     'default': dj_database_url.parse(DATABASE_URL),
# }
#
# DATABASES['default']['CONN_MAX_AGE'] = None

DEFAULT_FILE_STORAGE = u'storages.backends.overwrite.OverwriteStorage'
PIPELINE['PIPELINE_ENABLED'] = False


# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from pathlib import Path

from mozperftest.layers import Layer

class AndroidLog(Layer):
    """Runs an android log test."""

    name = "androidlog"
    activated = False
    arguments = {
        "first-timestamp": {
            "type": str,
            "default": None,
            "help": "First timestamp regexp",
        },
        "second-timestamp": {
            "type": str,
            "default": None,
            "help": "Second timestamp regexp",
        },
        "subtest-name": {
            "type": str,
            "default": "TimeToDisplayed",
            "help": "Name of the metric that is produced",
        },
    }

    def _get_logcat(self):
        logcat = self.get_arg("android-capture-logcat")
        if logcat is None:
            raise NotImplementedError()
        # check if the path is absolute or relative to output
        path = Path(logcat)
        if not path.is_absolute():
            return Path(self.get_arg("output"), path).resolve()
        return path.resolve()

    def __call__(self, metadata):
        app_name = self.get_arg("android-app-name")
        first_ts = r".*Start proc.*" + app_name.replace(".", r"\.") + ".*"
        second_ts = r".*Fully drawn.*" + app_name.replace(".", r"\.") + ".*"
        options = {
            "first-timestamp": self.get_arg("first-timestamp", first_ts),
            "second-timestamp": self.get_arg("second-timestamp", second_ts),
            "processor": self.env.hooks.get("logcat_processor"),
            "transform-subtest-name": self.get_arg("subtest-name"),
        }

        metadata.add_result(
            {
                "results": str(self._get_logcat()),
                "transformer": "LogCatTimeTransformer",
                "transformer-options": options,
                "name": "LogCat",
            }
        )

        return metadata


import os
import re
import subprocess
import tempfile
import random
import glob
import signal
import threading
import functools
from pkg_resources import parse_version
from io import StringIO
import logging as pyLog
import six
import sys
import threading
import json
try:
    from shutil import which, get_terminal_size
except ImportError:
    from backports.shutil_which import which

# workaround for python2/3 string handling {{{
try:
    from string import strip
except ImportError:
    strip = str.strip
# }}}

# Copyright 2011-2023 Ralf Mueller, ralf.mueller@dkrz.de {{{
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
# 3. Neither the name of the copyright holder nor the names of its contributors
#    may be used to endorse or promote products derived from this software without
#    specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# }}}

# build interactive documentation: help(cdo.sinfo) {{{

def operator_doc(tool, path2cdo):
    proc = subprocess.Popen('%s -h %s ' % (path2cdo, tool),
                            shell=True,
                            stderr=subprocess.PIPE,
                            stdout=subprocess.PIPE)
    retvals = proc.communicate()
    return retvals[0].decode("utf-8")
# }}}

# return the cdo version {{{

def getCdoVersion(path2cdo, verbose=False):
    proc = subprocess.Popen(
        [path2cdo, '-V'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    retvals = proc.communicate()
    cdo_help = retvals[0].decode("utf-8")
    if verbose:
        return cdo_help
    match = re.search(r"Climate Data Operators version (\d.*) .*", cdo_help)
    return match.group(1)

# helper function without side effects {{{

def setupLogging(logFile):
    logger = pyLog.getLogger(__name__)
    logger.setLevel(pyLog.INFO)

    if isinstance(logFile, six.string_types):
        handler = pyLog.FileHandler(logFile)
    else:
        handler = pyLog.StreamHandler(stream=logFile)

    formatter = pyLog.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler)

    return logger
# }}}

# extra exceptions for CDO {{{

class CDOException(Exception):

    def __init__(self, stdout, stderr, returncode):
        super(CDOException, self).__init__()
        self.stdout = stdout
        self.stderr = stderr
        self.returncode = returncode
        self.msg = '(returncode:%s) %s' % (returncode, stderr)

    def __str__(self):
        return self.msg
# }}}

# MAIN Cdo class {{{

class Cdo(object):

    # fallback operator lists {{{
    NoOutputOperators = 'cdiread cmor codetab conv_cmor_table diff diffc diffn \
    diffp diffv dump_cmor_table dumpmap filedes gmtcells gmtxyz gradsdes griddes \
    griddes2 gridverify info infoc infon infop infos infov map ncode ndate \
    ngridpoints ngrids nlevel nmon npar ntime nvar nyear output outputarr \
    outputbounds outputboundscpt outputcenter outputcenter2 outputcentercpt \
    outputext outputf outputfld outputint outputkey outputsrv outputtab outputtri \
    outputts outputvector outputvrml outputxyz pardes partab partab2 seinfo \
    seinfoc seinfon seinfop showattribute showatts showattsglob showattsvar \
    showcode showdate showformat showgrid showlevel showltype showmon showname \
    showparam showstdname showtime showtimestamp showunit showvar showyear sinfo \
    sinfoc sinfon sinfop sinfov spartab specinfo tinfo vardes vct vct2 verifygrid \
    vlist xinfon zaxisdes'.split()
    TwoOutputOperators = 'trend samplegridicon mrotuv eoftime \
    eofspatial eof3dtime eof3dspatial eof3d eof complextorect complextopol'.split()
    MoreOutputOperators = 'distgrid eofcoeff eofcoeff3d intyear scatter splitcode \
    splitday splitgrid splithour splitlevel splitmon splitname splitparam splitrec \
    splitseas splitsel splittabnum splitvar splityear splityearmon splitzaxis'.split()
    AliasOperators = {'seq': 'for'}

    # the following operators introduce additional new lines in cdo-2.0.0 for
    # increased readability in the therminal. This leads to inconsistens parsing
    # behaviour here because before new lines indicated meta data for a new
    # variable for all show* operators.
    ShowTimeOperators = 'showdate showtime showtimestamp showyear showmon'.split()
    # operators are now called with '-s' to ease the parsing process. diff* does
    # not print the errors when '-s' is given, so these operators need special
    # treatment
    # avoiding '-s' can lead to errors when working with operators which write to
    # stdout, but it can done with cdo.silent = False
    DiffOperators = 'diff diffc diffn diffv diffp'.split()
    # }}}

    name = ''

    def __init__(self, #{{{
                 cdo='cdo',
                 returnNoneOnError=False,
                 forceOutput=True,
                 env=os.environ,
                 debug=False,
                 tempdir=tempfile.gettempdir(),
                 tempStore=None,
                 logging=False,
                 logFile=StringIO(),
                 cmd=[],
                 options=[],
                 silent=True):

        if 'CDO' in os.environ and os.path.isfile(os.environ['CDO']):
            self.CDO = os.environ['CDO']
        else:
            self.CDO = cdo

        self._cmd = cmd
        self._options = options

        self.operators = self.__getOperators()
        self.noOutputOperators = [op for op, num in self.operators.items() if 0 == num]
        self.returnNoneOnError = returnNoneOnError
        self.tempStore = tempStore or CdoTempfileStore(dir=tempdir)
        self.forceOutput = forceOutput
        self.env = env
        self.debug = True if 'DEBUG' in os.environ else debug
        self.silent = silent
        self.libs = self.getSupportedLibs()

        # optional IO libraries for additional return types
        self.hasNetcdf = False
        self.hasXarray = False
        self.cdf = None
        self.xa_open = None
        self.__loadOptionalLibs()

        self.logging = logging  # internal logging {{{
        self.logFile = logFile
        if self.logging:
            self.logger = setupLogging(self.logFile)  # }}}

        # CDO build configuration available since cdo-1.9x
        self.config = self.__getConfig()
        #}}}

    def __get__(self, instance, owner):
        if instance is None:
            return self
        name = self.name
        # CDO (version 1.9.6 and older) has an operator called 'for', which cannot
        # called with 'cdo.for()' because 'for' is a keyword in python. 'for' is
        # renamed to 'seq' in 1.9.7.
        # This workaround translates all calls of 'seq' into for in case of
        # versions prior to 1.9.7
        if name in self.AliasOperators and (
                parse_version(getCdoVersion(self.CDO)) < parse_version('1.9.7')):
            name = self.AliasOperators[name]
        return self.__class__(
            instance.CDO,
            instance.returnNoneOnError,
            instance.forceOutput,
            instance.env,
            instance.debug,
            instance.tempStore.dir,
            instance.tempStore,
            instance.logging,
            instance.logFile,
            instance._cmd + ['-' + name],
            instance._options,
            instance.silent)

    # from 1.9.6 onwards CDO returns 1 of diff* finds a difference {{{
    def __exit_success(self, operatorName):
        if parse_version(getCdoVersion(self.CDO)) < parse_version('1.9.6'):
            return 0
        if 'diff' != operatorName[0:4]:
            return 0
        return 1 #}}}

    # read json formatted output of 'cdo --config all' {{{
    def __getConfig(self):
      proc = subprocess.Popen([self.CDO, '--config','all'], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
      ret  = proc.communicate()
      try:
        return json.loads(ret[0].decode('utf-8'))
      except:
        return {} #}}}

    # retrieve the list of operators from the CDO binary plus info out number of {{{
    # output streams
    def __getOperators(self):
        operators = {}

        version = parse_version(getCdoVersion(self.CDO))
        if version < parse_version('1.7.2'):
            proc = subprocess.Popen(
                [self.CDO, '-h'], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
            ret = proc.communicate()
            l = ret[1].decode("utf-8").find("Operators:")
            ops = ret[1].decode("utf-8")[l:-1].split(os.linesep)[1:-1]
            endI = ops.index('')
            s = ' '.join(ops[:endI]).strip()
            s = re.sub(r"\s+", " ", s)

            for op in list(set(s.split(" "))):
                operators[op] = 1
                if op in self.NoOutputOperators:
                    operators[op] = 0
                if op in self.TwoOutputOperators:
                    operators[op] = 2
                if op in self.MoreOutputOperators:
                    operators[op] = -1

        elif version < parse_version('1.8.0') or parse_version('1.9.0') == version:
            proc = subprocess.Popen([self.CDO, '--operators'],
                                    stderr=subprocess.PIPE, stdout=subprocess.PIPE)
            ret = proc.communicate()
            ops = list(map(lambda x: x.split(' ')[0], ret[0].decode(
                "utf-8")[0:-1].split(os.linesep)))

            for op in ops:
                operators[op] = 1
                if op in self.NoOutputOperators:
                    operators[op] = 0
                if op in self.TwoOutputOperators:
                    operators[op] = 2
                if op in self.MoreOutputOperators:
                    operators[op] = -1

        elif version < parse_version('1.9.3'):
            proc = subprocess.Popen([self.CDO, '--operators'],
                                    stderr=subprocess.PIPE, stdout=subprocess.PIPE)
            ret = proc.communicate()
            ops = list(map(lambda x: x.split(' ')[0], ret[0].decode(
                "utf-8")[0:-1].split(os.linesep)))

            proc = subprocess.Popen(
                [self.CDO, '--operators_no_output'],
                stderr=subprocess.PIPE,
                stdout=subprocess.PIPE)
            ret = proc.communicate()
            opsNoOutput = list(map(lambda x: x.split(
                ' ')[0], ret[0].decode("utf-8")[0:-1].split(os.linesep)))

            for op in ops:
                operators[op] = 1
                if op in opsNoOutput:
                    operators[op] = 0
                if op in self.TwoOutputOperators:
                    operators[op] = 2
                if op in self.MoreOutputOperators:
                    operators[op] = -1

        else:
            proc = subprocess.Popen([self.CDO, '--operators'],
                                    stderr=subprocess.PIPE, stdout=subprocess.PIPE)
            ret = proc.communicate()
            ops = list(map(lambda x: x.split(' ')[0], ret[0].decode(
                "utf-8")[0:-1].split(os.linesep)))
            ios = list(map(lambda x: x.split(' ')[-1], ret[0].decode(
                "utf-8")[0:-1].split(os.linesep)))

            for i, op in enumerate(ops):
                operators[op] = int(ios[i][1:len(ios[i]) - 1].split('|')[1])

        return operators  # }}}

    # execute a single CDO command line {{{
    def __call(self, cmd, envOfCall={}):
        if self.logging and '-h' != cmd[1]:
            self.logger.info(u' '.join(cmd))

        env = dict(self.env)
        env.update(envOfCall)

        proc = subprocess.Popen(' '.join(cmd),
                                shell=True,
                                stderr=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                env=env)

        retvals = proc.communicate()
        stdout = retvals[0].decode("utf-8")
        stderr = retvals[1].decode("utf-8")

        if self.debug:  # debug printing {{{
            print('# DEBUG - start =============================================================')
            # if {} != env:
            #     for k,v in list(env.items()):
            #         print("ENV: " + k + " = " + v)
            print('CALL  :' + ' '.join(cmd))
            print('STDOUT:')
            if 0 != len(stdout.strip()):
                print(stdout)
            print('STDERR:')
            if 0 != len(stderr.strip()):
                print(stderr)
            # }}}
            print('# DEBUG - end ===============================================================')

        return {"stdout": stdout, "stderr": stderr, "returncode": proc.returncode}  # }}}

    # error handling for CDO calls {{{
    def __hasError(self, method_name, cmd, retvals):
        if self.debug:
            print("RETURNCODE:" + retvals["returncode"].__str__())
        if self.__exit_success(method_name) < retvals["returncode"]:
            print("Error in calling operator " + method_name + " with:")
            print(">>> " + ' '.join(cmd) + "<<<")
            print('STDOUT:' + retvals["stdout"])
            print('STDERR:' + retvals["stderr"])

            if self.logging:
                self.logger.error(cmd + " with:" + retvals["stderr"])
            return True
        else:
            return False  # }}}

    # {{{ attempt to load optional libraries: netcdf-IO + XArray
    # numpy is a dependency of both, so no need to check that
    def __loadOptionalLibs(self):
        try:
            import xarray
            self.hasXarray = True
            self.xa_open = xarray.open_dataset
        except Exception:
            print("-->> Could not load xarray!! <<--")

        try:
            from netCDF4 import Dataset as cdf
            import numpy as np
            self.hasNetcdf = True
            self.cdf = cdf
            self.np = np
        except Exception:
            print("-->> Could not load netCDF4! <<--")  # }}}

    def infile(self, *infiles): #{{{
        for infile in infiles:
            if isinstance(infile, six.string_types):
                self._cmd.append(infile)
            elif self.hasXarray:
                import xarray  # <<-- python2 workaround
                if type(infile) == xarray.core.dataset.Dataset:
                    # create a temp nc file from input data
                    tmpfile = self.tempStore.newFile()
                    infile.to_netcdf(tmpfile)
                    self._cmd.append(tmpfile)
        return self #}}}

    def add_option(self, *options): #{{{
        self._options = self._options + list(options)
        return self #}}}

    def __call__(self, *args, **kwargs):
        user_kwargs = kwargs.copy()
        try:
            method_name = self._cmd[0][1:].split(',')[0]
        except IndexError:
            method_name = ''
        operatorPrintsOut = method_name in self.noOutputOperators

        self.envByCall = {}

        # Build the cdo command
        # 0. the cdo command itself
        cmd = [self.CDO]

        # 1. OVERWRITE EXISTING FILES
        cmd.append('-O')

        # 2. set the options
        # show full output in case of diff-like operators
        # or user requested the non-silent mode directly
        if (not method_name in self.DiffOperators) and self.silent:
            cmd.append('-s')
        cmd.extend(self._options)
        # switch to netcdf output in case of numpy/xarray usage
        if kwargs.get('returnArray') is not None \
           or kwargs.get('returnMaArray') is not None \
           or kwargs.get('returnXArray') is not None \
           or kwargs.get('returnXDataset') is not None \
           or kwargs.get('returnCdf') is not None:
            cmd.append('-f nc')
        if 'options' in kwargs:
            cmd += kwargs['options'].split()

        # 3. add operators
        # collect operator parameters and pad them to the operator name
        if len(args) != 0:
            self._cmd[-1] += ',' + ','.join(map(str, args))
        if self._cmd:
            cmd.extend(self._cmd)

        # 4. input files or other operators
        if 'input' in kwargs:
            if isinstance(kwargs["input"], six.string_types):
                cmd.append(kwargs["input"])
            elif type(kwargs["input"]) == list:
                cmd.append(' '.join(kwargs["input"]))
            elif self.hasXarray:
                import xarray  # <<-- python2 workaround
                if type(kwargs["input"]) in [xarray.core.dataset.Dataset,xarray.core.dataarray.DataArray]:
                    # create a temp nc file from input data
                    tmpfile = self.tempStore.newFile()
                    kwargs["input"].to_netcdf(tmpfile)
                    kwargs["input"] = tmpfile

                    cmd.append(kwargs["input"])
            else:
                # we assume it's either a list, a tuple or any iterable.
                cmd.append(kwargs["input"])

        # 5. handle rewrite of existing output files
        if not kwargs.__contains__("force"):
            kwargs["force"] = self.forceOutput

        # 6. handle environment setup per call
        envOfCall = {}
        if kwargs.__contains__("env"):
            for k, v in kwargs["env"].items():
                envOfCall[k] = v

        # 7. output handling: use given outputs or create temporary files
        outputs = []

        # collect the given output
        if kwargs.get("output") is not None:
            outputs.append(kwargs["output"])

        if not user_kwargs or not kwargs.get('compute', True):
            return self
        elif not kwargs.get('keep', True):
            self._cmd.clear()

        if operatorPrintsOut:
            retvals = self.__call(cmd, envOfCall)
            if not self.__hasError(method_name, cmd, retvals):
                r = list(map(strip, retvals["stdout"].split(os.linesep)))
                if "autoSplit" in kwargs:
                    splitString = kwargs["autoSplit"]
                    _output = [x.split(splitString) for x in r[:len(r) - 1]]
                    if 1 == len(_output):
                        return _output[0]
                    else:
                        return _output
                else:
                    return r[:len(r) - 1]
            else:
                if self.returnNoneOnError:
                    return None
                else:
                    raise CDOException(**retvals)
        else:
            if kwargs["force"] or \
               (kwargs.__contains__("output") and not os.path.isfile(kwargs["output"])):
                if not kwargs.__contains__("output") or kwargs["output"] is None:
                    for i in range(0, self.operators[method_name]):
                        outputs.append(self.tempStore.newFile())

                cmd.append(' '.join(outputs))

                retvals = self.__call(cmd, envOfCall)
                if self.__hasError(method_name, cmd, retvals):
                    if self.returnNoneOnError:
                        return None
                    else:
                        raise CDOException(**retvals)
            else:
                if self.debug:
                    print(("Use existing file'" + kwargs["output"] + "'"))

        # defaults for file handles as return values
        if not kwargs.__contains__("returnCdf"):
            kwargs["returnCdf"] = False
        if not kwargs.__contains__("returnXDataset"):
            kwargs["returnXDataset"] = False

        # return data arrays
        if kwargs.get("returnArray") is not None:
            return self.readArray(outputs[0], kwargs["returnArray"])
        elif kwargs.get("returnMaArray") is not None:
            return self.readMaArray(outputs[0], kwargs["returnMaArray"])
        elif kwargs.get("returnXArray") is not None:
            return self.readXArray(outputs[0], kwargs.get("returnXArray"))

        # return files handles (or lists of them)
        elif kwargs["returnCdf"]:
            if 1 == len(outputs):
                return self.readCdf(outputs[0])
            else:
                return [self.readCdf(file) for file in outputs]
        elif kwargs["returnXDataset"]:
            if 1 == len(outputs):
                return self.readXDataset(outputs[0])
            else:
                return [self.readXDataset(file) for file in outputs]

        # handle split-operator outputs
        elif 'split' == method_name[0:5]:
            return glob.glob(kwargs["output"] + '*')

        # default: return filename (given or tempfile)
        else:
            if 1 == len(outputs):
                return outputs[0]
            else:
                return outputs

    def __getattr__(self, method_name):  # main method-call handling for Cdo-objects {{{
        if any(method_name in opts for opts in (
               self.__dict__, self.operators, self.AliasOperators)):
            if self.debug:
                print(("Found operator:" + method_name))

            # cache the method for later
            class Operator(self.__class__):
                name = method_name
                __name__ = method_name
                __qualname__ = getattr(  # __qualname__ is available in python 3.3+
                    self.__class__, '__qualname__', self.__class__.__name__
                ) + '.' + method_name

                def __init__(self, *args, **kwargs):
                    super().__init__(*args, **kwargs)
                    self.__doc__ = operator_doc(method_name, self.CDO)

            setattr(self.__class__, method_name, Operator())
            return getattr(self, method_name)
        else:
            # given method might match part of know operators: autocompletion
            func = lambda x: re.search(method_name, x)
            options = list(filter(func, self.operators))
            message = "Unknown operator '" + method_name + "'!"
            if 0 != len(options):
                message += " Did you mean: " + ", ".join(options) + "?"
            raise AttributeError(message)
    # }}}

    # try to find out the possible output formats {{{
    # This can be replaces by the parsing of the --config option output in 2.x releases
    def getSupportedLibs(self):
        proc = subprocess.Popen(self.CDO + ' -V',
                                shell=True,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT)
        retvals = proc.communicate()
        withs = list(re.findall('(with|Features): (.*)',
                                retvals[0].decode("utf-8"))[0])[1].split(' ')

        # do an additional split if the entry has a /
        # and collect everything into a flatt list
        withs = list(map(lambda x: x.split('/') if re.search(r'\/', x) else x, withs))
        allWiths = []
        for _withs in withs:
            if isinstance(_withs, list):
                for __withs in _withs:
                    allWiths.append(__withs)
            else:
                allWiths.append(_withs)
        withs = allWiths

        libs = re.findall(r'(\w+) library version : (\d+\.\S+) ',
                          retvals[0].decode("utf-8"))
        libraries = dict({})
        for w in withs:
            libraries[w.lower()] = True

        for lib in libs:
            l, v = lib
            libraries[l.lower()] = v

        return libraries #}}}

    def collectLogs(self):
        if isinstance(self.logFile, six.string_types):
            content = []
            with open(self.logFile, 'r') as f:
                content.append(f.read())
            return ''.join(content)
        else:
            self.logFile.flush()
            return self.logFile.getvalue()

    def showLog(self):
        print(self.collectLogs())

    # check if the current (or given) CDO binary works
    def hasCdo(self, path=None):
        if path is None:
            path = self.CDO
        cmd = [path, ' -V', '>/dev/null 2>&1']
        executable = (0 == self.__call(cmd)["returncode"])
        fullpath = (os.path.isfile(path) and os.access(path, os.X_OK))
        return (executable or fullpath)

    # selfcheck for the current CDO binary
    def check(self):
        if not self.hasCdo():
            return False
        if self.debug:
            print(self.__call([self.CDO, ' -V']))
        return True

    # change the CDO binary for the current object
    def setCdo(self, value):
        self.CDO = value
        self.operators = self.__getOperators()

    # return the path to the CDO binary currently used
    def getCdo(self):
        return self.CDO

    def hasLib(self, lib):
        return lib in self.libs

    def libsVersion(self, lib):
        if not self.hasLib(lib):
            raise AttributeError("Cdo does NOT have support for '#{lib}'")
        else:
            if self.libs[lib] is not True:
                return self.libs[lib]
            else:
                print("No version information available about '" + lib + "'")
                return False

    def cleanTempDir(self):
        self.tempStore.cleanTempDir()

    # make use of internal documentation structure of python
    def __dir__(self):
        res = dir(type(self)) + list(self.__dict__)
        res.extend(list(self.operators))
        return res

    # ==================================================================
    # Addional operators:
    # ------------------------------------------------------------------

    def version(self, verbose=False):
        # return CDO's version
        return getCdoVersion(self.CDO, verbose)

    def boundaryLevels(self, **kwargs):
        ilevels = list(map(float, self.showlevel(input=kwargs['input'])[0].split()))
        bound_levels = []
        bound_levels.insert(0, 0)
        for i in range(1, len(ilevels) + 1):
            bound_levels.insert(
                i, bound_levels[i - 1] + 2 * (ilevels[i - 1] - bound_levels[i - 1]))

        return bound_levels

    def thicknessOfLevels(self, **kwargs):
        bound_levels = self.boundaryLevels(**kwargs)
        delta_levels = []
        for i in range(0, len(bound_levels)):
            v = bound_levels[i]
            if 0 == i:
                continue

            delta_levels.append(v - bound_levels[i - 1])

        return delta_levels

    def run(self, output=None):
        if output:
            return self(output=output, compute=True)
        else:
            return self(compute=True)

    def readCdf(self, iFile=None):
        """Return a cdf handle created by the available cdf library"""
        if iFile is None:
            iFile = self.run()
        if self.hasNetcdf:
            fileObj = self.cdf(iFile, mode='r')
            return fileObj
        else:
            print("Could not import data from file '%s' (python-netCDF4)" % iFile)
            six.raise_from(ImportError, None)

    def readArray(self, iFile=None, varname=None):
        """Direcly return a numpy array for a given variable name"""
        if iFile is None:
            iFile = self.run()
        if varname is None:
            raise ValueError("A varname needs to be specified!")
        filehandle = self.readCdf(iFile)
        try:
            # return the data array for given variable name
            return filehandle.variables[varname][:].copy()
        except Exception:
            print("Cannot find variable '%s'" % varname)
            six.raise_from(LookupError, None)

    def readMaArray(self, iFile=None, varname=None):  # {{{
        """Create a masked array based on cdf's FillValue"""
        if iFile is None:
            iFile = self.run()
        if varname is None:
            raise ValueError("A varname needs to be specified!")
        fileObj = self.readCdf(iFile)

        if varname not in fileObj.variables:
            print("Cannot find variables '%s'" % varname)
            six.raise_from(LookupError, None)
        else:
            data = fileObj.variables[varname][:].copy()

        if hasattr(fileObj.variables[varname], '_FillValue'):
            # return masked array
            retval = self.np.ma.array(
                data, mask=data == fileObj.variables[varname]._FillValue)
        else:
            # generate dummy mask which is always valid
            retval = self.np.ma.array(data, mask=data != data)

        return retval  # }}}

    def readXArray(self, ifile=None, varname=None):
        if ifile is None:
            ifile = self.run()
        if varname is None:
            raise ValueError("A varname needs to be specified!")
        if not self.hasXarray:
            print("Could not load XArray")
            six.raise_from(ImportError, None)

        dataSet = self.xa_open(ifile)
        try:
            return dataSet[varname]
        except Exception:
            print("Cannot find variable '%s'" % varname)
            six.raise_from(LookupError, None)

    def readXDataset(self, ifile=None):
        if ifile is None:
            ifile = self.run()
        if not self.hasXarray:
            print("Could not load XArray")
            six.raise_from(ImportError, None)

        return self.xa_open(ifile)

    def __print__(self, context=''):
        if '' != context:
            print('CDO:CONTEXT ' + context)
        print("CDO:ID  = " + str(id(self)))
        print("CDO:ENV = " + str(self.env))
# }}}

# Helper module for easy temp file handling {{{

class CdoTempfileStore(object):

    __tempfiles = []

    def __init__(self, dir):
        self.persistent_tempfile = False
        self.fileTag = 'cdoPy'
        self.dir = dir
        if not os.path.isdir(dir):
            os.makedirs(dir)
        # handling different exits from interactive sessions
        # python3 has threading.main_thread(), but python2 doesn't
        if sys.version_info[0] == 2 \
                or threading.current_thread() is threading.main_thread():
            for sig in (signal.SIGINT, signal.SIGTERM, signal.SIGSEGV):
                sig_default = signal.getsignal(sig)
                sig_wrapped = functools.partial(self.__catch__, throw=sig_default)
                signal.signal(sig, sig_wrapped)
                signal.siginterrupt(sig, False)

    def __del__(self):
        # remove temporary files
        for filename in self.__class__.__tempfiles:
            if os.path.isfile(filename):
                os.remove(filename)

    def __catch__(self, signum, frame, throw=None, **kwargs):
        # if a termination signal could be caught, remove tempfile
        self.__del__()
        if callable(throw):
            throw(signum, frame, **kwargs)
        else:
            print("caught signal", signum, frame)

    def cleanTempDir(self):
        leftOvers = [os.path.join(self.dir, f) for f in os.listdir(self.dir)]
        # filter for cdo.py's tempfiles owned by you
        leftOvers = [f for f in leftOvers if
                     self.fileTag in f
                     and os.path.isfile(f)
                     and os.stat(f).st_uid == os.getuid()]
        # this might lead to trouble if it is used by server side computing like
        # jupyter notebooks, filtering by userid might no be enough
        for f in leftOvers:
            os.remove(f)

    def setPersist(self, value):
        self.persistent_tempfiles = value

    def newFile(self):
        if not self.persistent_tempfile:
            t = tempfile.NamedTemporaryFile(
                delete=True, prefix=self.fileTag, dir=self.dir)
            self.__class__.__tempfiles.append(t.name)
            t.close()

            return t.name
        else:
            N = 10000000
            return "_" + random.randint(0, N).__str__()
# }}}

# vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 fdm=marker


# if n even , divide by 2
# if n is odd , multi by 3 and add 1
# find number of steps to reach 1

i=1
while True:
    num=int(input("enter the number greater than 1:"))

    if num>1:
        while True:
            if num/2==1:
                break
            elif num%2==0:
                num/=2
                i+=1
            elif num%2==1 and num/2!=1:
                num=(num*3)+1
                i+=1

        break

    else:
        print("enter the number again:")
        continue

print("the number of steps taken to reach 1 is :", i)