from sklearn.model_selection import GridSearchCV
from sklearn.metrics import roc_auc_score, roc_curve, auc
from sklearn.metrics import average_precision_score, precision_recall_curve
from sklearn.metrics import mean_absolute_error, mean_squared_error
from sklearn.linear_model import LogisticRegression, LinearRegression
from sklearn.externals import joblib
import math
import numpy as np
import pandas as pd
import sys
import matplotlib.pyplot as plt

def clfreport(modeltype,
              debug,
              devcheck,
              algo,
              X_train,
              y_train,
              X_test,
              y_test=None,
              param=None,
              cores=4,
              tune=False,
              use_saved_model=False,
              col_list=None):
    """

    Parameters
    ----------
    modeltype
    debug
    devcheck
    algo
    X_train
    y_train
    X_test
    y_test
    param
    cores
    tune
    use_saved_model
    col_list

    Returns
    -------

    """

    # Initialize conditional vars that depend on ifelse to avoid PC warnng
    y_pred_class = None
    y_pred = None

    if devcheck == 'yesdev':

        if tune:
            clf = GridSearchCV(algo,
                               param,
                               cv=5,
                               scoring='roc_auc',
                               n_jobs=cores)
        else:
            clf = algo

        if debug:
            print('\nclf object right before fitting main model:')
            print(clf)

        if modeltype == 'classification':
            y_pred = np.squeeze(clf.fit(X_train, y_train).predict_proba(
                X_test)[:, 1])
            #y_pred_class = clf.fit(X_train, y_train).predict(X_test)
        elif modeltype == 'regression':
            y_pred = clf.fit(X_train, y_train).predict(X_test)

        print('\n', algo)
        print("Best hyper-parameters found after tuning:")

        if hasattr(clf, 'best_params_') and tune:
            print(clf.best_params_)
        else:
            print("No hyper-parameter tuning was done.")

        if modeltype == 'classification':
            print('\nMetrics:')
            roc_auc = roc_auc_score(y_test, y_pred)
            print('AU_ROC Score:', roc_auc)

            precision, recall, thresholds = precision_recall_curve(y_test, y_pred)
            pr_auc = auc(recall, precision)
            print('\nAU_PR Score:', pr_auc)

        elif modeltype == 'regression':
            print('##########################################################')
            print('Model accuracy:')
            print('\nRMSE error:', math.sqrt(mean_squared_error(y_test,
                                                                y_pred)))
            print('\nMean absolute error:', mean_absolute_error(y_test,
                                                                y_pred), '\n')
            print('##########################################################')

        # TODO: refactor this logic to be simpler
        # Return without printing variable importance for linear case
        if (not hasattr(clf, 'feature_importances_')) and (not
            hasattr(clf, 'best_estimator_')):

            return y_pred, roc_auc

        # Print variable importance if rf and not tuning
        elif hasattr(clf, 'feature_importances_'):
            write_feature_importances(clf.feature_importances_,
                                          col_list)

            return y_pred, roc_auc, clf

        # Print variable importance if rf and tuning
        elif hasattr(clf.best_estimator_, 'feature_importances_'):
            write_feature_importances(
                clf.best_estimator_.feature_importances_,
                col_list)

            return y_pred, roc_auc, clf

    elif devcheck == 'notdev':

        clf = algo

        if use_saved_model is True:

            clf = joblib.load('probability.pkl')

        else:

            if debug:
                print('\nclf object right before fitting main model:')

            clf.fit(X_train, y_train)

            joblib.dump(clf, 'probability.pkl', compress=1)

        if modeltype == 'classification':
            y_pred = np.squeeze(clf.predict_proba(X_test)[:, 1])
        elif modeltype == 'regression':
            y_pred = clf.predict(X_test)

    return y_pred

def findtopthreefactors(debug,
                        X_train,
                        y_train,
                        X_test,
                        modeltype,
                        use_saved_model):

    # Initialize conditional vars that depend on ifelse to avoid PC warnng
    clf = None

    if modeltype == 'classification':
        clf = LogisticRegression()

    elif modeltype == 'regression':
        clf = LinearRegression()

    if use_saved_model is True:

        clf = joblib.load('factorlogit.pkl')

    elif use_saved_model is False:

        if modeltype == 'classification':

            if debug:
                print('\nclf object right before fitting factor ranking model')
                print(clf)

            clf.fit(X_train, y_train).predict_proba(X_test)

        elif modeltype == 'regression':

            if debug:
                print('\nclf object right before fitting factor ranking model')
                print(clf)

            clf.fit(X_train, y_train).predict(X_test)

        joblib.dump(clf, 'factorlogit.pkl', compress=1)

    if debug:
        print('\nCoeffs right before multiplic. to determine top 3 factors')
        print(clf.coef_)
        print('\nX_test right before this multiplication')
        print(X_test.loc[:3, :])

    # Populate X_test array of ordered col importance;
    # Start by multiplying X_test vals by coeffs
    res = X_test.values * clf.coef_

    if debug:
        print('\nResult of coef * Xtest row by row multiplication')
        for i in range(0, 3):
            print(res[i, :])

    col_list = X_test.columns.values

    first_fact = []
    second_fact = []
    third_fact = []

    if debug:
        print('\nSorting column importance rankings for each row in X_test...')

    # TODO: switch 2-d lists to numpy array
    # (although would always convert back to list for ceODBC
    for i in range(0, len(res[:, 1])):
        list_of_indexrankings = np.array((-res[i]).argsort().ravel())
        first_fact.append(col_list[list_of_indexrankings[0]])
        second_fact.append(col_list[list_of_indexrankings[1]])
        third_fact.append(col_list[list_of_indexrankings[2]])

    if debug:
        print('\nTop three factors for top five rows:')  # pretty-print w/ df
        print(pd.DataFrame({'first': first_fact[:3],
                            'second': second_fact[:3],
                            'third': third_fact[:3]}))

    return first_fact, second_fact, third_fact

def write_feature_importances(importance_attr, col_list):
    """
    This function prints an ordered list of rf-related feature importance.

    Parameters
    ----------
    importance_attr (attribute) : This is the feature importance attribute
    from a scikit-learn method that represents feature importances
    col_list (list) : Vector holding list of column names

    Returns
    -------
    Nothing. Simply prints feature importance list to console.
    """
    indices = np.argsort(importance_attr)[::-1]
    print('\nVariable importance:')
    for f in range(0, len(col_list)):
        print("%d. %s (%f)" % (f + 1, col_list[indices[f]],
                               importance_attr[indices[f]]))

def calculate_rfmtry(number_of_columns, type):
    if number_of_columns < 3:
        message = "You need more than two columns to tune hyperparameters."
        raise ValueError(message)

    if type == 'classification':
        # Default to grid of 1,2,3 for start of less than 2
        start_temp = math.floor(math.sqrt(number_of_columns))
        start = start_temp if start_temp >= 2 else 2
        grid_mtry = [start-1,start,start+1]

    if type == 'regression':
        # Default to grid of 1,2,3 for start of less than 2
        start_temp = math.floor(number_of_columns/3)
        start = start_temp if start_temp >= 2 else 2
        grid_mtry = [start-1,start,start+1]

    return grid_mtry

def GenerateAUC(predictions, labels, aucType='SS', plotFlg=False, allCutoffsFlg=False):
    """
    This function creates an ROC or PR curve and calculates the area under it.

    Parameters
    ----------
    predictions (list) : predictions coming from an ML algorithm of length n.
    labels (list) : true label values corresponding to the predictions. Also length n.
    aucType (str) : either 'SS' for ROC curve or 'PR' for precision recall curve. Defaults to 'SS'
    plotFlg (bol) : True will return plots. Defaults to False.
    allCutoffsFlg (bol) : True will return plots. Defaults to False.

    Returns
    -------
    AUC (float) : either AU_ROC or AU_PR
    """
    # Error check for uneven length predictions and labels
    if len(predictions) != len(labels):
        raise Exception('Data vectors are not equal length!')

    # make AUC type upper case.
    aucType = aucType.upper()

    # check to see if AUC is SS or PR. If not, default to SS
    if aucType != 'SS' and aucType != 'PR':
        print('Drawing ROC curve with Sensitivity/Specificity')
        aucType = 'SS'

    # Compute ROC curve and ROC area
    if aucType == 'SS':
        fpr, tpr, thresh = roc_curve(labels, predictions)
        area = auc(fpr, tpr)
        print('Area under ROC curve (AUC): %0.2f' % area)
        # get ideal cutoffs for suggestions
        d = (fpr - 0)**2 + (tpr - 1)**2
        ind = np.where(d == np.min(d))
        bestTpr = tpr[ind]
        bestFpr = fpr[ind]
        cutoff = thresh[ind]
        print("Ideal cutoff is %0.2f, yielding TPR of %0.2f and FPR of %0.2f" % (cutoff, bestTpr, bestFpr))
        if allCutoffsFlg is True:
            print('%-7s %-6s %-5s' % ('Thresh', 'TPR', 'FPR'))
            for i in range(len(thresh)):
                print('%-7.2f %-6.2f %-6.2f' % (thresh[i], tpr[i], fpr[i]))

        # plot ROC curve
        if plotFlg is True:
            plt.figure()
            plt.plot(fpr, tpr, color='darkorange',
                     lw=2, label='ROC curve (area = %0.2f)' % area)
            plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
            plt.xlim([0.0, 1.0])
            plt.ylim([0.0, 1.05])
            plt.xlabel('False Positive Rate')
            plt.ylabel('True Positive Rate')
            plt.title('Receiver operating characteristic curve')
            plt.legend(loc="lower right")
            plt.show()
        return ({'AU_ROC': area,
                 'BestCutoff': cutoff[0],
                 'BestTpr': bestTpr[0],
                 'BestFpr': bestFpr[0]})
    # Compute PR curve and PR area
    else: # must be PR
        # Compute Precision-Recall and plot curve
        precision, recall, thresh = precision_recall_curve(labels, predictions)
        area = average_precision_score(labels, predictions)
        print('Area under PR curve (AU_PR): %0.2f' % area)
        # get ideal cutoffs for suggestions
        d = (precision - 1) ** 2 + (recall - 1) ** 2
        ind = np.where(d == np.min(d))
        bestPre = precision[ind]
        bestRec = recall[ind]
        cutoff = thresh[ind]
        print( "Ideal cutoff is %0.2f, yielding TPR of %0.2f and FPR of %0.2f"
               % (cutoff, bestPre, bestRec))
        if allCutoffsFlg is True:
            print('%-7s %-10s %-10s' % ('Thresh', 'Precision', 'Recall'))
            for i in range(len(thresh)):
                print('%5.2f %6.2f %10.2f' %(thresh[i],precision[i], recall[i]))

        # plot PR curve
        if plotFlg is True:
            # Plot Precision-Recall curve
            plt.figure()
            plt.plot(recall, precision, lw=2, color='darkred',
                     label='Precision-Recall curve' % area)
            plt.xlabel('Recall')
            plt.ylabel('Precision')
            plt.ylim([0.0, 1.05])
            plt.xlim([0.0, 1.0])
            plt.title('Precision-Recall AUC={0:0.2f}'.format(
                area))
            plt.legend(loc="lower right")
            plt.show()
        return({'AU_PR':area,
                'BestCutoff':cutoff[0],
                'BestPrecision':bestPre[0],
                'BestRecall':bestRec[0]})

if __name__ == "__main__":
    pass


"""
Learn to apply different geometric transformation to images
    like translation, rotation, affine transformation etc.
"""

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

def scale():
    """
    对图片进行缩放的两种方法
    """
    img = cv.imread(r'../resources/messi5.jpg')
    cv.imshow(winname='image', mat=img)
    cv.waitKey(0)
    # 对图片进行 x ， y上的缩放
    res = cv.resize(img, None, fx=0.5, fy=0.5, interpolation=cv.INTER_CUBIC)
    cv.imshow(winname='image', mat=res)
    cv.waitKey(0)
    height, width = img.shape[:2]
    # 将图片缩放到指定大小
    res = cv.resize(img, (2*width, 2*height), interpolation=cv.INTER_CUBIC)
    cv.imshow(winname='image', mat=res)
    cv.waitKey(0)

    cv.destroyAllWindows()

def translation():
    """
    对图片进行平移操作，使用函数  cv.warpAffine() 针对灰色处理后的数据
    向量公式
     M = | 1  0 tx |
        | 0  1 ty |
    :return:
    """
    img = cv.imread(r'../resources/messi5.jpg', flags=cv.IMREAD_GRAYSCALE)
    rows, cols = img.shape
    # 分别在x，y上正向移动 100,50
    M = np.float32([[1, 0, 100], [0, 1, 50]])
    # 进行向量计算获取目标数据
    dst = cv.warpAffine(img, M, (cols, rows))

    cv.imshow('img', img)
    cv.imshow('dst', dst)
    cv.waitKey(0)
    cv.destroyAllWindows()

def rotation():
    """
    对图片进行旋转
    普通旋转的 使用向量：
    M=[cosθ−sinθ
       sinθcosθ]
    但 openCV中支持旋转带缩放，使用向量
    M=[ α β (1−α)⋅center.x−β⋅center.y
       −β α β⋅center.x+(1−α)⋅center.y]
    其中 α=scale⋅cosθ, β=scale⋅sinθ
    M 使用 getRotationMatrix2D 来获取
    """
    img = cv.imread(r'../resources/messi5.jpg', flags=cv.IMREAD_GRAYSCALE)
    rows, cols = img.shape
    # 参数 ： 旋转中心点，角度，放大倍数
    M = cv.getRotationMatrix2D(((cols - 1) / 2.0, (rows - 1) / 2.0), 90, 0.5)
    dst = cv.warpAffine(img, M, (cols, rows))

    cv.imshow('img', img)
    cv.imshow('dst', dst)
    cv.waitKey(0)
    cv.destroyAllWindows()

def affine_transformation():
    """
    仿射变换,变换的向量 M 可以通过 定出原图中的三个点和目标图中的三个点
    使用 cv.getAffineTransform 获取需要的向量
    """

    img = cv.imread(r'../resources/messi5.jpg')
    rows, cols, ch = img.shape
    pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
    pts2 = np.float32([[10, 100], [200, 50], [100, 250]])
    M = cv.getAffineTransform(pts1, pts2)  # 使用三个点对应的变换获取向量
    dst = cv.warpAffine(img, M, (cols, rows))
    plt.subplot(121), plt.imshow(img), plt.title('Input')
    plt.subplot(122), plt.imshow(dst), plt.title('Output')
    plt.show()

def perspective_transformation():
    """
    透视变化,变换的向量 M 可以通过 定出原图中的4个点和目标图中的4个点
    使用 cv.getPerspectiveTransform 获取需要的向量
    :return:
    """
    img = cv.imread(r'../resources/messi5.jpg')
    pts1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]])
    pts2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]])
    M = cv.getPerspectiveTransform(pts1, pts2) # 使用四个点对应的变换获取向量
    dst = cv.warpPerspective(img, M, (300, 300))
    plt.subplot(121), plt.imshow(img), plt.title('Input')
    plt.subplot(122), plt.imshow(dst), plt.title('Output')
    plt.show()

# scale()
# translation()
# rotation()
# affine_transformation()
perspective_transformation()


#!/usr/bin/env python2
#
# Take a list of websites and scan them for any version headers
# Common headers are ignored, so only version or interesting ones are shown
# Sites with the same headers are merged in the output
# Usage: $ ./headerget.py <targetfile or domain>
# Target file can be nmap or servicescan XML output (use service detection with XML)
# Otherwise target file can be plain text, with one target per line
# Missing or misconfigured security headers are also listed
#

import os
import platform
import re
import requests
import sys
import traceback
from xml.dom import minidom
import OpenSSL

class col:
    if sys.stdout.isatty() and platform.system() != "Windows":
        green = '\033[32m'
        blue = '\033[94m'
        red = '\033[31m'
        brown = '\033[33m'
        end = '\033[0m'
    else:   # Colours mess up redirected output, disable them
        green = ""
        blue = ""
        red = ""
        brown = ""
        end = ""

# Parse Nmap XML file
def xmlparse_nmap(xmldoc):
    hostlist = xmldoc.getElementsByTagName("host")
    for hostNode in hostlist :
        addressNode = hostNode.getElementsByTagName("address")
        host = addressNode[0].attributes["addr"].value
        ports = hostNode.getElementsByTagName("ports")
        try:
            portlist = ports[0].getElementsByTagName("port")
        except:
            continue
        for portNode in portlist:
            protocol = portNode.attributes["protocol"].value
            # Only interested in TCP
            if protocol != "tcp":
                continue
            port = portNode.attributes["portid"].value
            stateNode = portNode.getElementsByTagName("state")
            state = stateNode[0].attributes["state"].value
            serviceNode = portNode.getElementsByTagName("service")
            try:
                service = serviceNode[0].attributes["name"].value
            except:
                continue
            try:
                tunnel = serviceNode[0].attributes["tunnel"].value
            except:
                tunnel = ""

            if state == "open" and service == "http" and port == "80" and tunnel == "":
                target = "http://" + host
            elif state == "open" and service == "http" and tunnel == "":
                target = "http://" + host + ":" + port
            elif state == "open" and service == "http" and port == "443" and tunnel == "ssl":
                target = "https://" + host
            elif state == "open" and service == "http" and tunnel == "ssl":
                target = "https://" + host + ":" + port
            # If we don't have service info, just catch http/https based on port
            elif state == "open" and port == "80":
                target = "http://" + host
            elif state == "open"  and port == 443:
                target = "https://" + host

            try:
                targets[target] = ""
            except UnboundLocalError:
                pass

# Parse servicescan XML file
def xmlparse_servicescan(xmldoc):
    hostlist = xmldoc.getElementsByTagName("host")
    for hostNode in hostlist :
        host = hostNode.attributes["address"].value
        portlist = hostNode.getElementsByTagName("port")
        for portNode in portlist:
            protocol = portNode.attributes["protocol"].value
            # Only interested in TCP
            if protocol != "TCP":
                continue
            port = portNode.attributes["number"].value
            state = portNode.attributes["state"].value
            desc = portNode.attributes["description"].value
            if state == "open" and desc == "HTTP" and port == "80":
                target = "http://" + host
            elif state == "open" and (desc == "HTTP" or desc == "HTTP-ALT"):
                target = "http://" + host + ":" + port
            elif state == "open" and desc == "HTTPS" and port == "443":
                target = "https://" + host
            elif state == "open" and desc == "HTTPS":
                target = "https://" + host + ":" + port

            try:
                targets[target] = ""
            except UnboundLocalError:
                pass

# Parse targets (xml)
def xmlparse ():
    xmldoc = minidom.parse(sys.argv[1])
    if xmldoc.getElementsByTagName("nmaprun"):
        xmlparse_nmap(xmldoc)
    elif xmldoc.getElementsByTagName("servicescan"):
        xmlparse_servicescan(xmldoc)
    else:
        print(col.red + "Invalid XML file" + col.end)
        sys.exit(1)

# Parse targets (txt)
def txtparse():
    for line in lines:
        if not line.startswith('http'):
            line = "http://" + line
        targets[line.rstrip()] = ""

# Reverse a dictionary
def reverse_dict(dictionary):
    sorted = {}
    for k, v in dictionary.items ():
        if v:
            if v not in sorted:
                sorted [v] = []
            sorted [v].append (k)
    return sorted

# Truncate a string to 80 chars
def trunc(string):
    return (string[:75] + '[...]') if len(string) > 80 else string

# Check for missing/bad security headers
def check_security_headers(target, headers):
    # X-Frame-Options
    try:
        m = re.search("SAMEORIGIN|DENY", headers["x-frame-options"], re.IGNORECASE)
        if not m:
            badheaders[target] += "x-frame-options: " + trunc(headers["x-frame-options"]) +"\n"
    except Exception as e:
        missingsecurity[target] += "x-frame-options\n"

    # X-Content-Type-Options: nosniff
    try:
        m = re.search("nosniff", headers["x-content-type-options"], re.IGNORECASE)
        if not m:
            badheaders[target] += "x-content-type-options\n"
    except:
        missingsecurity[target] += "x-content-type-options\n"

    # X-XSS-Protection
    try:
        m = re.search("0", headers["x-xss-protection"], re.IGNORECASE)
        if m:
            badheaders[target] += "x-xss-protection: " + trunc(headers["x-xss-protection"]) + "\n"
    except:
        pass

    # Strict-Transport-Security (HSTS)
    try:
        m = re.search("max-age=(\d+)", headers["strict-transport-security"], re.IGNORECASE)
        if int(m.group(1)) < (60*60*24 * 30):     # Flag if less than 30 days
            badheaders[target] += "strict-transport-security: " + trunc(headers["strict-transport-security"]) +"\n"
    except:
        missingsecurity[target] += "strict-transport-security\n"

    # Access-Control-Allow-Origin (CORS)
    try:
        m = re.search("\*", headers["access-control-allow-origin"], re.IGNORECASE)
        if m:
            badheaders[target] += "access-control-allow-origin: " + trunc(headers["access-control-allow-origin"]) +"\n"
    except:
        pass

    # Content-Security-Policy
    if not ("content-security-policy" in headers or "x-content-security-policy" in headers or "x-webkit-csp" in headers):
        missingsecurity[target] += "content-security-policy\n"

# Print the headers
def print_headers(headerarray):
    for headers,servers in headerarray.items():
       if not headers:
           continue
       for server in servers:
           print(col.blue + server + col.end)
       print(headers)

########
# Main #
########

# Supress warnings that we're not validating certificates
requests.packages.urllib3.disable_warnings()
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

# Get targets
targets = {}
try:
    arg = sys.argv[1]
except:
    print("\nUsage: $ " + sys.argv[0] + " <targetfile or domain>\n")
    sys.exit(1)

if arg == "-h" or arg == "--help":
    print("\nUsage: $ " + sys.argv[0] + " <targetfile or domain>\n")
    sys.exit(1)

if arg.startswith("http"):
    targets[arg] = ""
else:
    try:
        with open(sys.argv[1]) as f:
            lines = f.readlines()
    except:
        print("\nCould not open file " + arg)
        sys.exit(1)

# Parse the targets file based on extension
    if sys.argv[1].endswith("xml"):
        xmlparse()
    else:
        txtparse()

# Get list of boring headers
try:
    path = os.path.dirname(os.path.realpath(__file__)) + "/boringheaders.txt"
    boringheaders = []
    with open(path, "r") as f:
        lines = f.readlines()
        for line in lines:
            boringheaders.append(line.rstrip().lower())
except IOError:
    print("File boringheaders.txt not found")
    sys.exit(1)

# Scan the servers
headersfound = targets.copy()
missingsecurity = targets.copy()
badheaders = targets.copy()
for target in headersfound:
    if sys.stdout.isatty():
        sys.stdout.write(target + "                                        \r")
        sys.stdout.flush()
    try:
        # Timeout after 2 seconds, don't try and verify the SSL cert
        r = requests.head(target, timeout=2, verify=False)
    except requests.exceptions.RequestException:
        try:
            print("HEAD failed, trying GET")
            r = requests.get(target, timeout=2, verify=False)
        except Exception as e:
            continue
    except requests.exceptions.ReadTimeout:
        print(col.red + target + " timed out" + col.end)
        continue
    except requests.exceptions.ConnectTimeout:
        print(col.red + target + " timed out" + col.end)
        continue
    except requests.exceptions.SSLError:
        print(col.red + target + " SSL error" + col.end)
        continue
    except OpenSSL.SSL.ZeroReturnError:
        print(col.red + target + " empty response" + col.end)
        continue
    except KeyboardInterrupt:
        print("\n\nCaught KeyboardInterrupt, quitting...")
        print("Results so far:\n")
        break
    except:
        print(traceback.format_exc())
        continue

    for header in r.headers:
        if header.lower() not in boringheaders:
            h = (r.headers[header][:75] + '[...]') if len(r.headers[header]) > 80 else r.headers[header]
            headersfound[target] += header + ": " + h + "\n"
    check_security_headers(target, r.headers)

# Get rid of any trailing characters on the TTY
if sys.stdout.isatty():
    sys.stdout.write("                                                         \r")
    sys.stdout.flush()

# Interesting Headers
sorted = reverse_dict(headersfound)
if len(sorted) > 0:
    print(col.green + 'Interesting Headers' + col.end)
    print_headers(sorted)

# Missing security headers
sorted = reverse_dict(missingsecurity)
if len(sorted) > 0:
    print('\n' + col.brown + 'Missing Security Headers' + col.end)
    print_headers(sorted)

# Bad security headers
sorted = reverse_dict(badheaders)
if len(sorted) > 0:
    print('\n' + col.red + 'Bad Security Headers' + col.end)
    print_headers(sorted)


"""singular value weather model prediction table

Revision ID: 2442f07d975c
Revises: f49418d95584
Create Date: 2023-09-26 16:14:01.658515

"""
from alembic import op
import sqlalchemy as sa
from app.db.models.common import TZTimeStamp

# revision identifiers, used by Alembic.
revision = '2442f07d975c'
down_revision = 'f49418d95584'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('model_run_predictions',
                    sa.Column('id', sa.Integer(), nullable=False),
                    sa.Column('prediction_model_run_timestamp_id', sa.Integer(), nullable=False),
                    sa.Column('prediction_timestamp', TZTimeStamp, nullable=False),
                    sa.Column('tmp_tgl_2', sa.Float(), nullable=True),
                    sa.Column('rh_tgl_2', sa.Float(), nullable=True),
                    sa.Column('apcp_sfc_0', sa.Float(), nullable=True),
                    sa.Column('wdir_tgl_10', sa.Float(), nullable=True),
                    sa.Column('wind_tgl_10', sa.Float(), nullable=True),
                    sa.ForeignKeyConstraint(['prediction_model_run_timestamp_id'], [
                                            'prediction_model_run_timestamps.id'], ),
                    sa.PrimaryKeyConstraint('id'),
                    sa.UniqueConstraint('prediction_model_run_timestamp_id', 'prediction_timestamp'),
                    comment='The prediction values of a particular model run.'
                    )
    op.create_index(op.f('ix_model_run_predictions_id'), 'model_run_predictions', ['id'], unique=False)
    op.create_index(op.f('ix_model_run_predictions_prediction_model_run_timestamp_id'),
                    'model_run_predictions', ['prediction_model_run_timestamp_id'], unique=False)
    op.create_index(op.f('ix_model_run_predictions_prediction_timestamp'),
                    'model_run_predictions', ['prediction_timestamp'], unique=False)
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f('ix_model_run_predictions_prediction_timestamp'), table_name='model_run_predictions')
    op.drop_index(op.f('ix_model_run_predictions_prediction_model_run_timestamp_id'),
                  table_name='model_run_predictions')
    op.drop_index(op.f('ix_model_run_predictions_id'), table_name='model_run_predictions')
    op.drop_table('model_run_predictions')
    # ### end Alembic commands ###


import time
import gc
from datetime import datetime
from os import makedirs

import torch

from eval_run import eval_and_save_metrics
from utils import get_device, ResultWriter, log
from task import pubmed_task
from train import SentenceClassificationTrainer
from models import BertHSLN
import os

# BERT_VOCAB = "bert-base-uncased"
BERT_MODEL = "bert-base-uncased"
# BERT_VOCAB = "bert_model/scibert_scivocab_uncased/vocab.txt"
#BERT_MODEL = "allenai/scibert_scivocab_uncased"

config = {
    "bert_model": BERT_MODEL,
    "bert_trainable": False,
    "model": BertHSLN.__name__,
    "cacheable_tasks": [],

    "dropout": 0.5,
    "word_lstm_hs": 758,
    "att_pooling_dim_ctx": 200,
    "att_pooling_num_ctx": 15,

    "lr": 3e-05,
    "lr_epoch_decay": 0.9,
    "batch_size":  32,
    "max_seq_length": 128,
    "max_epochs": 20,
    "early_stopping": 5,

}

MAX_DOCS = -1
def create_task(create_func):
    return create_func(train_batch_size=config["batch_size"], max_docs=MAX_DOCS)

def create_generic_task(task_name):
    return generic_task(task_name, train_batch_size=config["batch_size"], max_docs=MAX_DOCS)

# ADAPT: Uncomment the task that has to be trained and comment all other tasks out

# ADAPT: Uncomment the task that has to be trained and comment all other tasks out
task = create_task(pubmed_task)
#task = create_task(pubmed_task_small)
#task = create_task(nicta_task)
#task = create_task(dri_task)
#task = create_task(art_task)
#task = create_task(art_task_small)
#task = create_generic_task(GEN_DRI_TASK)
#task = create_generic_task(GEN_PMD_TASK)
#task = create_generic_task(GEN_NIC_TASK)
# task = create_generic_task(GEN_ART_TASK)

# ADAPT: Set to False if you do not want to save the best model
save_best_models = True

# ADAPT: provide a different device if needed
device = get_device(0)

timestamp = datetime.now().strftime("%Y-%m-%d_%H_%M_%S")

# ADAPT: adapt the folder name of the run if necessary
run = f"{timestamp}_{task.task_name}_baseline"

# -------------------------------------------

os.makedirs("results/complete_epoch_wise_new",exist_ok=True)
#run_results = f'/nfs/data/sentence-classification/results/{run}'
run_results = f'results/{run}'
makedirs(run_results, exist_ok=False)

# preload data if not already done
task.get_folds()

restarts = 1 if task.num_folds == 1 else 1
for restart in range(restarts):
    for fold_num, fold in enumerate(task.get_folds()):
        start = time.time()
        result_writer = ResultWriter(f"{run_results}/{restart}_{fold_num}_results.jsonl")
        result_writer.log(f"Fold {fold_num} of {task.num_folds}")
        result_writer.log(f"Starting training {restart} for fold {fold_num}... ")

        trainer = SentenceClassificationTrainer(device, config, task, result_writer)
        best_model = trainer.run_training_for_fold(fold_num, fold, return_best_model=save_best_models)
        if best_model is not None:
            model_path = os.path.join(run_results, f'{restart}_{fold_num}_model.pt')
            result_writer.log(f"saving best model to {model_path}")
            torch.save(best_model.state_dict(), model_path)

        result_writer.log(f"finished training {restart} for fold {fold_num}: {time.time() - start}")

        # explicitly call garbage collector so that CUDA memory is released
        gc.collect()

log("Training finished.")

log("Calculating metrics...")
eval_and_save_metrics(run_results)
log("Calculating metrics finished")


import os
import sys
import cv2
import json
import numpy as np
import urllib.request

# load the labels
coco91_labels = ['__background__', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus',
    'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'N/A', 'stop sign',
    'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
    'elephant', 'bear', 'zebra', 'giraffe', 'N/A', 'backpack', 'umbrella', 'N/A', 'N/A',
    'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',
    'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket',
    'bottle', 'N/A', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl',
    'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
    'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'N/A', 'dining table',
    'N/A', 'N/A', 'toilet', 'N/A', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
    'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'N/A', 'book',
    'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush']
# this will help us create a different color for each class
coco91_colors = np.random.uniform(0, 255, size=(len(coco91_labels), 3))

def preprocess_imagenet(img, chw=True, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], img_size=(224,224), make_square=True):
    x = img.copy()
    h,w,c = x.shape
    if make_square:
        max_side = 0
        if h!=w: # squared - make it square to avoid distortions
            max_side = max(h,w)
            new_img = np.zeros((max_side,max_side,c), dtype=np.uint8)
            new_img[0:h, 0:w] = x[:]
            x = new_img
    x = cv2.cvtColor(x, cv2.COLOR_BGR2RGB)
    x = cv2.resize(x, img_size)
    x = (x / 255)
    x = (x - mean) / std # normalize
    if chw: x = x.transpose(2,0,1) # HWC to CHW
    x = np.expand_dims(x, 0).astype(np.float32)
    return x

def draw_boxes(boxes, classes, labels, image, img_size=300):
    """
    Draws the bounding box around a detected object.
    """
    h,w,c = image.shape
    max_side = max(h,w)
    fx,fy = max_side/img_size,max_side/img_size
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    for i, box in enumerate(boxes):
        box = (box.astype(np.float32) * (fx,fy,fx,fy)).astype(np.int32)
        #box += (0,-r,0,r)
        color = coco91_colors[labels[i]]
        cv2.rectangle(
            image,
            (int(box[0]), int(box[1])),
            (int(box[2]), int(box[3])),
            color, w//150
        )
        cv2.putText(image, classes[i], (int(box[0]), int(box[1]-5)),
                    cv2.FONT_HERSHEY_SIMPLEX, int(0.5*fx), color, int(1*fx),
                    lineType=cv2.LINE_AA)
    return image

def load_sample_imgA():
    if not os.path.exists("goldfish.jpg"):
        urllib.request.urlretrieve("https://images.unsplash.com/photo-1579161256825-57ba3094f057", "goldfish.jpg")
    return cv2.imread("goldfish.jpg")

def load_sample_imgB():
    if not os.path.exists("zidane.jpg"):
        urllib.request.urlretrieve("https://ultralytics.com/images/zidane.jpg", "zidane.jpg")
    return cv2.imread("zidane.jpg")

def load_sample_imgC():
    if not os.path.exists("man_walking.jpg"):
        urllib.request.urlretrieve("https://images.unsplash.com/photo-1611324204543-ecc01e953173", "man_walking.jpg")
    return cv2.imread("man_walking.jpg")

def load_sample_imgD():
    if not os.path.exists("signs.jpg"):
        urllib.request.urlretrieve("https://cdn-01.media-brady.com/store/stca/media/catalog/product/r/e/reflective-warning-signs-deer-crossing-ac0568-lg.jpg", "signs.jpg")
    return cv2.imread("signs.jpg")

def load_sample_imgE():
    if not os.path.exists("text.jpg"):
        urllib.request.urlretrieve("https://fki.tic.heia-fr.ch/static/img/a01-122-02.jpg", "text.jpg")
    return cv2.imread("text.jpg")

def load_imagenet1k_labels():
    # Download the labels for Imagenet 1k
    if not os.path.exists("imagenet1k.json"):
        urllib.request.urlretrieve(
            "https://raw.githubusercontent.com/anishathalye/imagenet-simple-labels/master/imagenet-simple-labels.json",
            "imagenet1k.json"
        )
    return json.loads(open('imagenet1k.json', 'r').read())

def load_coco80_labels():
    # load the labels
    if not os.path.exists("coco80.json"):
        urllib.request.urlretrieve(
            "https://raw.githubusercontent.com/amikelive/coco-labels/master/coco-labels-2014_2017.txt",
            "coco80.labels"
        )
    labels = open('coco80.labels', 'r').readlines()
    return [l.strip() for l in labels]


from secret import secret

import httplib
import json
import sys
import time

class Client:
    def __init__(self, logger = None):
        self.logger = logger
        if self.logger is None:
            self.logger = lambda x: None
        #if sys.executable[-4:] != 'pypy':
        #    self.logger('Whoa! You should be using pypy.\n')
        #    exit()

    def invoke(self, name, param):
        self.logger('Invoking %s...\n' % name)
        rq_body = json.dumps(param)
        cn = httplib.HTTPConnection('icfpc2013.cloudapp.net')
        cn.request('POST', '/' + name + '?auth=' + secret, rq_body)
        resp = cn.getresponse()
        if resp.status == 429:
            self.logger('Too many requests -- sleeping then repeating.\n')
            time.sleep(5)
            return self.invoke(name, param)
        raw = resp.read()
        data = None
        if raw is not None and raw != '':
            try:
                data = json.loads(raw)
            except ValueError:
                pass
        return resp.status, resp.reason, data

    def print_status(self):
        st, msg, resp = self.invoke('status', '')
        assert st == 200
        self.logger('\nStatus: %d\n' % st)
        self.logger('Reason: %s\n' % msg)
        self.logger('Response:\n')
        for k in resp:
            self.logger('%s: %s\n' % (k, str(resp[k])))
        self.logger('\n')

    def train(self, size = None, ops = None):
        if size is None and ops is None:
            args = ''
        else:
            args = {}
            if size is not None:
                args['size'] = size
            if ops is not None:
                args['operators'] = ops
        st, msg, resp = self.invoke('train', args)
        assert st == 200
        resp['operators'] = map(lambda x: x.encode('latin1'), resp['operators'])
        self.logger('\nStatus: %d\n' % st)
        self.logger('Reason: %s\n' % msg)
        self.logger('Response:\n')
        for k in resp:
            self.logger('%s: %s\n' % (k, str(resp[k])))
        self.logger('\n')
        return resp

    def myproblems(self):
        st, msg, resp = self.invoke('myproblems', '')
        assert st == 200
        self.logger('Total (live) problems: %d\n' % len(resp))
        resp.sort(key = lambda x: (x['timeLeft'] if 'timeLeft' in x else 1000, x['size']))
        for ix in range(len(resp)):
            resp[ix]['operators'] = map(lambda x: x.encode('latin1'), resp[ix]['operators'])
        return resp

    def guess(self, pid, code):
        st, msg, resp = self.invoke('guess', {'id': str(pid), 'program': str(code)})
        self.logger('\nStatus: %d\n' % st)
        self.logger('Reason: %s\n' % msg)
        if st == 200:
            self.logger('Response:\n')
            for k in resp:
                self.logger('%s: %s\n' % (k, str(resp[k])))
        self.logger('\n')
        if st == 412:
            return None
        return resp

    def evl(self, pid, xs):
        st, msg, resp = self.invoke('eval', {'id': pid, 'arguments': map(lambda x: x if x[-1] != 'L' else x[:-1], map(hex, xs))})
        self.logger('\nStatus: %d\n' % st)
        self.logger('Reason: %s\n' % msg)
        if st == 200:
            self.logger('Response:\n')
            for k in resp:
                if k == 'outputs':
                    continue
                self.logger('%s: %s\n' % (k, str(resp[k])))
        self.logger('\n')
        if st == 412:
            return None
        return resp


import logging
import configparser
from pathlib import Path
from urllib.request import Request, urlopen
from bs4 import BeautifulSoup as bs
from .utils import save_into_csv
from .extractors import extract_products_information
from ..utils import set_query_string_parameter_from_url

config = configparser.RawConfigParser()
config.read('{}/scraper.properties'.format(Path().absolute()))
TOTTUS = dict(config.items('TOTTUS'))

PAGINATION_INCREMENT = int(TOTTUS['pagination_increment'])
MAX_TRIES = int(TOTTUS['max_tries'])

def scrap(entries):
  print('Starting Tottus')
  logging.info('Processing Tottus')
  information = process_entries(entries)
  save_into_csv(information)
  print('Tottus done...')
  logging.info('Ending Tottus')

def should_continue(html):
  result = html.findAll('div', {'style' : 'width: 100%;height: 200px;float: left;'})
  if len(result) == 0:
    return True
  return False

def process_entries(entries):
  result = list()
  for entry in entries:
    information = process_entry(entry)
    result.extend(information)
  return result

def process_entry(entry):
  index = 0
  tries = 0
  result = list()
  while True:
    url = set_query_string_parameter_from_url(entry, 'No', index)
    print('Processing: {}'.format(url))
    request = Request(url, headers = {'User-Agent': 'Mozilla/5.0'})
    try:
      response = urlopen(request).read()
      html = bs(response, 'html.parser')
      if not should_continue(html):
        break
      products_information = extract_products_information(html)
      result.extend(products_information)
      tries = 0
    except Exception as e:
      tries += 1
      logging.error('Failure processing: {}'.format(url))
      logging.error(e)
      if tries == MAX_TRIES:
        logging.error('Skipping rest of calls: {}'.format(url))
        return result
    index += PAGINATION_INCREMENT
  return result


import cv2
import numpy as np

from argparse import ArgumentParser
from glob import glob
from pickle import dump, load
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split, cross_val_score, KFold
from time import time
from util import get_dataset

def setup_model():
    svm = load(open("credits_detection/models/svm.p", "r"))

    def is_credit(frame):
        frame = process_frame(frame)
        return svm.predict([frame]) == [[1]]

    return is_credit

def process_frame(frame):
    frame = cv2.resize(frame, (100, frame.shape[0]))
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    frame = cv2.GaussianBlur(frame, (9, 9), 0)

    col_mean = np.mean(frame, axis=0)
    col_mean = col_mean - np.min(col_mean)

    if np.max(col_mean) > 0:
        col_mean = col_mean / np.max(col_mean)

    return col_mean

def crossvalidate(model, X, y):
    scores = cross_val_score(model, X, y, cv=KFold(shuffle=True), scoring="f1")

    print("score statistics:", scores.mean(), scores.std() * 2)
    print("individual scores:", scores)

def train_and_dump_model(model, X, y):
    X_train, X_test, y_train, y_test = train_test_split(X, y)

    model.fit(X_train, y_train)
    print("score:", model.score(X_test, y_test))

    print("dumping model...")
    dump(model, open("models/svm.p", "wb"))

    print("testing on unseen data...")
    credits_X, credits_y = get_dataset(
        ["credits/john_wick.mov"], 1,
        process_frame
    )
    print("data loaded:", credits_X.shape, credits_y.shape)

    print("score:", model.score(credits_X, credits_y))

def main(cross_validate=False):
    start = time()
    print("loading data...")

    credits_X, credits_y = get_dataset(
        ["credits/mad_max.mov", "credits/under_the_skin.mov"], 1,
        process_frame, 10000
    )
    print("credits done:", credits_X.shape, credits_y.shape)

    content_X, content_y = get_dataset(
        glob("./content/*.mov"), 0,
        process_frame, 10000
    )
    print("content done:", content_X.shape, content_y.shape)
    print("took", time() - start, "sec")

    X = np.vstack((credits_X, content_X))
    y = np.vstack((credits_y, content_y)).ravel()

    model = SVC()

    if cross_validate:
        print("training model with cross-validation...")
        crossvalidate(model, X, y)
    else:
        print("training model...")
        train_and_dump_model(model, X, y)

    print("DONE")
    print("took", time() - start, "sec")

if __name__ == "__main__":
    parser = ArgumentParser(
        description="""Train a machine learning classifier to detect credit
        sequences in video files and dump the generated model to file. If
        cross-validation is activated, no model will be dumped.

        The training data needs to be stored as MOV files in the folders
        credits/ and content/ respectively.
        """
    )

    parser.add_argument(
        "--cv",
        action="store_true", default=False,
        help="Perform cross-validation and do not dump model"
    )

    args = parser.parse_args()
    main(cross_validate=args.cv)


import sys
import numpy as np
from utils.davis2017_metrics import db_eval_boundary, db_eval_iou
import utils.davis2017_utils as utils

def _evaluate_semisupervised(all_gt_masks, all_res_masks, all_void_masks, metric):
    if all_res_masks.shape[0] > all_gt_masks.shape[0]:
        sys.stdout.write("\nIn your PNG files there is an index higher than the number of objects in the sequence!")
        sys.exit()
    elif all_res_masks.shape[0] < all_gt_masks.shape[0]:
        sys.stdout.write("\nThe number of predictions is less than ground truth. Padding with zero.")
        zero_padding = np.zeros((all_gt_masks.shape[0] - all_res_masks.shape[0], *all_res_masks.shape[1:]))
        all_res_masks = np.concatenate([all_res_masks, zero_padding], axis=0)
    j_metrics_res, f_metrics_res = np.zeros(all_gt_masks.shape[:2]), np.zeros(all_gt_masks.shape[:2])
    for ii in range(all_gt_masks.shape[0]):

        if 'J' in metric:
            j_metrics_res[ii, :] = db_eval_iou(all_gt_masks[ii, ...], all_res_masks[ii, ...], all_void_masks)
            sys.stdout.flush()

        if 'F' in metric:
            f_metrics_res[ii, :] = db_eval_boundary(all_gt_masks[ii, ...], all_res_masks[ii, ...], all_void_masks)
            sys.stdout.flush()

    return j_metrics_res, f_metrics_res

def evaluate_semi(all_gt_masks, all_res_masks, metric=('J', 'F'), debug=False):
    metric = metric if isinstance(metric, tuple) or isinstance(metric, list) else [metric]
    if 'T' in metric:
        raise ValueError('Temporal metric not supported!')
    if 'J' not in metric and 'F' not in metric:
        raise ValueError('Metric possible values are J for IoU or F for Boundary')

    # Containers
    metrics_res = {}
    if 'J' in metric:
        metrics_res['J'] = {"M": [], "R": [], "D": [], "M_per_object": {}}
    if 'F' in metric:
        metrics_res['F'] = {"M": [], "R": [], "D": [], "M_per_object": {}}

    for seq, (seq_gt_masks, seq_res_masks) in enumerate(zip(all_gt_masks, all_res_masks)):

        seq_gt_masks, seq_res_masks = seq_gt_masks[:, 1:-1, :, :], seq_res_masks[:, 1:-1, :, :]
        j_metrics_res, f_metrics_res = _evaluate_semisupervised(seq_gt_masks, seq_res_masks, None, metric)

        for ii in range(seq_gt_masks.shape[0]):
            seq_name = f'{seq}_{ii+1}'
            if 'J' in metric:
                [JM, JR, JD] = utils.db_statistics(j_metrics_res[ii])
                metrics_res['J']["M"].append(JM)
                metrics_res['J']["R"].append(JR)
                metrics_res['J']["D"].append(JD)
                metrics_res['J']["M_per_object"][seq_name] = JM
            if 'F' in metric:
                [FM, FR, FD] = utils.db_statistics(f_metrics_res[ii])
                metrics_res['F']["M"].append(FM)
                metrics_res['F']["R"].append(FR)
                metrics_res['F']["D"].append(FD)
                metrics_res['F']["M_per_object"][seq_name] = FM

        # Show progress
        if debug:
            sys.stdout.write(seq + '\n')
            sys.stdout.flush()

    return metrics_res


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

hour = 3600

energies = [0.250,0.230,0.200,0.150,0.100,0.07]  # MeV
spread   = [0.1020,0.0979,0.0913,0.0790,0.0645,0.0540]
thickness = [1.,2.,3.,5.]   # cm

input_protons  = 1e7
actual_protons = 1e11
beam_time = 60  # 1 min beam time

rows = []

for i, e in enumerate(energies):
    for t in thickness:
        with open("template.txt", 'r') as templatef:
            directory = "/{rThickness}-{bEnergy:03}/".format(rThickness=round(t), bEnergy=round(1000*e))
            with open(os.getcwd() + directory + "in001_fort.28", 'r') as f:
                lines = f.readlines()

                mergedata = []
                data = []
                data = lines[17:-1]
                for i in range(len(data)):
                    data[i] = data[i].split()
                for i in range(len(data)):
                    mergedata = mergedata + data[i]
                for i in range(len(mergedata)):
                    mergedata[i]=float(mergedata[i])

                length = np.linspace(1,60,num=60)
                plt.bar(x=length,height=mergedata)
                plt.xlabel("Energy (GeV)")
                plt.ylabel("Differential Fluence per Energy (cm^-2 sr^-1 GeV^-1)")
                plt.title("E=70MeV, x=1cm")
                plt.show()

df = pd.DataFrame(mergedata)

range = np.linspace(1,60,num=60)
plt.bar(x=range,height=mergedata)
plt.xlabel("Energy (GeV)")
plt.ylabel("Differential Fluence per Energy (cm^-2 sr^-1 GeV^-1)")
plt.title("E=70MeV, x=1cm")
plt.show()

df.to_csv("Test.csv")

flukafiles/ActivationRangeShifter/20-11-18 Activation Products Data/EnergyspecTest.py


from preproces import Preprocessing
import pandas as pd
import streamlit as st
import pickle
from scraper import Scraper

st.title("Hello")
movieId = st.text_input(label="IMDB ID")
subBut = st.button("Submit")

if subBut:

    df, df_org = Scraper(movieId)

    try:
        data = Preprocessing(df)
    except:
        print("Could Not PreProcess")

    with open("logisticModel500","rb")as file:
        reviewModel = pickle.load(file)

    prediction = reviewModel.predict(data[0:100])
    df_pred = pd.DataFrame(prediction, columns =["prediction"])
    df_final = pd.concat([df, df_pred],axis = 1)

    positive = 0
    negative = 0
    for i, y in enumerate(df_org["review"]):
        if df_final["prediction"][i] == 1:
            st.text("Positive "+":- "+f'{y}')
            positive += 1
        else:
            st.text("Negative "+":- "+f'{y}')
            negative += 1

    st.header(f'Total Postitve score {positive}')
    st.header(f'Total Negative score {negative}')


#!/usr/bin/env python
import bpy
from math import log
from mathutils import Vector
from bpy.props import *

## CamAnim
## a Blender Python extension by Joshua R (GitHub user Botmasher)
##
## Ordered marking of camera locations and rotations.
## Automatic camera animation along those markers.
##

# TODO check that replace_current_markers and remove_current_markers do not break cycling or placement

# TODO adjust all markers, or all markers following currently selected one

# TODO allow for multiple cameras (currently leans on scene camera)
# - place, replace, jump, animate methods now take camera
# - check and pass currently selected camera from operators
# - update markers to store name of camera as well, allowing multiple tracks for multiple cameras

# TODO track markers (incl replace and remove) through something other than name (add uuid property?)

# TODO allow for undoing keyframing along path and resetting it

# NOTE sketch procedure to get all cameras
def get_scene_cameras():
	cams = []
	scene = bpy.context.scene
	for obj in scene.objects:
		if obj.type == 'CAMERA':
			cams.append(obj)
	return cams

# UI props for setting keyframing params
def setup_cam_ui_props():
	Cam = bpy.types.Camera
	cam.camanim_frames_per_space = FloatProperty(name="Location frames", description="How many frames to count between location units", default=3)
	Cam.camanim_frames_per_degree = FloatProperty(name="Rotation frames", description="How many frames to count between rotation degrees", default=0.1)
	Cam.camanim_min_frames_per_kf = IntProperty(name="Min in-betweens", description="Minimum number of frames between keyframes", default=0)
	Cam.camanim_max_frames_per_kf = IntProperty(name="Max in-betweens", description="Maximum number of frames between keyframes", default=9999)
	Cam.camanim_frames_pause = IntProperty(name="Pause frames", description="Length of \"long keyframes\" between movements", default=3)
	return

class CamAnim:
	def __init__(self, marker_name_text="camanim_marker"):
		# internal refs for building and storing markers
		self.sorted_markers = []                  # marker objects store cam loc-rot state
		self.marker_name_text = marker_name_text  # unique string found only in marker names - suffix added on duplication
		self.current_marker = None
		return None

	def find_highest_suffix(self):
		"""Find the highest numeral suffixed to placed marker names"""
		highest_i = 0
		found_marker = False
		for obj in bpy.context.scene.objects:
			if self.is_marker(obj):
				found_marker = True
				split_name = obj.name.split(".")
				marker_i = int(split_name[len(split_name)-1]) if len(split_name) > 0 else 0
				highest_i = marker_i if marker_i > highest_i else highest_i
		if found_marker:
			return highest_i
		else:
			return -1

	def place_marker(self, camera):
		"""Place marker in the scene at current cam loc and rot"""
		# create object
		marker = bpy.data.objects.new(name="", object_data=None)
		bpy.context.scene.objects.link(marker)
		marker.empty_draw_type = "SINGLE_ARROW"

		# orient to camera
		marker.rotation_euler = camera.rotation_euler

		# take over the duplication naming process
		# - append number to base name counting from "1"
		# - look for and increment largest suffix so far
		marker_suffix = self.find_highest_suffix() + 1
		marker.name = "{0}.{1}".format(self.marker_name_text, marker_suffix)
		marker.location = camera.location

		self.current_marker = marker
		return marker

	def replace_marker(self, camera, marker):
		"""Update selected placed marker in the scene to current cam loc and rot"""
		if not self.is_marker(marker): return
		marker.location = camera.location
		marker.rotation_euler = camera.rotation_euler
		self.current_marker = marker
		return marker

	def replace_current_marker(self, camera):
		"""Update current camera marker in the scene to a new cam loc and rot"""
		marker = self.current_marker
		if marker is None: return
		self.replace_marker(camera, marker)
		return marker

	def remove_marker(self, marker=None):
		"""Delete selected placed marker from camanim tracking"""
		if self.is_marker(marker):
			bpy.context.scene.objects.unlink(marker)					# remove from scene
			bpy.data.objects.remove(marker, do_unlink=True)		# delete and verify unlink from whole project
		return marker

	def remove_current_marker(self):
		"""Delete current camer marker from camanim tracking"""
		marker = self.current_marker
		if marker is None: return
		self.remove_marker(marker)
		return marker

	def jump_first_marker(self, camera):
		"""Jump to the first tracked marker"""
		self.sort_markers()
		if len(self.sorted_markers) < 1: return False
		self.snap_cam_to_marker(camera, self.sorted_markers[0])
		return True

	def jump_last_marker(self, camera):
		"""Jump to the final tracked marker"""
		self.sort_markers()
		if len(self.sorted_markers) < 1: return False
		self.snap_cam_to_marker(camera, self.sorted_markers[len(self.sorted_markers) - 1])
		return True

	def jump_marker(self, camera, marker_count):
		"""Jump camera a certain number of markers earlier or later along path"""
		self.sort_markers()
		if len(self.sorted_markers) < 1:
			return 0
		# determine index to jump from
		current_index = 0
		if self.current_marker is not None: 	# else current_index = 0
			for i in range(len(self.sorted_markers)):
				if self.sorted_markers[i] == self.current_marker:
					current_index = i
		# add index to jump to
		jump_i = current_index + marker_count
		# clamp jump to marker list length
		clamped_jump_i = jump_i % (len(self.sorted_markers))
		self.snap_cam_to_marker(camera, self.sorted_markers[clamped_jump_i])
		return clamped_jump_i

	def has_current_marker(self):
		"""Check if there is a stored current marker"""
		if self.current_marker is not None:
			return True
		return False

	def has_any_marker(self):
		"""Check if there are any stored markers"""
		self.sort_markers()
		if len(self.sorted_markers) > 0:
			return True
		return False

	def is_marker(self, obj=None):
		"""Check that an object's name contains the unique marker name base string"""
		if obj is not None and len(obj.name) >= len(self.marker_name_text) and self.marker_name_text == obj.name[0:len(self.marker_name_text)]:
			return True
		return False

	def get_current_marker_details(self):
		"""Find the name and index of the current marker"""
		if self.current_marker:
			return {
				'name': self.current_marker.name,
				'id': self.get_marker_index(self.current_marker)
			}
		return {}

	def get_marker_index(self, marker):
		"""Return the index along path of the current marker"""
		if marker is not None:
			self.sort_markers()
			marker_i = None
			for i in range(len(self.sorted_markers)):
				if self.sorted_markers[i] == marker:
					marker_i = i
			if marker_i is not None: return marker_i
		return None

	def snap_cam_to_marker(self, camera, marker):
		"""Set camera location and rotation to match marker"""
		camera.location = marker.location
		camera.rotation_euler = marker.rotation_euler
		self.current_marker = marker
		return marker

	def sort_markers(self):
		"""Retrieve well-named markers and sort from earliest to latest"""

		marker_indexes = [] 	# store all suffix "indexes" to sort
		markers_by_index = {} 	# marker_index: marker_object pairs for hash retrieval after sort

		# catalog indexes suffixed to all marker objects
		# NOTE relies on proper name formatting on marker creation
		for obj in bpy.context.scene.objects:
			if self.is_marker(obj):
				marker_split_name = obj.name.split(".") 	# "name_base.nnn"
				marker_index = int(marker_split_name[len(marker_split_name)-1])
				markers_by_index[marker_index] = obj
				marker_indexes.append(marker_index)
		# sort split suffixes and grab markers in that order
		marker_indexes.sort()
		markers = [markers_by_index[i] for i in marker_indexes]
		self.sorted_markers = markers
		return markers

	def animate(self, camera, frames_per_space=3, frames_per_degree=0.1, min_frames_per_kf=0, max_frames_per_kf=9999, frames_pause=3):
		"""Use placed markers to set keyframes timed out by frames per loc and rot unit"""
		self.sort_markers()
		bpy.context.scene.frame_current = bpy.context.scene.frame_start + 1

		# keyframe cam along markers
		for i in range(len(self.sorted_markers)):
			marker = self.sorted_markers[i]
			self.snap_cam_to_marker(camera, marker)
			camera.keyframe_insert("location")
			camera.keyframe_insert("rotation_euler")
			# start/end stasis gaps
			if 0 < i < len(self.sorted_markers) - 1 and frames_pause > 0:
				bpy.context.scene.frame_current += frames_pause
				camera.keyframe_insert("location")
				camera.keyframe_insert("rotation_euler")

			# calculate diff between keyframes
			if i < len(self.sorted_markers) - 1:
				this_marker = self.sorted_markers[i]
				next_marker = self.sorted_markers[i + 1]
				loc_distance = (next_marker.location - this_marker.location).length
				rot_distance = (Vector(next_marker.rotation_euler) - Vector(this_marker.rotation_euler)).magnitude * 57.2958
				# smooth frame count over distance to give sense of reaching top speed
				added_loc_frames = int(log(max(1, 10 * frames_per_space * loc_distance), 2))
				added_rot_frames = int(log(max(1, frames_per_degree * rot_distance), 2))
				added_frames = added_loc_frames + added_rot_frames
				# clamp frame count between the two keyframes
				clamped_frames = min(max(min_frames_per_kf, int(added_frames)), max_frames_per_kf)
			else:
				clamped_frames = 0
			bpy.context.scene.frame_current += clamped_frames

		# stretch timeline to fit keyframes
		if bpy.context.scene.frame_current > bpy.context.scene.frame_end:
			bpy.context.scene.frame_end = bpy.context.scene.frame_current + 1

		return None

camanim = CamAnim()

def is_camera(obj=bpy.context.scene.objects.active):
	"""Check if an object has type 'CAMERA'"""
	return ctx.scene.objects.active.type == ctx.scene.camera.type

class CamAnimPanel(bpy.types.Panel):
	bl_label = "CamAnim"
	bl_idname = "camera.camanim_panel"
	bl_space_type = "VIEW_3D"
	bl_region_type = "TOOLS"
	bl_category = "CamAnim"

	def draw(self, ctx):
		setup_cam_ui_props()

		layout = self.layout

		if ctx.scene.objects.active == ctx.scene.camera or camanim.is_marker(obj=ctx.scene.objects.active):
			col = layout.column(align=True)

			# update marker data and marker objects
			col.label("Manage markers")
			col.operator("camera.camanim_set_marker", text="Place marker")
			col.operator("camera.camanim_replace_current_marker", text="Update marker")
			col.operator("camera.camanim_remove_current_marker", text="Delete marker")

			# update camera loc-rot to match marker loc-rot
			if camanim.has_any_marker():
				col.label("Jump to marker")
				row = col.row(align=True)
				row.operator("camera.camanim_first_marker", text="First")
				row.operator("camera.camanim_last_marker", text="Last")
				if camanim.has_current_marker():
					row = col.row(align=True)
					row.operator("camera.camanim_prev_marker", text="Previous")
					row.operator("camera.camanim_next_marker", text="Next")

			# update marker data and display marker stats
			current_marker_stats = camanim.get_current_marker_details()
			col.operator("camera.camanim_refresh_markers", text="Refresh markers")
			if current_marker_stats and current_marker_stats['id'] is not None and current_marker_stats['id'] > -1:
				col.label("marker %s: %s" % (current_marker_stats.get('id'), current_marker_stats.get('name')))
			else:
				col.label("(no current marker)")

			# set keyframes
			if camanim.has_any_marker():
				col.label("Animate camera")
				cam = ctx.scene.camera.data
				col.row().prop(cam, "camanim_frames_per_space")
				col.row().prop(cam, "camanim_frames_per_degree")
				col.row().prop(cam, "camanim_min_frames_per_kf")
				col.row().prop(cam, "camanim_max_frames_per_kf")
				col.row().prop(cam, "camanim_frames_pause")
				col.row().operator("camera.camanim_animate", text="Keyframe camera")

		# invalid selection
		else:
			layout.label("Select Scene Camera...")

		return None

class CamAnimSetMarker(bpy.types.Operator):
	bl_label = "CamAnim Set Marker"
	bl_idname = "camera.camanim_set_marker"
	bl_description = "Place marker along CamAnim path"
	bl_options = {'REGISTER', 'UNDO'}

	@classmethod
	def poll(c, ctx):
		return ctx.mode == "OBJECT"

	def execute(self, ctx):
		obj = ctx.scene.objects.active
		if is_camera():
			camanim.place_marker(obj)
		return {'FINISHED'}

class CamAnimReplaceMarker(bpy.types.Operator):
	bl_label = "CamAnim Replace Marker"
	bl_idname = "camera.camanim_replace_current_marker"
	bl_description = "Replace current marker along CamAnim path"
	bl_options = {'REGISTER', 'UNDO'}

	@classmethod
	def poll(c, ctx):
		return ctx.mode == "OBJECT"

	def execute(self, ctx):
		camanim.replace_current_marker(bpy.context.scene.camera)
		return {'FINISHED'}

class CamAnimRemoveMarker(bpy.types.Operator):
	bl_label = "CamAnim Remove Marker"
	bl_idname = "camera.camanim_remove_current_marker"
	bl_description = "Remove marker from CamAnim path"
	bl_options = {'REGISTER', 'UNDO'}

	@classmethod
	def poll(c, ctx):
		return ctx.mode == "OBJECT"

	def execute(self, ctx):
		camanim.remove_current_marker(bpy.context.scene.objects.active)
		return {'FINISHED'}

class CamAnimRefreshMarkers(bpy.types.Operator):
	bl_label = "CamAnim Refresh Markers"
	bl_idname = "camera.camanim_refresh_markers"
	bl_description = "Jump to current marker along CamAnim path"
	bl_options = {'REGISTER', 'UNDO'}

	@classmethod
	def poll(c, ctx):
		return ctx.mode == "OBJECT"

	def execute(self, ctx):
		camanim.jump_marker(bpy.context.scene.camera, 0)
		return {'FINISHED'}

class CamAnimFirstMarker(bpy.types.Operator):
	bl_label = "CamAnim First Marker"
	bl_idname = "camera.camanim_first_marker"
	bl_description = "Jump to first marker along CamAnim path"
	bl_options = {'REGISTER', 'UNDO'}

	@classmethod
	def poll(c, ctx):
		return ctx.mode == "OBJECT"

	def draw(self, ctx):
		self.layout.row().label("Jumping to first available marker")

	def execute(self, ctx):
		camanim.jump_first_marker(bpy.context.scene.camera)
		return {'FINISHED'}

class CamAnimPrevMarker(bpy.types.Operator):
	bl_label = "CamAnim Previous Marker"
	bl_idname = "camera.camanim_prev_marker"
	bl_description = "Jump to previous marker along CamAnim path"
	bl_options = {'REGISTER', 'UNDO'}

	@classmethod
	def poll(c, ctx):
		return ctx.mode == "OBJECT"

	def draw(self, ctx):
		self.layout.row().label("Jumping to previous available marker")

	def execute(self, ctx):
		camanim.jump_marker(bpy.context.scene.camera, -1)
		return {'FINISHED'}

class CamAnimNextMarker(bpy.types.Operator):
	bl_label = "CamAnim Next Marker"
	bl_idname = "camera.camanim_next_marker"
	bl_description = "Jump to next marker along CamAnim path"
	bl_options = {'REGISTER', 'UNDO'}

	@classmethod
	def poll(c, ctx):
		return ctx.mode == "OBJECT"

	def draw(self, ctx):
		self.layout.row().label("Jumping to next available marker")

	def execute(self, ctx):
		camanim.jump_marker(bpy.context.scene.camera, 1)
		return {'FINISHED'}

class CamAnimLastMarker(bpy.types.Operator):
	bl_label = "CamAnim Last Marker"
	bl_idname = "camera.camanim_last_marker"
	bl_description = "Jump to final marker along CamAnim path"
	bl_options = {'REGISTER', 'UNDO'}

	@classmethod
	def poll(c, ctx):
		return ctx.mode == "OBJECT"

	def draw(self, ctx):
		self.layout.row().label("Jumping to last available marker")

	def execute(self, ctx):
		camanim.jump_last_marker(bpy.context.scene.camera)
		return {'FINISHED'}

class CamAnimAnimate(bpy.types.Operator):
	bl_label = "CamAnim Animate"
	bl_idname = "camera.camanim_animate"
	bl_description = "Follow and keyframe along CamAnim path"
	bl_options = {'REGISTER', 'UNDO'}

	@classmethod
	def poll(c, ctx):
		return ctx.mode == "OBJECT"

	def execute(self, ctx):
		camanim.animate(bpy.context.scene.camera)
		return {'FINISHED'}

def register():
	bpy.utils.register_class(CamAnimPanel)
	bpy.utils.register_module(__name__)

def unregister():
	bpy.utils.unregister_class(CamAnimPanel)
	bpy.utils.unregister_module(__name__)

if __name__ == "__main__": register()


import numpy as np
import matplotlib.pyplot as plt
import cv2
# my processing function - make sure that this file is imported
import processingFunctions as pf

def channelToImage(channels):
    _, M, N = channels.shape
    Blue = (channels[0]).reshape((M, N, 1))
    Green = (channels[1]).reshape((M, N, 1))
    Red = (channels[2]).reshape((M, N, 1))
    img = np.concatenate([Blue, Green, Red], axis=-1)
    return img

# extracts channel and normalizes the channels
def channelExtractor(I):
    M, _ = I.shape
    N = int(np.floor(M/3))
    Blue_channel = (I[0 : N] / (2 ** 16 - 1)).astype(np.float64)
    Green_channel = (I[N : 2*N] / (2 ** 16 - 1)).astype(np.float64)
    Red_channel = (I[2*N : 3*N] / (2 ** 16 - 1)).astype(np.float64)
    channels = np.stack([Blue_channel, Green_channel, Red_channel], axis=0)
    return channels

# calculate error:
def errorCal(chn1, chn2, errMod):
    M, N = chn1.shape
    Error = 0
    if errMod == 'ABS':
        return np.sum( np.abs(chn1 - chn2) )
    else:
        return np.sqrt(np.sum( (chn1 - chn2) ** 2 ))

# shift the channel along with 'one' axis at a time
def channelShifter(chn, shift):
    chnShifted = np.copy(chn)

    M, N = chnShifted.shape
    if shift[0] >= 0:
        for i in range(M):
            chnShifted[i, int(shift[0]):] = chnShifted[i, 0:N-int(shift[0])]
    else:
        for i in range(M):
            chnShifted[i, 0:N+int(shift[0])] = chnShifted[i, -int(shift[0]):]

    if shift[1] >= 0:
        for j in range(N):
            chnShifted[int(shift[1]):, j] = chnShifted[0:M-int(shift[1]), j]
    else:
        for j in range(N):
            chnShifted[0:M+int(shift[1]), j] = chnShifted[-int(shift[1]):, j]

    return chnShifted

# resolution change
def changeRes(chn, coeff):
    M, N = chn.shape
    Mo, No = ( int(np.ceil(M / coeff)), int(np.ceil(N / coeff)) )
    resizedChn = np.zeros((Mo, No), dtype=chn.dtype)
    for i in range(0,M,coeff):
        resizedChn[int(i / coeff), : ] = chn[i, np.arange(0, N, coeff)]

    return resizedChn

def findProperShift(fixedChn, movingChn, resFactor, fixedInterval, errMod='RMS'):
    properShift = np.zeros(2, dtype=int)
    for frac in range(int(np.log2(resFactor)) + 1):
        properShift *= 2

        currentFactor = int(resFactor / ( 2 ** frac) ) # changing resultion factor
        fixedResized = changeRes(fixedChn, currentFactor)
        movingResized = changeRes(movingChn, currentFactor)

        M, N = fixedResized.shape

        if frac == 0:
            errors = np.zeros( (4 * fixedInterval + 1 , 4 * fixedInterval + 1) ) # in last level enlarge interval by two
            for i in range(4 * fixedInterval + 1):
                for j in range(4 * fixedInterval + 1):
                    xshift = int((i - 2 * fixedInterval + properShift[0]))
                    yshift = int((j - 2 * fixedInterval + properShift[1]))
                    C = channelShifter(movingResized, (xshift, yshift) )
                    errors[i, j] = errorCal(fixedResized[2*fixedInterval:M-2*fixedInterval, 2*fixedInterval:N-2*fixedInterval],
                                                       C[2*fixedInterval:M-2*fixedInterval, 2*fixedInterval:N-2*fixedInterval], errMod)

            ind = np.array(np.unravel_index(np.argmin(errors), errors.shape), dtype=properShift.dtype)
            properShift += ind - np.array([2 * fixedInterval, 2 * fixedInterval], dtype=properShift.dtype)

        else:
            errors = np.zeros( (2*fixedInterval+1 , 2*fixedInterval+1) )
            for i in range(2 * fixedInterval + 1):
                for j in range(2 * fixedInterval + 1):
                    xshift = int((i - fixedInterval + properShift[0]))
                    yshift = int((j - fixedInterval + properShift[1]))
                    C = channelShifter(movingResized, (xshift, yshift) )
                    errors[i, j] = errorCal(fixedResized[fixedInterval:M-fixedInterval, fixedInterval:N-fixedInterval],
                                                       C[fixedInterval:M-fixedInterval, fixedInterval:N-fixedInterval], errMod)

            ind = np.array(np.unravel_index(np.argmin(errors), errors.shape), dtype=properShift.dtype)
            properShift += ind - np.array([fixedInterval, fixedInterval], dtype=properShift.dtype)

        print("Current stage: {}".format(frac))
        print("Current shifts: ({}, {})".format(properShift[0], properShift[1]) )

    return properShift

def findClip(chn1_shift, ch2_shift):
    positive_clip = 0
    negative_clip = -1
    if chn1_shift * ch2_shift > 0:
        if chn1_shift > 0:
            positive_clip = np.amax([chn1_shift, ch2_shift])
        else:
            negative_clip = np.amin([chn1_shift, ch2_shift])
    else:
        if chn1_shift > 0:
            positive_clip = chn1_shift
            negative_clip = ch2_shift
        else:
            positive_clip = ch2_shift
            negative_clip = chn1_shift

    return [positive_clip, negative_clip]

def whiteColorClipper(cols, chn_col_numbers):
    white_thr = np.sum(cols[:, 0:5]) / (3 * 5) - 0.02
    _, y = np.where(cols >= white_thr)
    left_margin = np.amax(y[np.where(y < chn_col_numbers//32)])
    right_margin = np.amin(y[np.where(y > chn_col_numbers//32)])
    return [left_margin, right_margin]

def calColorRow(chns):
    _, _, N = chns.shape
    color_rows = np.sum(chns, axis=2) / N
    return color_rows

def calColorCol(chns):
    _, M, _ = chns.shape
    color_cols = np.sum(chns, axis=1) / M
    return color_cols

def gaussianKernel(sigma, N):
    gauss = lambda sig, x: 1 / (np.sqrt(2 * np.pi) * sig) * np.exp(-x**2 / (2 * (sig ** 2)))
    sigmaList = np.ones(N*N) * sigma
    xList = np.arange(N) - ((N-1) / 2)
    gaussVal = np.array(list(map(gauss, sigmaList, xList))).reshape(N, 1)
    # for two dimmensional kernel:
    # kernel = gaussVal @ gaussVal.T
    return gaussVal / (np.sum(gaussVal))

# if col is inserted => negative: left, positive: right
# if row is inserter => negative: up, positive: down
def findFracIndex(chn_color, len_val, sigma, ksize):
    # cal derivative:
    chn_color_diff = np.abs(np.sum(np.diff(chn_color), axis=0) / 3)

    # filtering
    kernel = gaussianKernel(sigma, ksize)
    kernel = kernel.reshape(len(kernel))
    chn_color_diff = np.convolve(chn_color_diff, kernel, 'same')

    # normalizing
    chn_color_diff /= np.amax(chn_color_diff)

    # used for report:
    # plt.plot(np.arange(len(chn_color_diff)), chn_color_diff)
    # plt.xlabel('Pixels')
    # plt.ylabel('value')
    # plt.title('Smoothed derivative (abs)')
    # plt.grid(True)
    # plt.show()

    thr = 10 * np.sum(chn_color_diff) / len_val

    indices = np.array(np.where(chn_color_diff >= thr))
    indices = indices.reshape(indices.shape[1])
    negative_halves = indices[indices <= len_val // 2]
    positive_halves = indices[indices > len_val // 2]

    if len(negative_halves) == 0:
        negative_half = 0
    else:
        negative_half = negative_halves[-1]

    if len(positive_halves) == 0:
        positive_half = 0
    else:
        positive_half = positive_halves[0]

    return [negative_half, positive_half]

# change the picture name to use other pictures
print("Enter the img's name (without .tif, e.g. Amir, Train, Mosque etc)")
picture_name = input()
I = cv2.imread(picture_name + '.tif', cv2.IMREAD_UNCHANGED)
if I is None:
    raise(AttributeError("Img's name is wrong. Please make sure to enter ONLY the picture name (without .tif). Then check that if the img and this script are togheter."))
else:
    channels = channelExtractor(I)
    print("Img loaded successfully!")
    print("Starting procedures ...")
    print("--------------------------------------------------")
# channel extraction:

################################################################################
# proper shift finder:

# green channel is fixed:
resFactor = 16 # pyramid depth
fixedInterval = 4 # search interval
print("Finding red channel proper shift:")
redShift = findProperShift(channels[1], channels[2], resFactor, fixedInterval, 'ABS')
print("Finding blue channel shifts:")
blueShift = findProperShift(channels[1], channels[0], resFactor, fixedInterval, 'ABS')

# shift channels with respect to blueShift and redShift
print("--------------------------------------------------")
print("Final red channel's shift:")
print(redShift)
print("Final blue channel's shift:")
print(blueShift)
channels[0] = channelShifter(channels[0], blueShift)
channels[2] = channelShifter(channels[2], redShift)

################################################################################
# clip extra color caused by shifting the image:

[left_clip, right_clip] = findClip(redShift[1], blueShift[1])
[top_clip, bottom_clip] = findClip(redShift[0], blueShift[0])
channels = channels[:, left_clip:right_clip, top_clip:bottom_clip]

###############################################################################
# white color clipping:
color_cols = calColorCol(channels)
[left_margin, right_margin] = whiteColorClipper(color_cols, channels.shape[1])
channels = channels[:, :, left_margin:right_margin]

###############################################################################
# dark color clipping:
color_cols = calColorCol(channels)
color_rows = calColorRow(channels)

_, M, N = channels.shape

# find proper fraction of picture to be clipped
sigma = 2
[left_frac, right_frac] = findFracIndex(color_cols, N, sigma, 6*sigma+1)
[top_frac, bottom_frac] = findFracIndex(color_rows, M, sigma, 6*sigma+1)

channels = channels[:, top_frac:bottom_frac, left_frac:right_frac]

channels *= (2 ** 8 - 1)
img = channelToImage(channels.astype(np.uint8))

cv2.imwrite('res03-{}.jpg'.format(picture_name), img)

pf.showImg(img, (960, 960), 'Color Image')
cv2.waitKey(0)
cv2.destroyAllWindows()


from django.shortcuts import render
from django.http import HttpResponse
from examples.models import study
from examples.models import SimpleTable
from examples.models import SNP_entry
from django.template.response import TemplateResponse
from django.shortcuts import render
from itertools import chain
import simplejson as json
import xlsxwriter
import subprocess
import os
import xlrd

# Create your views here.

currentGene = "NULL"

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

def get_GENE(request):
	if request.method == 'GET':
		geneName = request.GET['text_box']
		disorder_num = request.GET['dropdown']
		studyData = study.objects.all()
		SNPData = SNP_entry.objects.all()
		filterGene = SNP_entry.objects.filter(gene_name=geneName).filter(disorder=disorder_num)

		#WRITE TO EXCEL FILE
		if os.path.exists('geneData.xlsx'): os.remove('geneData.xlsx')
		workbook = xlsxwriter.Workbook('geneData.xlsx')
		worksheet1 = workbook.add_worksheet('studyData')
		worksheet2 = workbook.add_worksheet('SNP_entryData')

		excel_data(workbook, worksheet1, worksheet2, filterGene)

		table = SimpleTable(filterGene, template_name='django_tables2/bootstrap-responsive.html')
		return render(request, 'pages/database.html', {'table': table})

def get_SNP(request):
	if request.method == 'GET':
		SNPname = request.GET['text_box']
		disorder_num = request.GET['dropdown']
		studyData = study.objects.all()
		SNPData = SNP_entry.objects.all()
		filterSNP = SNP_entry.objects.filter(SNP_id=SNPname).filter(disorder=disorder_num)

		# WRITE TO EXCEL FILE
		if os.path.exists('SNPData.xlsx'): os.remove('geneData.xlsx')
		workbook = xlsxwriter.Workbook('geneData.xlsx')
		worksheet1 = workbook.add_worksheet('studyData')
		worksheet2 = workbook.add_worksheet('SNP_entryData')

		excel_data(workbook, worksheet1, worksheet2, filterSNP)

		table = SimpleTable(filterSNP, template_name='django_tables2/bootstrap-responsive.html')
		return render(request, 'pages/database.html', {'table': table})

def get_Disorder(request):
	if request.method == 'GET':
		disorder_num = request.GET['dropdown']
		studyData = study.objects.all()
		SNPData = SNP_entry.objects.all()
		filterDisorder = SNP_entry.objects.filter(disorder=disorder_num)

		# WRITE TO EXCEL FILE
		if os.path.exists('geneData.xlsx'): os.remove('geneData.xlsx')
		workbook = xlsxwriter.Workbook('geneData.xlsx')
		worksheet1 = workbook.add_worksheet('studyData')
		worksheet2 = workbook.add_worksheet('SNP_entryData')

		excel_data(workbook, worksheet1, worksheet2, filterDisorder)

		table = SimpleTable(filterDisorder, template_name='django_tables2/bootstrap-responsive.html')
		return render(request, 'pages/database.html', {'table': table})

def index(request):
	return render(request, 'pages/index.html')

def results(request):
	return render(request, 'pages/results.html')

def methods(request):
	return render(request, 'pages/methods.html')

def about(request):
	return render(request, 'pages/about.html')

def contacts(request):
	return render(request, 'pages/contact.html')

def input(request):
	return render(request, 'pages/input.html')

#Trigger Rscript
def gene(request):

	retcode = subprocess.call("Rscript --vanilla examples/meta_analysis_SNP.r", shell=True)
	wb=xlrd.open_workbook("geneData.xlsx")
	sheet = wb.sheet_by_index(1)
	context = {
		"name": sheet.cell_value(1, 19)
	}
	return render(request, 'pages/gene.html', context)

def search(request):
	return render(request, 'pages/search.html')

def database(request):
	data = study.objects.all()
	table = SimpleTable(data, template_name='django_tables2/bootstrap-responsive.html')
	return render(request, 'pages/database.html', {'table': table})
	#return TemplateResponse(request, 'pages/disorders.html',{"data": data})

def excel_data(workbook, worksheet1, worksheet2, filter):
	row = 0
	# write headers
	worksheet1.write(row, 0, "studyId")
	worksheet1.write(row, 1, "Pmid")
	worksheet1.write(row, 2, "design")
	worksheet1.write(row, 3, "type of study")
	worksheet1.write(row, 4, "ethnic Population")
	worksheet1.write(row, 5, "source")
	worksheet1.write(row, 6, "platform")
	worksheet1.write(row, 7, "the_domain")
	worksheet1.write(row, 8, "num_SNPs")
	worksheet1.write(row, 9, "num_polys")
	worksheet1.write(row, 10, "DX")
	worksheet1.write(row, 11, "Case_N")
	worksheet1.write(row, 12, "Case_perc_fem")
	worksheet1.write(row, 13, "Case_age")
	worksheet1.write(row, 14, "Control_N")
	worksheet1.write(row, 15, "Control_perc_fem")
	worksheet1.write(row, 16, "Control_age")
	worksheet1.write(row, 17, "num_families")
	worksheet1.write(row, 18, "num_affected")
	worksheet1.write(row, 19, "num_generations")
	worksheet1.write(row, 20, "mean_score")
	worksheet1.write(row, 21, "SD_score")
	worksheet1.write(row, 22, "measure_used")
	worksheet1.write(row, 23, "disorder")
	worksheet1.write(row, 24, "test")
	worksheet1.write(row, 25, "hyperlink")

	worksheet2.write(row, 0, "entryId")
	worksheet2.write(row, 1, "SNP_id")
	worksheet2.write(row, 2, "Meta_p_value")
	worksheet2.write(row, 3, "SNP_chromosome_location")
	worksheet2.write(row, 4, "SNP_chromosome_band")
	worksheet2.write(row, 5, "SNP_position")
	worksheet2.write(row, 6, "SNP_version")
	worksheet2.write(row, 7, "odds_risk")
	worksheet2.write(row, 8, "odds_risk_lci")
	worksheet2.write(row, 9, "odds_risk_uci")
	worksheet2.write(row, 10, "ethnicity_1000_pop")
	worksheet2.write(row, 11, "REF_allele")
	worksheet2.write(row, 12, "ALT_allele")
	worksheet2.write(row, 13, "EFF_score")
	worksheet2.write(row, 14, "EFF_var")
	worksheet2.write(row, 15, "mtc_pvalue")
	worksheet2.write(row, 16, "SNP_risk")
	worksheet2.write(row, 17, "SNP_test")
	worksheet2.write(row, 18, "SNP_hyperlink")
	worksheet2.write(row, 19, "gene_name")
	worksheet2.write(row, 20, "gene_ensmbl_id")
	worksheet2.write(row, 21, "gene_chr")
	worksheet2.write(row, 22, "gene_band")
	worksheet2.write(row, 23, "gene_start")
	worksheet2.write(row, 24, "gene_end")
	worksheet2.write(row, 25, "gene_risk_status")
	worksheet2.write(row, 26, "gene_hyperlink")
	worksheet2.write(row, 27, "disorder")
	worksheet2.write(row, 28, "study_id")

	row = 1
	# write data
	for g in filter:
		col = 0
		worksheet1.write(row, col, g.study_id.study_id)
		worksheet1.write(row, col + 1, g.study_id.pmid)
		worksheet1.write(row, col + 2, g.study_id.design)
		worksheet1.write(row, col + 3, g.study_id.type_of_study)
		worksheet1.write(row, col + 4, g.study_id.ethnic_Population)
		worksheet1.write(row, col + 5, g.study_id.source)
		worksheet1.write(row, col + 6, g.study_id.platform)
		worksheet1.write(row, col + 7, g.study_id.the_domain)
		worksheet1.write(row, col + 8, g.study_id.num_SNPs)
		worksheet1.write(row, col + 9, g.study_id.num_polys)
		worksheet1.write(row, col + 10, g.study_id.DX)
		worksheet1.write(row, col + 11, g.study_id.Case_N)
		worksheet1.write(row, col + 12, g.study_id.Case_perc_fem)
		worksheet1.write(row, col + 13, g.study_id.Case_age)
		worksheet1.write(row, col + 14, g.study_id.Control_N)
		worksheet1.write(row, col + 15, g.study_id.Control_perc_fem)
		worksheet1.write(row, col + 16, g.study_id.Control_age)
		worksheet1.write(row, col + 17, g.study_id.num_families)
		worksheet1.write(row, col + 18, g.study_id.num_affected)
		worksheet1.write(row, col + 19, g.study_id.num_generations)
		worksheet1.write(row, col + 20, g.study_id.mean_score)
		worksheet1.write(row, col + 21, g.study_id.SD_score)
		worksheet1.write(row, col + 22, g.study_id.measure_used)
		worksheet1.write(row, col + 23, g.study_id.disorder)
		worksheet1.write(row, col + 24, g.study_id.test)
		worksheet1.write(row, col + 25, g.study_id.hyperlink)
		worksheet2.write(row, col, g.entry_id)
		worksheet2.write(row, col + 1, g.SNP_id)
		worksheet2.write(row, col + 2, g.Meta_p_value)
		worksheet2.write(row, col + 3, g.SNP_chromosome_location)
		worksheet2.write(row, col + 4, g.SNP_chromosome_band)
		worksheet2.write(row, col + 5, g.SNP_position)
		worksheet2.write(row, col + 6, g.SNP_version)
		worksheet2.write(row, col + 7, g.odds_risk)
		worksheet2.write(row, col + 8, g.odds_risk_lci)
		worksheet2.write(row, col + 9, g.odds_risk_uci)
		worksheet2.write(row, col + 10, g.ethnicity_1000_pop)
		worksheet2.write(row, col + 11, g.REF_allele)
		worksheet2.write(row, col + 12, g.ALT_allele)
		worksheet2.write(row, col + 13, g.EFF_score)
		worksheet2.write(row, col + 14, g.EFF_var)
		worksheet2.write(row, col + 15, g.mtc_pvalue)
		worksheet2.write(row, col + 16, g.SNP_risk)
		worksheet2.write(row, col + 17, g.SNP_test)
		worksheet2.write(row, col + 18, g.SNP_hyperlink)
		worksheet2.write(row, col + 19, g.gene_name)
		worksheet2.write(row, col + 20, g.gene_ensmbl_id)
		worksheet2.write(row, col + 21, g.gene_chr)
		worksheet2.write(row, col + 22, g.gene_band)
		worksheet2.write(row, col + 23, g.gene_start)
		worksheet2.write(row, col + 24, g.gene_end)
		worksheet2.write(row, col + 25, g.gene_risk_status)
		worksheet2.write(row, col + 26, g.gene_hyperlink)
		worksheet2.write(row, col + 27, g.disorder)
		row += 1
	workbook.close()


from django.urls import path
from . import views

urlpatterns = [
    path('', views.HomeView.as_view(), name="Home"),
    path('accounts/registration/', views.RegisterFormView.as_view(), name="registration"),
    path('specialty/', views.SpecialtyView.as_view(), name='specialty'),
    path('specialty/<str:slug>/', views.specialty_single_page, name="specialty"),
    path('profil/<username>/', views.profil_user, name="profil"),
]


# Standard library imports
import logging
import time
from urllib.parse import urlparse, parse_qs
from urllib.error import HTTPError

# Third party imports
from pytube import YouTube
from pytube.cli import on_progress
import requests
from simple_youtube_api.Channel import Channel
from simple_youtube_api.LocalVideo import LocalVideo
from slugify import slugify
from tqdm import tqdm
from youtube_dl import YoutubeDL

# User imports
from settings import *

# TODO
def is_youtube_video_region_restricted(yt_link_or_video_id):
    params = {
        "part": "contentDetails",
        "id": extract_youtube_video_id(yt_link_or_video_id),
        "key": API_KEY_GOOGLE,
    }
    response = requests.get(URL_YOUTUBE_API_VIDEOS, params=params)
    return response.url

# TODO improve
def extract_youtube_video_id(value):
    """
    Examples:
    - http://youtu.be/SA2iWivDJiE
    - http://www.youtube.com/watch?v=_oPAwA_Udwc&feature=feedu
    - http://www.youtube.com/embed/SA2iWivDJiE
    - http://www.youtube.com/v/SA2iWivDJiE?version=3&hl=en_US
    """
    query = urlparse(value)
    if query.hostname == "youtu.be":
        return query.path[1:]
    if query.hostname in ("www.youtube.com", "youtube.com"):
        if query.path == "/watch":
            p = parse_qs(query.query)
            return p["v"][0]
        if query.path[:7] == "/embed/":
            return query.path.split("/")[2]
        if query.path[:3] == "/v/":
            return query.path.split("/")[2]
    # fail?
    return None

def download_video_from_youtube(yt_link, output_filename):
    download_success = False

    while not download_success:
        try:
            yt = YouTube(yt_link, on_progress_callback=on_progress)

            yt.streams.first().download(
                output_path=LOCAL_VIDEOS_FOLDER_PATH, filename=output_filename
            )
            download_success = True
        except KeyError as e:
            # Video probably blocked in some countries
            if "streamingData" in str(e):
                raise

            print(e)
            time.sleep(10)
            download_success = False

def upload_to_youtube(channel_credentials_file, current_video_metadata):
    if not hasattr(upload_to_youtube, "channel"):
        channel = Channel()
        channel.login(CLIENT_SECRET_FILE, channel_credentials_file)
        upload_to_youtube.channel = channel

    video = LocalVideo(
        file_path=LOCAL_VIDEOS_FOLDER_PATH / current_video_metadata["mp4 name"]
    )

    video.set_title(current_video_metadata["mp4 name"])
    # video.set_description(current_video_metadata["Description"])
    video.set_privacy_status("public")
    return upload_to_youtube.channel.upload_video(video)

def get_channel_videos_list(all_uploads_playlist_id):
    """
    Returns a dictionary of format
    [
        {'video_title_1': 'youtube_video_id_1'},
        {'video_title_2': 'youtube_video_id_2'},
        ...
    ]
    """
    if hasattr(get_channel_videos_list, "title_id_dict"):
        return get_channel_videos_list.title_id_dict

    ytdl_opts = {
        "ignoreerrors": True,
        "extract_flat": "in_playlist",
        "dump_single_json": True,
        "quiet": True,
    }
    ytdl = YoutubeDL(ytdl_opts)

    channel_uploads_playlist_info = ytdl.extract_info(
        all_uploads_playlist_id, download=False
    )
    channel_videos = channel_uploads_playlist_info["entries"]
    channel_videos_by_title = {}

    for video in channel_videos:
        channel_videos_by_title[video["title"]] = video["id"]

    get_channel_videos_list.title_id_dict = channel_videos_by_title
    return channel_videos_by_title

def is_video_uploaded_on_destination_channel(channel_id, video_title):
    if not hasattr(is_video_uploaded_on_destination_channel, "title_id_dict"):
        is_video_uploaded_on_destination_channel.videos_list = get_channel_videos_list(
            # UC = User Channel
            # UU = User Uploads
            channel_id.replace("UC", "UU")
        )

    return video_title in is_video_uploaded_on_destination_channel.videos_list


from pylonemutestcase import PylonEmuTestCase
from pypylon import pylon
import unittest

class VersionInfoTestSuite(PylonEmuTestCase):
    # Tests that you can get proper version info
    def test_version_get(self):
        cam = self.create_first()
        cam.Open()

        v = cam.GetSfncVersion()

        # camemu has sfnc version 0.0.0.0
        self.assertEqual(0, v.getMajor())
        self.assertEqual(0, v.getMinor())
        self.assertEqual(0, v.getSubminor())
        self.assertEqual(0, v.getBuild())

        cam.Close()

    # Tests that you can compare version info
    def test_version_compare(self):
        v0 = pylon.VersionInfo(2, 2, 2)
        v1 = pylon.VersionInfo(2, 2, 1)
        v0_1 = pylon.VersionInfo(2, 2, 2)

        self.assertGreater(v0, v1)
        self.assertLess(v1, v0)
        self.assertEqual(v0, v0_1)

    # Tests that version info has repr
    def test_version_repr(self):
        cam = self.create_first()
        cam.Open()

        v = cam.GetSfncVersion()
        sfnc_version_repr = v.__repr__()
        self.assertEqual("<VersionInfo 0.0.0>", sfnc_version_repr)

if __name__ == "__main__":
    # import sys;sys.argv = ['', 'Test.testName']
    unittest.main()


from rest_framework import serializers
from .models import (Client, Order, Product, Provider)

class ClientSerializer(serializers.ModelSerializer):
    class Meta:
        model = Client
        fields = (
            'code',
            'name',
            'address',
            'client_type',
        )

class OrderSerializer(serializers.ModelSerializer):
    provider_info = serializers.SerializerMethodField()
    product_info = serializers.SerializerMethodField()
    client_info = serializers.SerializerMethodField()

    class Meta:
        model = Order
        fields = (
            'order_number',
            'provider',
            'provider_info',
            'product',
            'product_info',
            'client',
            'client_info',
            'order_date',
            'deliver_date',
            'priority',
            'items',
            'order_type',
            'distribution_center_store',
            'store_reference',
            'store_code',
            'company_reference',
            'company_member_code',
            'company_order_detail',
        )

    def get_provider_info(self, obj):
        return ProviderSerializer(obj.provider).data

    def get_product_info(self, obj):
        return ProductSerializer(obj.product).data

    def get_client_info(self, obj):
        return ClientSerializer(obj.client).data

    def validate(self, data):

        if data['order_type'] == 'CEDIS':

            if not data['distribution_center_store']:
                raise serializers.ValidationError("Field distribution_center_store is required.")

        if data['order_type'] == 'SUCURSAL':

            if not data['store_reference']:
                raise serializers.ValidationError("Field store_reference is required.")

            if not data['store_code']:
                raise serializers.ValidationError("Field store_code is required.")

        if data['order_type'] == 'EMPRESA_ASOCIADA':

            if not data['company_reference']:
                raise serializers.ValidationError("Field company_reference is required.")

            if not data['company_member_code']:
                raise serializers.ValidationError("Field company_member_code is required.")

            if not data['company_order_detail']:
                raise serializers.ValidationError("Field company_order_detail is required.")

        return data

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = (
            'code',
            'description',
        )

class ProviderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Provider
        fields = (
            'name',
            'address',
        )


import re
from csv import DictReader

import fire
import yaml

from helpers.aws_session import new_session_from_env
from mi.reporting.actions import each_stored_query_event, perform_query, write_csv
from mi.reporting.constants import VALIDATOR_PATH
from mi.reporting.resources import BadDateError, hash_str_to_int, parse_date_range

class ReportValidationError(ValueError):
    pass

def get_validator(report_name: str) -> dict:
    with open(VALIDATOR_PATH / f"{report_name}.yaml") as f:
        validator = {k: re.compile(v) for k, v in yaml.safe_load(f).items()}
    return validator

def validate(validator: dict[str, re.Pattern], results: list[dict], report_name: str):
    for row in results:
        extra_fields = row.keys() - validator.keys()
        if extra_fields:
            raise ReportValidationError(f"Extra fields found in output: {extra_fields}")

        missing_fields = validator.keys() - row.keys()
        if missing_fields:
            raise ReportValidationError(f"Fields missing in output: {missing_fields}")

        for field, regex in validator.items():
            value = row[field]
            if not regex.match(value):
                raise ReportValidationError(
                    f"{report_name}: "
                    f"Failed to validate field '{field}' with "
                    f"value '{value}' with pattern '{regex.pattern}'"
                )

def parse_results(path: str):
    with open(path) as f:
        results = list(DictReader(f=f))
    return results

def make_reports(
    session,
    env: str,
    workspace: str = None,
    partition_key=None,
    start_date: str = None,
    end_date: str = None,
):
    if workspace is None:
        workspace = env
    if partition_key is None:
        partition_key = ""

    for report_name, event in each_stored_query_event(
        session=session,
        workspace=workspace,
        env=env,
        partition_key=partition_key,
        start_date=start_date,
        end_date=end_date,
    ):
        data = perform_query(session=session, workspace=workspace, event=event)
        report_path = write_csv(
            data=data,
            workspace=workspace,
            env=env,
            report_name=report_name,
            partition_key=partition_key,
        )
        results = parse_results(path=report_path)
        if results:
            validator = get_validator(report_name=report_name)
            validate(validator=validator, results=results, report_name=report_name)
        else:
            print("\tNote: no results found")  # noqa

def _make_reports(
    env: str,
    workspace: str = None,
    partition_key: str = None,
    start_date: str = None,
    end_date: str = None,
):
    if partition_key is not None:
        partition_key = str(hash_str_to_int(key=partition_key))
    start_date, end_date = parse_date_range(start_date=start_date, end_date=end_date)

    if start_date > end_date:
        raise BadDateError(f"Start date {start_date} is after end date {end_date}")

    session = new_session_from_env(env=env)
    try:
        make_reports(
            session=session,
            env=env,
            workspace=workspace,
            partition_key=partition_key,
            start_date=start_date,
            end_date=end_date,
        )
    except ReportValidationError as err:
        print("\n❗❗❗ Validation error found in the previous report: ")  # noqa: T201
        print(str(err))  # noqa: T201

if __name__ == "__main__":
    fire.Fire(_make_reports)


import pytest
from brownie import exceptions
from scripts.reentrancy.deploy_and_attack import (
    deploy_attack,
    deploy_ether_store,
    deploy_ether_store_fixed,
)
from scripts.utils import get_attacker_account, get_user_account
from web3 import Web3

def test_ether_store_attack_successful():
    # Deploy EtherStore smart contract
    ether_store = deploy_ether_store()

    # Initialize a user account
    user_account = get_user_account()
    deposit_amount_eth = 10
    value_wei = Web3.toWei(deposit_amount_eth, "ether")

    # User deposits 1 ether to EtherStore
    tx = ether_store.deposit({"from": user_account, "value": value_wei})
    tx.wait(1)

    # Assert that EtherStore balance now is 10 ETH
    assert ether_store.balanceOf() / 10**18 == 10

    # Deploy Attack contract
    attack_contract = deploy_attack(ether_store.address)

    # Assert that Attack contract balance is 0 ETH
    assert attack_contract.balanceOf() / 10**18 == 0

    # Call `attack` function of Attack contract
    attack_tx = attack_contract.attack(
        {
            "from": get_attacker_account(),
            "value": Web3.toWei(1.5, "ether"),
        }
    )

    attack_tx.wait(1)

    # Assert that EtherStore balance now is 0 ETH
    assert ether_store.balanceOf() / 10**18 == 0

    # Assert that Attack contract balance is 11.5 ETH
    assert attack_contract.balanceOf() / 10**18 == 11.5

def test_ether_store_attack_failed():
    # 1. Deploy EtherStore smart contracts
    ether_store = deploy_ether_store_fixed()
    user_account = get_user_account()
    deposit_amount_eth = 10

    value_wei = Web3.toWei(deposit_amount_eth, "ether")
    tx = ether_store.deposit({"from": user_account, "value": value_wei})
    tx.wait(1)
    print(
        f"Account {user_account.address} has deposited {deposit_amount_eth} ETH to EtherStore!"
    )
    print(f"Ether store balance {ether_store.balanceOf()/10**18} ETH")

    # 2. Deploy Attack contract
    attack_contract = deploy_attack(ether_store.address)

    # 3. Call `attack` function of Attack contract

    with pytest.raises(exceptions.VirtualMachineError):
        attack_tx = attack_contract.attack(
            {
                "from": get_attacker_account(),
                "value": Web3.toWei(1.5, "ether"),
            }
        )

        attack_tx.wait(1)