#!/usr/bin/env python
# coding: utf-8

# In[1]:

from __future__ import print_function
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import classification_report
from sklearn import metrics
from sklearn import tree
import warnings
warnings.filterwarnings('ignore')

#for interactivity
from ipywidgets import interact
from tabulate import tabulate

data=pd.read_csv('crop_recommendation.csv')
print("Shape Of The Data:",data.shape)
print()
data.head()
data.tail()
data.columns
data.dtypes
data['label'].unique()
data['label'].value_counts()
data.isnull().sum()

#summary of dataset

# create a list of variable names
variables = ['N', 'P', 'K', 'temperature', 'humidity', 'ph', 'rainfall']

# loop through the variables and calculate/print their mean values
for var in variables:
    print("Average ratio of {0} in the soil: {1:.2f}".format(var, data[var].mean()))

@interact(crops=data['label'].unique())
def summary(crops):
    stats = ['mean', 'median', 'min', 'max']
    vars = ['N', 'P', 'K', 'temperature', 'humidity', 'ph', 'rainfall']

    print("Statistics for crop:", crops)
    for var in vars:
        print("Statistics of", var)
        print("Statistics for crop:", crops)
        for stat in stats:
            print(stat, var, "required: {:.2f}".format(data[data['label'] == crops][var].agg(stat)))
        print()  # Add an empty print statement to print a blank line

@interact
def compare(conditions =['N','P','K','temperature','humidity','rainfall','ph']):
    crops = ['rice', 'maize', 'jute', 'blackgram', 'banana', 'coconut', 'apple', 'papaya', 'muskmelon', 'grapes', 'watermelon', 'kidneybeans', 'mungbean', 'orange', 'chickpea', 'lentil', 'cotton', 'pigeonpeas', 'mothbeans', 'mango', 'pomegranate', 'coffee']
    for crop in crops:
        print("{}: {:.2f}".format(crop.title(), data[data['label'] == crop][conditions].mean()))

@interact
def compare(conditions =['N','P','K','temperature','humidity','rainfall','ph']):
    print("crops which requires greater than the average",conditions,'\n')
    print(data[data[conditions]>data[conditions].mean()]['label'].unique())
    print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
    print("crops which require less than average ", conditions,'\n')
    print(data[data[conditions]<=data[conditions].mean()]['label'].unique())

print("Some interesting facts")

print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")

headers = ['Condition', 'Crops']
data = [
    ['High Nitrogen content in soil', ', '.join(data[data['N']>120]['label'].unique())],
    ['High Phosphorus content in soil', ', '.join(data[data['P']>100]['label'].unique())],
    ['High Potassium content in soil', ', '.join(data[data['K']>200]['label'].unique())],
    ['High Rainfall', ', '.join(data[data['rainfall']>200]['label'].unique())],
    ['Low temperature', ', '.join(data[data['temperature']<10]['label'].unique())],
    ['High temperature', ', '.join(data[data['temperature']>40]['label'].unique())],
    ['Low humidity', ', '.join(data[data['humidity']<20]['label'].unique())],
    ['High PH', ', '.join(data[data['ph']>9]['label'].unique())],
    ['Very low PH', ', '.join(data[data['ph']<4]['label'].unique())]
]

print(tabulate(data, headers=headers))

# In[2]:

import pandas as pd
from sklearn.cluster import KMeans
import warnings
warnings.filterwarnings('ignore')

data=pd.read_csv('crop_recommendation.csv')
x=data.loc[:,['N','P','K','temperature','humidity','rainfall','ph']].values
print(x.shape)

x_data=pd.DataFrame(x)
x_data.head()

plt.rcParams['figure.figsize']=(10,4)

wcss=[]
for i in range(1,11):
    km=KMeans(n_clusters=i,init='k-means++',max_iter=300,n_init=10,random_state=0)
    km.fit(x)
    wcss.append(km.inertia_)

plt.plot(range(1,11),wcss)
plt.title('The Elbow method',fontsize=20)
plt.xlabel('no. of cluster')
plt.ylabel('wcss')
plt.show()

km=KMeans(n_clusters=4,init='k-means++',max_iter=300,n_init=10,random_state=0)
y_means=km.fit_predict(x)

a=data['label']
y_means=pd.DataFrame(y_means)
z=pd.concat([y_means,a],axis=1)
z=z.rename(columns={0:'cluster'})

#check cluster for each group
print("crops in first cluster :",z[z['cluster']==0]['label'].unique())
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
print("crops in second cluster :",z[z['cluster']==1]['label'].unique())
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
print("crops in third cluster :",z[z['cluster']==2]['label'].unique())
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
print("crops in forth cluster :",z[z['cluster']==3]['label'].unique())

# In[3]:

from sklearn.model_selection import train_test_split
import pandas as pd

data=pd.read_csv('crop_recommendation.csv')

x=data.drop(['label'],axis=1)
y=data['label']

print("shape of x",x.shape)
print("shape of y",y.shape)
print()
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=0)

from sklearn.linear_model import LogisticRegression

model=LogisticRegression()
model.fit(x_train,y_train)
y_pred=model.predict(x_test)

from sklearn.metrics import classification_report
cr=classification_report (y_test,y_pred)
print(cr)

Prediction=model.predict((np.array([[90,40,40,20,80,7,200]])))
print("the suggested crop for this given climate condition is ",Prediction)

Prediction=model.predict((np.array([[20,30,10,15,90,7.5,100]])))
print("the suggested crop for this given climate condition is ",Prediction)
print()

# convert any non-numeric columns to numeric
for col in data.columns:
    if data[col].dtype == object:
        data[col] = pd.to_numeric(data[col], errors='coerce')

sns.heatmap(data.corr(),annot=True)

features = data[['N', 'P','K','temperature', 'humidity', 'ph', 'rainfall']]
target = data['label']

#features = df[['temperature', 'humidity', 'ph', 'rainfall']]
labels = data['label']

# Initialzing empty lists to append all model's name and corresponding name
acc = []
model = []

# In[4]:

#Decision Tree
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score

data = pd.read_csv("crop_recommendation.csv")

X = data.drop(['label'], axis=1)
y = data['label']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

dt_clf = DecisionTreeClassifier()
dt_clf.fit(X_train, y_train)

y_pred = dt_clf.predict(X_test)

dt_acc = accuracy_score(y_test, y_pred)
print("Accuracy of Decision Tree:", dt_acc*100)

cv_score = cross_val_score(dt_clf, X, y, cv=5)
print("Cross-validation score:", cv_score)
print()

print(classification_report(y_test,y_pred))

#Saving trained Decision Tree model

import pickle
# Dump the trained Naive Bayes classifier with Pickle
DT_pkl_filename = 'DecisionTree.pkl'

# Open the file to save as pkl file
DT_Model_pkl = open(DT_pkl_filename, 'wb')
pickle.dump(DecisionTreeClassifier, DT_Model_pkl)

# Close the pickle instances
DT_Model_pkl.close()

# In[5]:

# Guassian Naive Bayes
import pandas as pd
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score

data = pd.read_csv("crop_recommendation.csv")

X = data.drop(['label'], axis=1)
y = data['label']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

nb_clf = GaussianNB()
nb_clf.fit(X_train, y_train)

y_pred = nb_clf.predict(X_test)

nb_acc = accuracy_score(y_test, y_pred)
print("Accuracy of Naive Bayes:", nb_acc*100)

cv_score = cross_val_score(nb_clf, X, y, cv=5)
print("Cross-validation score:", cv_score)
print()

print(classification_report(y_test,y_pred))

#Saving trained Guassian Naive Bayes model
import pickle
# Dump the trained Naive Bayes classifier with Pickle
NB_pkl_filename = 'NBClassifier.pkl'

# Open the file to save as pkl file
NB_Model_pkl = open(NB_pkl_filename, 'wb')
pickle.dump(GaussianNB, NB_Model_pkl)

# Close the pickle instances
NB_Model_pkl.close()

# In[6]:

# Support Vector Machine (SVM)
import pandas as pd
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score

data = pd.read_csv("crop_recommendation.csv")

X = data.drop(['label'], axis=1)
y = data['label']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

svm_clf = SVC(kernel='linear')
svm_clf.fit(X_train, y_train)

y_pred = svm_clf.predict(X_test)

svm_acc = accuracy_score(y_test, y_pred)
print("Accuracy of SVM:", svm_acc*100)

cv_score = cross_val_score(svm_clf, X, y, cv=5)
print("Cross-validation score:", cv_score)
print()

print(classification_report(y_test,y_pred))

#Saving trained SVM model
import pickle
# Dump the trained SVM classifier with Pickle
SVM_pkl_filename = 'SVMClassifier.pkl'
# Open the file to save as pkl file
SVM_Model_pkl = open(SVM_pkl_filename, 'wb')
pickle.dump(SVC, SVM_Model_pkl)
# Close the pickle instances
SVM_Model_pkl.close()

# In[7]:

#Logistic Regression
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score

data = pd.read_csv("Crop_recommendation.csv")

X = data.drop(['label'], axis=1)
y = data['label']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

lr_clf = LogisticRegression(random_state=42)
lr_clf.fit(X_train, y_train)

y_pred = lr_clf.predict(X_test)

lr_acc = accuracy_score(y_test, y_pred)
print("Accuracy of Logistic Regression:", lr_acc*100)

cv_score = cross_val_score(lr_clf, X, y, cv=5)
print("Cross-validation score:", cv_score)
print()

print(classification_report(y_test,y_pred))

#Saving trained Logistic Regression model
import pickle
# Dump the trained Naive Bayes classifier with Pickle
LR_pkl_filename = 'LogisticRegression.pkl'
# Open the file to save as pkl file
LR_Model_pkl = open(DT_pkl_filename, 'wb')
pickle.dump(LogisticRegression, LR_Model_pkl)
# Close the pickle instances
LR_Model_pkl.close()

# In[8]:

#Random Forest
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score

data = pd.read_csv("crop_recommendation.csv")

X = data.drop(['label'], axis=1)
y = data['label']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

rf_clf = RandomForestClassifier(n_estimators=100, random_state=42)
rf_clf.fit(X_train, y_train)

y_pred = rf_clf.predict(X_test)

rf_acc = accuracy_score(y_test, y_pred)
print("Accuracy of Random Forest:", rf_acc*100)

cv_score = cross_val_score(rf_clf, X, y, cv=5)
print("Cross-validation score:", cv_score)
print()

print(classification_report(y_test,y_pred))

#Saving trained Random Forest model
import pickle

# Dump the trained Naive Bayes classifier with Pickle
RF_pkl_filename = 'RandomForest.pkl'

# Open the file to save as pkl file
RF_Model_pkl = open(RF_pkl_filename, 'wb')
pickle.dump(RandomForestClassifier, RF_Model_pkl)

# Close the pickle instances
RF_Model_pkl.close()

# In[9]:

#Accuracy Comparison

import pandas as pd
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score

models = ['Decision Tree', 'SVM', 'Naive Bayes', 'Logistic Regression', 'Random Forest']
accuracies = [dt_acc, svm_acc, nb_acc, lr_acc, rf_acc]

fig, ax = plt.subplots(figsize=(10,7))
colors = ['cyan', 'pink', 'aquamarine', 'turquoise', 'lavender']
bars = ax.bar(models, accuracies, color=colors)

for bar in bars:
    height = bar.get_height()
    ax.text(bar.get_x() + bar.get_width() / 2, height, round(height, 4),
            ha='center', va='bottom', fontsize=12)

ax.set_xlabel('Model')
ax.set_ylabel('Accuracy')
ax.set_title('Comparison of Accuracy for Different Classifiers')
plt.show()

# In[10]:

import pandas as pd
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score

classifiers = [dt_clf, nb_clf, svm_clf, lr_clf, rf_clf]

scores = []
for clf in classifiers:
    cv_scores = cross_val_score(clf, X, y, cv=10)
    scores.append(cv_scores)

fig = plt.figure(figsize=(10, 7))
ax = fig.add_subplot(111)
bp = ax.boxplot(scores, patch_artist=True)
plt.setp(bp['boxes'], facecolor='lightblue')
plt.setp(bp['whiskers'], color='black')
plt.setp(bp['caps'], color='black')
plt.setp(bp['medians'], color='red')
plt.setp(bp['fliers'], marker='o', markersize=3, markerfacecolor='blue')
ax.set_xticklabels(['Naive Bayes', 'SVM', 'Random Forest', 'Logistic Regression', 'Decision Tree'])
ax.set_ylabel('Cross-validation score')
ax.set_title('Comparison of Cross-Validation Scores for Different Classifiers')
plt.show()

# In[11]:

classifiers = [dt_clf, nb_clf, svm_clf, lr_clf, rf_clf]
acc = [dt_acc, svm_acc, nb_acc, lr_acc, rf_acc]

# Create a dictionary that maps each classifier name to its accuracy score
accuracy_models = dict(zip(classifiers, acc))

# Print the dictionary
for k, v in accuracy_models.items():
    print (k, '==>', v)

# In[12]:

import numpy as np

# Define a single data instance to predict the crop label for
data_instance = np.array([[90, 42, 43, 23.6, 50.2, 6.8, 187.2]])

# Use the pre-trained Random Forest classifier to predict the crop label for the data instance
predicted_label = rf_clf.predict(data_instance)

# Print the predicted crop label
print("Predicted crop label:", predicted_label)

# In[13]:

import numpy as np

# Define a single data instance to predict the crop label for
data_instance = np.array([[83, 45, 60, 28, 70.3, 7.0, 150.9]])

# Use the pre-trained Random Forest classifier to predict the crop label for the data instance
predicted_label = rf_clf.predict(data_instance)

# Print the predicted crop label
print("Predicted crop label:", predicted_label)


import numpy as np
from config import *
from KnowledgeSent import KnowledgeSentence
from transformers import BertTokenizer, BertModel
import torch

hops = FLAGS.hops
string_year = str(FLAGS.year)
number = 0
start = FLAGS.start
end = FLAGS.end
if string_year == '2015':
    number = 3864
elif string_year == '2016':
    number = 5640

class Embeddings(object):
    '''
    For each input sentence:
    - Token embedding of each token
    - Segment embedding
    - Position embedding
    - Visibility matrix
    '''

    def __init__(self, sofpos=True, vm=True):
        self.sentences = []  # list of list of all tokens for a sentence
        self.visible_matrices = []
        self.vm_tensors = [] # a list of visible matrices for each sentence in tensor-shape of 1*token_numb*token_numb.
        self.soft_positions = [] # list of list of softpositions for each sentence
        self.segments = [] # list of list of segments for each sentence
        self.embeddings = []  # a list with intial embeddings for each token in tensor-shape of 1*token_numb*768
        self.hidden_states = []  # list of hidden states
        self.token_hidden_states = []  # list with for each token, the token and the hidden states
        self.tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
        self.model = BertModel.from_pretrained('bert-base-uncased', output_hidden_states=True)
        self.model.eval()
        self.sofpos = sofpos
        self.vm = vm

    def makeEmbeddings(self):
        count = 0
        with open('data/externalData/' + 'raw_data' + string_year + '.txt', 'r') as raw_data:
            line_list = raw_data.readlines()
            for i in range(start*3, min(number, end*3)):
                if i % 600 == 0:
                    print('another 200, ({}/{})'.format(i, min(number, end*3)))
                if count % 3 == 0 :  # if it is a sentence line
                    # add CLS and SEP and remove target sign
                    sentence = "[CLS] " + line_list[i].replace('$T$', line_list[i+1].replace('\n', '')) + " [SEP]"
                    # add no knowledge
                    sent = KnowledgeSentence(sentence, hops, self.tokenizer, include_knowledge=False)
                    self.sentences.append(sent.sentence)
                    self.soft_positions.append(sent.soft_positions)
                    self.segments.append(sent.segments)
                    self.visible_matrices.append(sent.visibility_matrix)
                else:  # if it is a target line or sentiment line
                    pass
                count += 1
            # append the raw test data and add knowledge
            for i in range(max(number, start*3), end*3):
                if i % 600 == 0:
                    print('another 200 ({}/{})'.format(i, end*3))
                if count % 3 == 0: # if it is a sentence line
                    # add CLS and SEP and replace $T$-token with target-token
                    sentence = "[CLS] " + line_list[i].replace('$T$', line_list[i+1].replace('\n', '')) + " [SEP]"
                    # add knowledge to sentence
                    know_sent = KnowledgeSentence(sentence, hops, self.tokenizer, include_knowledge=True)
                    self.sentences.append(know_sent.sentence)
                    self.soft_positions.append(know_sent.soft_positions)
                    self.segments.append(know_sent.segments)
                    if self.vm:
                        self.visible_matrices.append(know_sent.visibility_matrix)
                    else:
                        self.visible_matrices.append(np.ones((len(know_sent.sentence), len(know_sent.sentence))))
                else: # if it is a target line or sentiment line
                    pass
                count += 1

        print('Creating embeddings...')
        for i in range(len(self.sentences)):
            token_tensor = torch.tensor([self.tokenizer.convert_tokens_to_ids(self.sentences[i])])
            segment_tensor = torch.tensor([self.segments[i]])
            pos_tensor = torch.tensor([self.soft_positions[i]])
            if self.sofpos:
                output = self.model(token_tensor, None, segment_tensor, pos_tensor)
            else:
                output = self.model(token_tensor, None, segment_tensor, None)
            tensor = output.hidden_states.__getitem__(00)

            self.embeddings.append(tensor)
            self.vm_tensors.append(torch.tensor(self.visible_matrices[i]))
        print('Embeddings created!')


import cv2
from matplotlib.pyplot import contour
import numpy as np
import matplotlib.pyplot as plt
from random import randint
import matplotlib.pyplot as plt

def DetectPositionMaxSkin(filename,x, y, w, h, lower, upper):
    #y=y+50
    Image = cv2.VideoCapture(filename)

    #Image = cv2.VideoCapture('t8.mp4')
    success, frame = Image.read()

    while success :
        success, frame = Image.read()
        #cv2.imshow('Imagem Original', frame)
        if success:
            cropeedIMAGE = frame[y:y+h, x:x+w]

            converted = cv2.cvtColor(cropeedIMAGE, cv2.COLOR_BGR2HSV)
            #cv2.imshow('convertedHSV',converted)
            skinMask = cv2.inRange(converted, lower, upper)
            #cv2.imshow('skin',skinMask)

            # apply a series of erosions and dilations to the mask
            # using an elliptical kernel
            kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (12, 12))
            skinMask = cv2.erode(skinMask, kernel, iterations=3)
            skinMask = cv2.dilate(skinMask, kernel, iterations=3)

            # blur the mask to help remove noise, then apply the
            # mask to the frame
            skinMask = cv2.GaussianBlur(skinMask, (11, 11), 5)
            #cv2.imshow('skinMask',skinMask)
            skin = cv2.bitwise_and(cropeedIMAGE, cropeedIMAGE, mask=skinMask)
            #cv2.imshow('skin',skin)

            ########################################################
            #lowerFinger =np.array([8, 15, 110], dtype="uint8")
            #upperFinger = np.array([8, 15, 110], dtype="uint8")

            hsv_img = cv2.cvtColor(skin, cv2.COLOR_BGR2HSV)
            #hsv_img = cv2.inRange(hsv_img, lowerFinger, upperFinger)
            #cv2.imshow('hsv_img', hsv_img)

            # Extracting Saturation channel on which we will work
            img_s = hsv_img[:, :, 1]
            #img_s = skin[:, :, 1]
            #cv2.imshow('img_s', img_s)

            # smoothing before applying  threshold
            img_s_blur = cv2.GaussianBlur(img_s, (7,7), 2)
            #img_s_blur = cv2.medianBlur(skin,5)
            #cv2.imshow('img_s_blur', img_s_blur)

            img_s_binary = cv2.threshold(img_s_blur, 200, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]  # Thresholding to generate binary image (ROI detection)
            #cv2.imshow('img_s_binary1', img_s_binary1)

            # reduce some noise
            kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (4, 4))
            img_s_binary = cv2.morphologyEx(img_s_binary, cv2.MORPH_OPEN, kernel, iterations=4)
            #cv2.imshow('img_s_binary1', img_s_binary)

            # ROI only image extraction & contrast enhancement, you can crop this region
            #img_croped = cv2.bitwise_and(img_s, img_s_binary) * 10
            #cv2.imshow('img_croped', img_croped)

             #  eliminate
            kernel = np.ones((5, 5), np.float32)/25
            processedImage = cv2.filter2D(img_s_binary, -1, kernel)
            img_s_binary[processedImage > 250] = 0
            #cv2.imshow('img_s_binary2', img_s_binary)

            edges = cv2.threshold(img_s_binary, 100, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
            #th3 = cv2.adaptiveThreshold(img_s_blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
            #_,edges = cv2.threshold(img_croped, 160, 255, cv2.THRESH_BINARY_INV)

            #cv2.imshow('edges', edges)

            #https://docs.opencv.org/3.4/da/d0c/tutorial_bounding_rects_circles.html
            contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
            #print("Number of contours =" + str(len(contours)))
            #print("Number of hierarchy =" + str(len(hierarchy)))
            #print(np.argmax(hierarchy))

            contours_poly = [None]*len(contours)
            centers = [None]*len(contours)
            radius = [None]*len(contours)
            #area= [None]*len(contours)

            #drawing = np.zeros((edges.shape[0], edges.shape[1], 3), dtype=np.uint8)
            for i, c in enumerate(contours):
                contours_poly[i] = cv2.approxPolyDP(c, 0.02, True)
                #boundRect[i] = cv2.boundingRect(contours_poly[i])
                centers[i], radius[i] = cv2.minEnclosingCircle(contours_poly[i])
                #area[i] = cv2.contourArea(contours[i])
                #print("area: %s" % area)
                #if i>=6 and cv2.contourArea(contours[i]) >= 100:
                if  5000 >= cv2.contourArea(contours[i]) <= 7600 and radius[i] < 50:
                    #cv2.drawContours(skin, contours_poly, i, (255,0,0))
                    cv2.circle(skin, (int(centers[i][0]), int(centers[i][1])), int(radius[i]), (0,0,255), 2)
                    #cv2.imshow('Contours', skin)
                    cv2.imshow('skin', skin)

                    #print((centers[i][0]))S
                    #xe=np.arange(1,121)
                    #print(len(xe))
                    #plt.plot(x,centers[i][0],'ro')
                    #plt.ylabel('some numbers')
                    #plt.show()

        #cv2.imshow('Skin Mask', skinMask)
        #cv2.imshow('Skin', skin)

        #vcat = cv2.hconcat((skinMask, skin))
        #cv2.imshow('vcat', vcat)

        #cv2.imshow('hsv_img', hsv_img)
        #cv2.imshow('Extracting Saturation', img_s)
        #cv2.imshow('img_s_binary1', img_s_binary1)
        #cv2.imshow('img_croped', img_croped)
        #cv2.imshow('edges', edges)

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

    cv2.destroyAllWindows()

    #xc,yc,wc,hc,skin,skinMask,hsv_img,img_s_blur,img_s_binary1,img_croped,edges,cropeedIMAGE


from itertools import chain
import os
import pytest

@pytest.fixture(scope="module")
def organization_id():
    """Get Organization ID from the environment variable """
    return os.environ["GCLOUD_ORGANIZATION"]

@pytest.fixture(scope="module")
def source_name(organization_id):
    from google.cloud import securitycenter

    client = securitycenter.SecurityCenterClient()
    org_name = "organizations/{org_id}".format(org_id=organization_id)

    source = client.create_source(
        org_name,
        {
            "display_name": "Unit test source",
            "description": "A new custom source that does X",
        },
    )
    return source.name

def test_create_source(organization_id):
    """Create a new findings source. """
    # [START create_source]
    from google.cloud import securitycenter

    client = securitycenter.SecurityCenterClient()
    # organization_id is the numeric ID of the organization. e.g.:
    # organization_id = "111122222444"
    org_name = "organizations/{org_id}".format(org_id=organization_id)

    created = client.create_source(
        org_name,
        {
            "display_name": "Customized Display Name",
            "description": "A new custom source that does X",
        },
    )
    print("Created Source: {}".format(created.name))
    # [END create_source]

def test_get_source(source_name):
    """Gets an existing source."""
    # [START get_source]
    from google.cloud import securitycenter

    client = securitycenter.SecurityCenterClient()

    # source_name is the resource path for a source that has been
    # created previously (you can use list_sources to find a specific one).
    # Its format is:
    # source_name = "organizations/{organization_id}/sources/{source_id}"
    # e.g.:
    # source_name = "organizations/111122222444/sources/1234"
    source = client.get_source(source_name)

    print("Source: {}".format(source))
    # [END get_source]

def test_update_source(source_name):
    """Updates a source's display name."""
    # [START update_source]
    from google.cloud import securitycenter
    from google.protobuf import field_mask_pb2

    client = securitycenter.SecurityCenterClient()

    # Field mask to only update the display name.
    field_mask = field_mask_pb2.FieldMask(paths=["display_name"])

    # source_name is the resource path for a source that has been
    # created previously (you can use list_sources to find a specific one).
    # Its format is:
    # source_name = "organizations/{organization_id}/sources/{source_id}"
    # e.g.:
    # source_name = "organizations/111122222444/sources/1234"
    updated = client.update_source(
        {"name": source_name, "display_name": "Updated Display Name"},
        update_mask=field_mask,
    )
    print("Updated Source: {}".format(updated))
    # [END update_source]
    assert updated.display_name == "Updated Display Name"

def test_add_user_to_source(source_name):
    """Gives a user findingsEditor permission to the source."""
    user_email = "csccclienttest@gmail.com"
    # [START update_source_iam]
    from google.cloud import securitycenter
    from google.iam.v1 import policy_pb2

    client = securitycenter.SecurityCenterClient()

    # source_name is the resource path for a source that has been
    # created previously (you can use list_sources to find a specific one).
    # Its format is:
    # source_name = "organizations/{organization_id}/sources/{source_id}"
    # e.g.:
    # source_name = "organizations/111122222444/sources/1234"
    # Get the old policy so we can do an incremental update.
    old_policy = client.get_iam_policy(source_name)
    print("Old Policy: {}".format(old_policy))

    # Setup a new IAM binding.
    binding = policy_pb2.Binding()
    binding.role = "roles/securitycenter.findingsEditor"
    # user_email is an e-mail address known to Cloud IAM (e.g. a gmail address).
    # user_mail = user@somedomain.com
    binding.members.append("user:{}".format(user_email))

    # Setting the e-tag avoids over-write existing policy
    updated = client.set_iam_policy(
        source_name, {"etag": old_policy.etag, "bindings": [binding]}
    )

    print("Updated Policy: {}".format(updated))

    # [END update_source_iam]
    assert any(
        member == "user:csccclienttest@gmail.com"
        for member in chain.from_iterable(
            binding.members for binding in updated.bindings
        )
    )

def test_list_source(organization_id):
    """Lists finding sources."""
    i = -1
    # [START list_sources]
    from google.cloud import securitycenter

    # Create a new client.
    client = securitycenter.SecurityCenterClient()
    # organization_id is the numeric ID of the organization. e.g.:
    # organization_id = "111122222444"
    org_name = "organizations/{org_id}".format(org_id=organization_id)

    # Call the API and print out each existing source.
    for i, source in enumerate(client.list_sources(org_name)):
        print(i, source)
    # [END list_sources]
    assert i >= 0

def test_create_finding(source_name):
    """Creates a new finding."""
    # [START create_finding]
    from google.cloud import securitycenter
    from google.cloud.securitycenter_v1.proto.finding_pb2 import Finding
    from google.protobuf.timestamp_pb2 import Timestamp

    # Create a new client.
    client = securitycenter.SecurityCenterClient()

    # Use the current time as the finding "event time".
    now_proto = Timestamp()
    now_proto.GetCurrentTime()

    # source_name is the resource path for a source that has been
    # created previously (you can use list_sources to find a specific one).
    # Its format is:
    # source_name = "organizations/{organization_id}/sources/{source_id}"
    # e.g.:
    # source_name = "organizations/111122222444/sources/1234"

    # Controlled by caller.
    finding_id = "samplefindingid"

    # The resource this finding applies to.  The CSCC UI can link
    # the findings for a resource to the corresponding Asset of a resource
    # if there are matches.
    resource_name = "//cloudresourcemanager.googleapis.com/organizations/11232"

    # Call The API.
    created_finding = client.create_finding(
        source_name,
        finding_id,
        {
            "state": Finding.ACTIVE,
            "resource_name": resource_name,
            "category": "MEDIUM_RISK_ONE",
            "event_time": now_proto,
        },
    )
    print(created_finding)
    # [END create_finding]
    assert len(created_finding.name) > 0

def test_create_finding_with_source_properties(source_name):
    """Demonstrate creating a new finding with source properties. """
    # [START create_finding_with_properties]
    from google.cloud import securitycenter
    from google.cloud.securitycenter_v1.proto.finding_pb2 import Finding
    from google.protobuf.timestamp_pb2 import Timestamp
    from google.protobuf.struct_pb2 import Value

    # Create a new client.
    client = securitycenter.SecurityCenterClient()

    # source_name is the resource path for a source that has been
    # created previously (you can use list_sources to find a specific one).
    # Its format is:
    # source_name = "organizations/{organization_id}/sources/{source_id}"
    # e.g.:
    # source_name = "organizations/111122222444/sources/1234"

    # Controlled by caller.
    finding_id = "samplefindingid2"

    # The resource this finding applies to.  The CSCC UI can link
    # the findings for a resource to the corresponding Asset of a resource
    # if there are matches.
    resource_name = "//cloudresourcemanager.googleapis.com/organizations/11232"

    # Define source properties values as protobuf "Value" objects.
    str_value = Value()
    str_value.string_value = "string_example"
    num_value = Value()
    num_value.number_value = 1234

    # Use the current time as the finding "event time".
    now_proto = Timestamp()
    now_proto.GetCurrentTime()

    created_finding = client.create_finding(
        source_name,
        finding_id,
        {
            "state": Finding.ACTIVE,
            "resource_name": resource_name,
            "category": "MEDIUM_RISK_ONE",
            "source_properties": {"s_value": str_value, "n_value": num_value},
            "event_time": now_proto,
        },
    )
    print(created_finding)
    # [END create_finding_with_properties]

def test_update_finding(source_name):
    # [START update_finding]
    from google.cloud import securitycenter
    from google.protobuf.struct_pb2 import Value
    from google.protobuf import field_mask_pb2
    from google.protobuf.timestamp_pb2 import Timestamp

    client = securitycenter.SecurityCenterClient()
    # Only update the specific source property and event_time.  event_time
    # is required for updates.
    field_mask = field_mask_pb2.FieldMask(
        paths=["source_properties.s_value", "event_time"]
    )
    value = Value()
    value.string_value = "new_string"

    # Set the update time to Now.  This must be some time greater then the
    # event_time on the original finding.
    now_proto = Timestamp()
    now_proto.GetCurrentTime()

    # source_name is the resource path for a source that has been
    # created previously (you can use list_sources to find a specific one).
    # Its format is:
    # source_name = "organizations/{organization_id}/sources/{source_id}"
    # e.g.:
    # source_name = "organizations/111122222444/sources/1234"
    finding_name = "{}/findings/samplefindingid2".format(source_name)
    updated_finding = client.update_finding(
        {
            "name": finding_name,
            "source_properties": {"s_value": value},
            "event_time": now_proto,
        },
        update_mask=field_mask,
    )

    print(
        "New Source properties: {}, Event Time {}".format(
            updated_finding.source_properties, updated_finding.event_time.ToDatetime()
        )
    )
    # [END update_finding]

def test_update_finding_state(source_name):
    """Demonstrate updating only a finding state."""
    # [START update_finding_state]
    from google.cloud import securitycenter
    from google.cloud.securitycenter_v1.proto.finding_pb2 import Finding
    from google.protobuf.timestamp_pb2 import Timestamp
    from datetime import datetime

    # Create a client.
    client = securitycenter.SecurityCenterClient()
    # source_name is the resource path for a source that has been
    # created previously (you can use list_sources to find a specific one).
    # Its format is:
    # source_name = "organizations/{organization_id}/sources/{source_id}"
    # e.g.:
    # source_name = "organizations/111122222444/sources/1234"
    finding_name = "{}/findings/samplefindingid2".format(source_name)

    now_proto = Timestamp()
    now_proto.GetCurrentTime()

    # Call the API to change the finding state to inactive as of now.
    new_finding = client.set_finding_state(
        finding_name, Finding.INACTIVE, start_time=now_proto
    )
    print("New state: {}".format(Finding.State.Name(new_finding.state)))
    # [END update_finding_state]

def test_trouble_shoot(source_name):
    """Demonstrate calling test_iam_permissions to determine if the
    service account has the correct permisions."""
    # [START test_iam_permissions]
    from google.cloud import securitycenter

    # Create a client.
    client = securitycenter.SecurityCenterClient()
    # source_name is the resource path for a source that has been
    # created previously (you can use list_sources to find a specific one).
    # Its format is:
    # source_name = "organizations/{organization_id}/sources/{source_id}"
    # e.g.:
    # source_name = "organizations/111122222444/sources/1234"

    # Check for permssions to call create_finding or update_finding.
    permission_response = client.test_iam_permissions(
        source_name, ["securitycenter.findings.update"]
    )

    print(
        "Permision to create or update findings? {}".format(
            len(permission_response.permissions) > 0
        )
    )
    # [END test_iam_permissions]
    assert len(permission_response.permissions) > 0
    # [START test_iam_permissions]
    # Check for permissions necessary to call set_finding_state.
    permission_response = client.test_iam_permissions(
        source_name, ["securitycenter.findings.setState"]
    )
    print(
        "Permision to update state? {}".format(len(permission_response.permissions) > 0)
    )
    # [END test_iam_permissions]
    assert len(permission_response.permissions) > 0

def test_list_all_findings(organization_id):
    # [START list_all_findings]
    from google.cloud import securitycenter

    # Create a client.
    client = securitycenter.SecurityCenterClient()

    # organization_id is the numeric ID of the organization. e.g.:
    # organization_id = "111122222444"
    org_name = "organizations/{org_id}".format(org_id=organization_id)
    # The "sources/-" suffix lists findings across all sources.  You
    # also use a specific source_name instead.
    all_sources = "{org_name}/sources/-".format(org_name=org_name)
    finding_result_iterator = client.list_findings(all_sources)
    for i, finding_result in enumerate(finding_result_iterator):
        print(
            "{}: name: {} resource: {}".format(
                i, finding_result.finding.name, finding_result.finding.resource_name
            )
        )
    # [END list_all_findings]
    assert i > 0

def test_list_filtered_findings(source_name):
    # [START list_filtered_findings]
    from google.cloud import securitycenter

    # Create a new client.
    client = securitycenter.SecurityCenterClient()

    # source_name is the resource path for a source that has been
    # created previously (you can use list_sources to find a specific one).
    # Its format is:
    # source_name = "organizations/{organization_id}/sources/{source_id}"
    # e.g.:
    # source_name = "organizations/111122222444/sources/1234"
    # You an also use a wild-card "-" for all sources:
    #   source_name = "organizations/111122222444/sources/-"
    finding_result_iterator = client.list_findings(
        source_name, filter_='category="MEDIUM_RISK_ONE"'
    )
    # Iterate an print all finding names and the resource they are
    # in reference to.
    for i, finding_result in enumerate(finding_result_iterator):
        print(
            "{}: name: {} resource: {}".format(
                i, finding_result.finding.name, finding_result.finding.resource_name
            )
        )
    # [END list_filtered_findings]
    assert i > 0

def test_list_findings_at_time(source_name):
    # [START list_findings_at_a_time]
    from google.cloud import securitycenter
    from google.protobuf.timestamp_pb2 import Timestamp
    from datetime import timedelta, datetime

    # Create a new client.
    client = securitycenter.SecurityCenterClient()

    # source_name is the resource path for a source that has been
    # created previously (you can use list_sources to find a specific one).
    # Its format is:
    # source_name = "organizations/{organization_id}/sources/{source_id}"
    # e.g.:
    # source_name = "organizations/111122222444/sources/1234"
    # You an also use a wild-card "-" for all sources:
    #   source_name = "organizations/111122222444/sources/-"
    five_days_ago = Timestamp()
    five_days_ago.FromDatetime(datetime.now() - timedelta(days=5))
    # [END list_findings_at_a_time]
    i = -1
    five_days_ago.FromDatetime(datetime(2019, 3, 5, 0, 0, 0))
    # [START list_findings_at_a_time]

    finding_result_iterator = client.list_findings(source_name, read_time=five_days_ago)
    for i, finding_result in enumerate(finding_result_iterator):
        print(
            "{}: name: {} resource: {}".format(
                i, finding_result.finding.name, finding_result.finding.resource_name
            )
        )
    # [END list_findings_at_a_time]
    assert i == -1

def test_get_iam_policy(source_name):
    """Gives a user findingsEditor permission to the source."""
    user_email = "csccclienttest@gmail.com"
    # [START get_source_iam]
    from google.cloud import securitycenter
    from google.iam.v1 import policy_pb2

    client = securitycenter.SecurityCenterClient()

    # source_name is the resource path for a source that has been
    # created previously (you can use list_sources to find a specific one).
    # Its format is:
    # source_name = "organizations/{organization_id}/sources/{source_id}"
    # e.g.:
    # source_name = "organizations/111122222444/sources/1234"
    # Get the old policy so we can do an incremental update.
    policy = client.get_iam_policy(source_name)
    print("Policy: {}".format(policy))
    # [END get_source_iam]

def test_group_all_findings(organization_id):
    """Demonstrates grouping all findings across an organization."""
    # [START group_all_findings]
    from google.cloud import securitycenter

    # Create a client.
    client = securitycenter.SecurityCenterClient()

    # organization_id is the numeric ID of the organization. e.g.:
    # organization_id = "111122222444"
    org_name = "organizations/{org_id}".format(org_id=organization_id)
    # The "sources/-" suffix lists findings across all sources.  You
    # also use a specific source_name instead.
    all_sources = "{org_name}/sources/-".format(org_name=org_name)
    group_result_iterator = client.group_findings(all_sources, group_by="category")
    for i, group_result in enumerate(group_result_iterator):
        print((i + 1), group_result)
    # [END group_all_findings]
    assert i > 0

def test_group_filtered_findings(source_name):
    """Demonstrates grouping all findings across an organization."""
    # [START group_filtered_findings]
    from google.cloud import securitycenter

    # Create a client.
    client = securitycenter.SecurityCenterClient()

    # source_name is the resource path for a source that has been
    # created previously (you can use list_sources to find a specific one).
    # Its format is:
    # source_name = "organizations/{organization_id}/sources/{source_id}"
    # e.g.:
    # source_name = "organizations/111122222444/sources/1234"

    group_result_iterator = client.group_findings(
        source_name, group_by="category", filter_='state="ACTIVE"'
    )
    for i, group_result in enumerate(group_result_iterator):
        print((i + 1), group_result)
    # [END group_filtered_findings]
    assert i == 0

def test_group_findings_at_time(source_name):
    """Demonstrates grouping all findings across an organization as of
    a specific time."""
    i = -1
    # [START group_findings_at_time]
    from datetime import datetime, timedelta
    from google.cloud import securitycenter
    from google.protobuf.timestamp_pb2 import Timestamp

    # Create a client.
    client = securitycenter.SecurityCenterClient()

    # source_name is the resource path for a source that has been
    # created previously (you can use list_sources to find a specific one).
    # Its format is:
    # source_name = "organizations/{organization_id}/sources/{source_id}"
    # e.g.:
    # source_name = "organizations/111122222444/sources/1234"

    # Group findings as of yesterday.
    read_time = datetime.utcnow() - timedelta(days=1)
    timestamp_proto = Timestamp()
    timestamp_proto.FromDatetime(read_time)

    group_result_iterator = client.group_findings(
        source_name, group_by="category", read_time=timestamp_proto
    )
    for i, group_result in enumerate(group_result_iterator):
        print((i + 1), group_result)
    # [END group_filtered_findings_at_time]
    assert i == -1

def test_group_findings_and_changes(source_name):
    """Demonstrates grouping all findings across an organization and
    associated changes."""
    # [START group_filtered_findings_with_changes]
    from datetime import timedelta

    from google.cloud import securitycenter
    from google.protobuf.duration_pb2 import Duration

    # Create a client.
    client = securitycenter.SecurityCenterClient()

    # source_name is the resource path for a source that has been
    # created previously (you can use list_sources to find a specific one).
    # Its format is:
    # source_name = "organizations/{organization_id}/sources/{source_id}"
    # e.g.:
    # source_name = "organizations/111122222444/sources/1234"

    # List assets and their state change the last 30 days
    compare_delta = timedelta(days=30)
    # Convert the timedelta to a Duration
    duration_proto = Duration()
    duration_proto.FromTimedelta(compare_delta)

    group_result_iterator = client.group_findings(
        source_name, group_by="state_change", compare_duration=duration_proto
    )
    for i, group_result in enumerate(group_result_iterator):
        print((i + 1), group_result)
    # [END group_findings_with_changes]
    assert i == 0


#coding: utf-8
import tornado.web
from basehandler import BaseHandler
from lib.lrclib import LrcLib
from lib.songinfo import SongInfo
from models import MusicModel, UserModel
import json
import re

import logging
log = logging.getLogger("index")
log.setLevel(logging.DEBUG)
rm_regex = r"/(\([^\)]*\))|(\[[^\]]*\])|(（[^）]*）)|(【[^】]*】)|((-|\/|&).*)/g"
def simplify(string):
  return re.sub(rm_regex, "", string)

class IndexHandler(BaseHandler):

  def __init__(self, application, request, **kwargs):
    self._lrclib = LrcLib()
    self._info = SongInfo()
    self._music = MusicModel()
    self._users = UserModel()
    super(IndexHandler, self).__init__(application, request, **kwargs)
  def get(self):
    user_id = self.current_user
    log.debug("user_id is {0}".format(user_id))
    # if not user_id:
      # return self.render('login.html')
    account = ""
    if user_id:
      user = self._users.get_one(user_id)
      log.debug(user)
      if user:
        account = user["account"]
    return self.render('index.html', current_user = account, domain=self.request.full_url())

  def on_error(self):
    return self.write(json.dumps({
                    "code": 1
                  }))

  def post(self):
    request = json.loads(self.request.body)
    song = dict(
                  sid = request.get("songId"),
                  artist = request.get("artist"),
                  title = request.get("title"),
                  channel = request.get("channel"),
                  share_url = request.get("shareUrl"),
                  album_img = request.get("albumImgUrl"),
                  start_time = request.get("startTime")
              )
    lrc, song_info = self._music.get_rep(song["sid"])
    if lrc and song_info:
      lrc.update({"startTime": song["start_time"]})
      return self.write(json.dumps({
                                    "code": 0,
                                    "lyricsInfo": lrc,
                                    "songInfo": song_info
                                  }))
    lrc = self._lrclib.getlrc(simplify(song["title"]), simplify(song["artist"]))
    if not song_info:
      info_res = self._info.get_info(song["share_url"])
      if not info_res:
        return self.on_error()
      song_info = info_res["song"][0]
      song_info = {
                    "album": song_info["albumtitle"],
                    "albumId": song_info["aid"],
                    "albumImgUrl": song_info["picture"],
                    "albumUrl": song_info["album"],
                    "artist": song_info["artist"],
                    "company": song_info["company"],
                    "duration": song_info["length"],
                    "mp3Url": song_info["url"],
                    "rating": song_info["rating_avg"],
                    "releaseYear": song_info["public_time"],
                    "songId": song_info["sid"],
                    "ssid": song_info["ssid"],
                    "startToken": song_info["start_token"],
                    "title": song_info["title"],
                    "shareUrl": song["share_url"]
                  }
    response = json.dumps({
                "code": 0,
                "lyricsInfo": {
                        "lyrics": lrc,
                        "offset": 0,
                        "startTime": song["start_time"]
                      },
                "songInfo": song_info
              })
    self._music.set_rep(song["sid"], dict(lyrics=lrc,offset=0), song_info)
    return self.write(response)


import base64

from django.shortcuts import render
from django.http import JsonResponse
from django.views.decorators.cache import never_cache

from stolen_wiki_game.models import Article

# Create your views here.
def index(request):
    return render(request, 'stolen_wiki_game/index.html', {})

@never_cache
def article(request):
    art = Article.objects.order_by('?').first()
    encoded = base64.b64encode(art.slug.encode('ascii')).decode('ascii')
    return JsonResponse({
        'article': encoded,
        'redactleIndex': 0,
        'token': 'abc',
        'yesterday': 'blah'
    })


# coding:utf-8

from flask import request
from flask import Flask,  render_template
from controller import search, getPage, get_suggestion
import sys
import json
# reload(sys)
# sys.setdefaultencoding('utf-8')

app = Flask(__name__)

@app.route('/')
def index():
    return "the server is running!"
   # return render_template('/result.html',name = 'zhangsan',)

@app.route('/search', methods=['GET'])
def do_search():
    print(request.args)
    params = {
        'query': request.args.get('query'),
        'method': request.args.get('method')
    }
    res = search(params)
    return json.dumps({
        'status': 1,
        'result': res['result'],
        'time': res['time']
    }, ensure_ascii=False)

@app.route('/page', methods=['GET'])
def page():
    docId = request.args.get('id')
    res = getPage(docId)
    return json.dumps({
        'status': 1,
        'page': res
    }, ensure_ascii=False)

@app.route('/suggestion', methods=['GET'])
def suggestion():
    query =request.args.get('query')
    res = get_suggestion(query)
    return json.dumps({
        'status':1,
        'queries':res
    }, ensure_ascii=False)

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5000, debug=False)


import matplotlib.pyplot as plt
import eel

eel.init("web")

userid = []

@eel.expose
def login(uid,upass):
    get = open("data.txt", "r")
    temp = get.readlines()
    udata = []

    for i in range(len(temp)):
        if temp[i].startswith(uid):
            udata = temp[i].split("|")
    #print(udata)
    if udata[2] != upass:
        return "false"
    else:
        if udata[0].startswith("vt"):
            return udata,"voter"
        elif udata[0].startswith("ca"):
            return udata,"candidate"
        elif udata[0].startswith("st"):
            return udata,"staff"
    get.close()

def vsort():
    get = open("data.txt", "r")
    get.seek(0)
    temp = get.readlines()

    v = []
    c = []
    s = []
    l = ""

    for i in range(len(temp)):
        if temp[i].startswith("vt"):
            v.append(temp[i])
        if temp[i].startswith("st"):
            s.append(temp[i])
        if temp[i].startswith("ca"):
            c.append(temp[i])
        if temp[i].startswith("system"):
            l = temp[i]

    fout = open("data.txt", "w")
    v.sort()
    c.sort()
    s.sort()
    for j in range(len(c)):
        final = f"{c[j]}"
        fout.write(final)
    for j in range(len(s)):
        final = f"{s[j]}"
        fout.write(final)
    for j in range(len(v)):
        final = f"{v[j]}"
        fout.write(final)
    fout.write(l)
    fout.close()

    fin1 = open("data.txt","r")
    fin2 = open("index.txt","w")
    fin1.seek(0)

    details = fin1.readlines()
    for i in range(len(details)):
        data = details[i].split("|")
        fin2.write(f"{i}|{data[0]}|\n")
    fin1.close()

    fin2.close()
    get.close()

@eel.expose
def display_teams():
    gets = open("data.txt", "r")
    temp = gets.readlines()
    clist = []
    iget = open("index.txt","r")
    index = iget.readlines()
    cid=[]
    fdata = []
    for i in range(len(index)):
        data = index[i].split("|")
        if data[1].startswith("ca"):
            cid.append(data[0])

    for i in cid:
        i=int(i)
        clist.append(temp[i])

    for i in range(len(clist)):
        data = clist[i].split("|")
        fdata.append(f"{data[0]}|{data[1]}|{data[3]}|")
    print(fdata)
    gets.close()
    iget.close()
    return fdata

@eel.expose
def display_voter(uid):
    gets = open("data.txt", "r")
    temp = gets.readlines()
    clist = []
    iget = open("index.txt","r")
    index = iget.readlines()
    cid=[]
    fdata = []
    for i in range(len(index)):
        data = index[i].split("|")
        if data[1].startswith(uid):
            cid.append(data[0])
    for i in cid:
        i=int(i)
        clist.append(temp[i])
    for i in range(len(clist)):
        data = clist[i].split("|")
        fdata = data
    gets.close()
    iget.close()
    return fdata

def system_status():
    data = []
    get = open("data.txt","r")
    temp = get.readlines()
    for i in range(len(temp)):
        if temp[i].startswith("system"):
            data = temp[i].split("|")
    if data[1]=="true":
        return True
    elif data[1]=="false":
        return False
    get.close()

@eel.expose
def cast_vote(cid,uid):
    iget=open("index.txt","r")
    index = iget.readlines()
    get = open("data.txt","r")
    temp = get.readlines()
    cindex = ""
    vindex = ""
    cdata = []
    vdata = []

    for i in range(len(index)):
        data = index[i].split("|")
        if data[1].startswith(cid):
            cindex = data[0]
        if data[1].startswith(uid):
            vindex = data[0]

    vidx =int(vindex)
    cidx =int(cindex)
    vdata = temp[vidx].split("|")
    cdata = temp[cidx].split("|")
    val = system_status()

    if val:
        if vdata[5] == "false":
            vote = int(cdata[4])
            vote += 1
            cdata[4] = vote
            vdata[5] = "true"
            cupdate = f"{cdata[0]}|{cdata[1]}|{cdata[2]}|{cdata[3]}|{cdata[4]}|\n"
            vupdate = f"{vdata[0]}|{vdata[1]}|{vdata[2]}|{vdata[3]}|{vdata[4]}|{vdata[5]}|\n"
            fout = open("data.txt","w")
            for i in range(len(temp)):
                if temp[i].startswith(vdata[0]):
                    temp[i] = vupdate
                if temp[i].startswith(cdata[0]):
                    temp[i] = cupdate
            for i in range(len(temp)):
                fout.write(temp[i])
            fout.close()
            iget.close()
            get.close()
            return "voted successfully"
        else:
            iget.close()
            get.close()
            return "it seems you have already voted"
    else:
        return("Vote System is Inactive")

@eel.expose
def profile(vid):
    print(vid)
    iget = open("index.txt","r")
    index = iget.readlines()
    get = open("data.txt","r")
    temp = get.readlines()
    pid = ""
    for i in range(len(index)):
        data = index[i].split("|")
        if data[1] == vid:
            pid = data[0]
    pid = int(pid)
    user_data = temp[pid].split("|")
    print(user_data)
    get.close()
    iget.close()
    return user_data,"true"
@eel.expose
def winner():
    cid = []
    c_teams = []
    c_votes = []
    iget = open("index.txt","r")
    get = open("data.txt","r")
    index = iget.readlines()
    temp = get.readlines()

    for i in range(len(index)):
        data = index[i].split("|")
        if data[1].startswith("ca"):
            cid.append(data[0])

    for i in cid:
        i=int(i)
        data = temp[i].split("|")
        c_teams.append(data[3])
        c_votes.append(int(data[4]))
    num = max(c_votes)
    id = c_votes.index(num)
    name = c_teams[id]
    plt.bar(c_teams,c_votes)
    plt.savefig("web\output1", facecolor='w', bbox_inches="tight",pad_inches=0.3, transparent=True)
    plt.title('winner')
    plt.xlabel('teams')
    plt.ylabel('Votes')
    get.close()
    iget.close()
    return name

@eel.expose
def system_mod(uid,override_key):
    sid = []
    iget = open("index.txt","r")
    get = open("data.txt","r")
    index = iget.readlines()
    temp = get.readlines()
    details = temp
    flag = False
    for i in range(len(index)):
        data = index[i].split("|")
        if data[1].startswith("st"):
            sid.append(data[0])
    for i in sid:
        i = int(i)
        data = temp[i].split("|")
        if data[0].startswith(uid):
            if data[3].startswith(override_key):
                flag = True
    if flag:
        for i in range(len(details)):
            if details[i].startswith("system"):
                s_data = details[i].split("|")
                if s_data[1] == "true":
                    s_data[1] = "false"
                    s_final = f"{s_data[0]}|{s_data[1]}|"
                    for j in range(len(details)):
                        if details[j].startswith("system"):
                            details[j] = s_final
                    fout = open("data.txt", "r+")
                    for k in range(len(details)):
                        op = f"{details[k]}"
                        fout.write(op)
                    fout.close()
                    vsort()
                    return "System is Inactive"

                elif s_data[1] == "false":
                    s_data[1] = "true"
                    s_final = f"{s_data[0]}|{s_data[1]}|"
                    for j in range(len(details)):
                        if details[j].startswith("system"):
                            details[j] = ""
                            details[j] = s_final
                    fout = open("data.txt", "r+")
                    for k in range(len(details)):
                        op = f"{details[k]}"
                        fout.write(op)
                    fout.close()
                    vsort()
                    return "system is active"

@eel.expose
def reset(uid,override_key):
    sid = []
    key = str(override_key)
    iget = open("index.txt","r")
    get = open("data.txt","r")
    index = iget.readlines()
    temp = get.readlines()
    details = temp
    flag = False
    for i in range(len(index)):
        data = index[i].split("|")
        if data[1].startswith("st"):
            sid.append(data[0])
    for i in sid:
        i = int(i)
        data = temp[i].split("|")
        if data[0].startswith(uid):
            if data[3].startswith(key):
                flag = True
                print("pass")
    if flag:
        for i in range(len(details)):
            if details[i].startswith("vt"):
                data = details[i].split("|")
                data[5] = "false"
                vupdate = f"{data[0]}|{data[1]}|{data[2]}|{data[3]}|{data[4]}|{data[5]}|\n"
                for i in range(len(details)):
                    if details[i].startswith(data[0]):
                        details[i] = vupdate
                fout = open("data.txt", "w")
                for j in range(len(details)):
                    op = f"{details[j]}"
                    fout.write(op)
                fout.close()

            if details[i].startswith("ca"):
                cdata = details[i].split("|")
                cdata[4] = 0
                cupdate = f"{cdata[0]}|{cdata[1]}|{cdata[2]}|{cdata[3]}|{cdata[4]}|\n"
                for i in range(len(details)):
                    if details[i].startswith(cdata[0]):
                        details[i] = cupdate
                fout = open("data.txt", "w")
                for j in range(len(details)):
                    op = f"{details[j]}"
                    fout.write(op)
                fout.close()
        vsort()
        return "System Data is been formated"
    else:
        return "Failed"

@eel.expose
def add_voter(name,password,age,ano):
    get = open("data.txt","r")
    details = get.readlines()
    count = 0
    voters = []
    for i in range(len(details)):
        if details[i].startswith("vt"):
            data = details[i].split("|")
            if data[4] == ano:
                return "person already exsist"

    for i in range(len(details)):
        if details[i].startswith("vt"):
            voters.append(details[i])
    temp = voters[-1].split("|")
    id = temp[0]
    count = id[2:]
    b =  int(count)
    count = b
    if count < 9:
        count = count+1
        vid = "000"+str(count)
    elif count<99:
        count+=1
        vid = "00"+str(count)
    elif count<999:
        count+=1
        vid = "0"+str(count)
    else:
        vid = str(count)

    id = "vt"+vid
    status = "false"
    final = f"{id}|{name}|{password}|{age}|{ano}|{status}|\n"
    details.append(final)
    fout = open("data.txt", "w")
    for j in range(len(details)):
        op = f"{details[j]}"
        fout.write(op)
    fout.close()
    vsort()
    get.close()
    return "Voter added successfully"

@eel.expose
def remove_voter(uid):
    if uid[0:2] == "vt":
        data = []
        get = open("data.txt","r")
        details = get.readlines()
        for i in range(len(details)):
            if details[i].startswith(uid):
                clear = ""
                data=details[i].split("|")
                details[i] = clear
                fout = open("data.txt", "r+")
                for j in range(len(details)):
                    op = f"{details[j]}"
                    fout.write(op)
                fout.close()
        vsort()
        get.close()
        return f"{data[1]}"
    else:
        return "false"

@eel.expose
def modify_voter(uid,name,password,age,ano):
    vid = []
    get = open("data.txt","r")
    iget = open("index.txt","r")
    details=get.readlines()
    index = iget.readlines()
    for i in range(len(index)):
        data = index[i].split("|")
        if data[1].startswith(uid):
            vid = data[0]
    vid = int(vid)
    v_data = details[vid].split("|")
    v_data[1] = name
    v_data[2] = password
    v_data[3] = age
    v_data[4] = ano
    vupdate = f"{v_data[0]}|{v_data[1]}|{v_data[2]}|{v_data[3]}|{v_data[4]}|{v_data[5]}|\n"
    for i in range(len(details)):
        if details[i].startswith(v_data[0]):
            details[i]=vupdate
    fout = open("data.txt", "r+")
    for j in range(len(details)):
        op = f"{details[j]}"
        fout.write(op)
    fout.close()
    get.close()
    iget.close()
    vsort()
    return "data Modified"

@eel.expose
def add_candidate(name,password,teamname):
    get = open("data.txt","r")
    details = get.readlines()
    count = 0
    candi=[]
    for i in range(len(details)):
        if details[i].startswith("ca"):
            data = details[i].split("|")
            if data[1] == name or data[3] == teamname:
                return "team already exsist"

    for i in range(len(details)):
        if details[i].startswith("ca"):
            candi.append(details[i])
    temp = candi[-1].split("|")
    id = temp[0]
    count = id[2:]
    b =  int(count)
    count = b
    if count < 9:
        count = count+1
        vid = "000"+str(count)
    elif count<99:
        count+=1
        vid = "00"+str(count)
    elif count<999:
        count+=1
        vid = "0"+str(count)
    else:
        vid = str(count)

    id = "ca"+vid
    votes = 0
    final = f"{id}|{name}|{password}|{teamname}|{votes}|\n"
    details.append(final)
    fout = open("data.txt", "w")
    for j in range(len(details)):
        op = f"{details[j]}"
        fout.write(op)
    fout.close()
    vsort()
    get.close()
    return "Team Added Succesfully"

@eel.expose
def remove_candidate(uid):
    get = open("data.txt","r")
    details = get.readlines()
    for i in range(len(details)):
        if details[i].startswith(uid):
            clear = ""
            data = details[i].split("|")
            details[i] = clear
            fout = open("data.txt", "r+")
            for j in range(len(details)):
                op = f"{details[j]}"
                fout.write(op)
            fout.close()
    vsort()
    get.close()
    return data[3]
@eel.expose
def display_candidate(vid):
    gets = open("data.txt", "r")
    temp = gets.readlines()
    clist = []
    iget = open("index.txt","r")
    index = iget.readlines()
    cid=[]
    fdata = []
    for i in range(len(index)):
        data = index[i].split("|")
        if data[1].startswith(vid):
            cid.append(data[0])

    for i in cid:
        i=int(i)
        clist.append(temp[i])
    for i in range(len(clist)):
        data = clist[i].split("|")
        fdata = data
    #print(fdata)
    gets.close()
    iget.close()
    return fdata

@eel.expose
def modify_candidate(uid,name,password,teamname):
    vid = []
    get = open("data.txt","r")
    iget = open("index.txt","r")
    details=get.readlines()
    index = iget.readlines()
    for i in range(len(index)):
        data = index[i].split("|")
        if data[1].startswith(uid):
            vid = data[0]
    vid = int(vid)
    v_data = details[vid].split("|")
    v_data[1] = name
    v_data[2] = password
    v_data[3] = teamname
    vupdate = f"{v_data[0]}|{v_data[1]}|{v_data[2]}|{v_data[3]}|{v_data[4]}|\n"
    for i in range(len(details)):
        if details[i].startswith(v_data[0]):
            details[i]=vupdate
    fout = open("data.txt", "r+")
    for j in range(len(details)):
        op = f"{details[j]}"
        fout.write(op)
    fout.close()
    get.close()
    iget.close()
    vsort()
    return "Modified Successfully"

@eel.expose
def allvoter():
    get = open("data.txt","r")
    get.seek(0)
    temp = get.readlines()
    voters = []
    for i in range(len(temp)):
        if temp[i].startswith("vt"):
            voters.append(temp[i])
    get.close()
    count = len(voters)
    return voters,count

@eel.expose
def allcandidate():
    get = open("data.txt","r")
    get.seek(0)
    temp = get.readlines()
    candidate = []
    for i in range(len(temp)):
        if temp[i].startswith("ca"):
            candidate.append(temp[i])
    get.close()
    count = len(candidate)
    return candidate,count

eel.start("index.html")
#if __name__ == '__main__':
    #allvoter()
    #vsort()
    #login("vt1001","1001")
    #cast_vote("ca1001","vt1008")
    #profile("vt1001")
    #profile("ca0002")
    #profile("st1002")
    #display_teams()
    # val = display_voter("vt0002")
    # print(val)
    #system_status()
    #val=winner()
    #print(val)
    #system_mod("st1001","5656")
    #val=reset("st0001","5656")
    #print(val)
    #add_voter("pheonix","20","2101","1010")
    #remove_voter("vt0004")
    #modify_voter("vt1009","breach","25","1009","3102")
    #add_candidate("thanos","1004","genysis")
    #remove_candidate("ca0003")
    #modify_candidate("ca1003","brimstone","1003","valo")


import torch
from transformers import BertTokenizer, BertModel, BertConfig, AdamW, BertForMaskedLM
from tokenizers import ByteLevelBPETokenizer
from tokenizers.implementations import ByteLevelBPETokenizer
from tokenizers.processors import BertProcessing
from sumerian_data import SumerianDataset
from typing import List, Tuple
import numpy as np
from tqdm import tqdm
import os

DEVICE = torch.device("cuda")

DATA_PATH = r"../data/sumerian_document_set.atf"
VOCAB_PATH = r"../data/sumerian_vocab_list"

def save_corpus(save_path: str, dataset: torch.utils.data.Dataset):
    try:
        os.mkdir(save_path)
    except FileExistsError:
        print("Directory path already exists.")

    docs = dataset.get_corpus()
    processed_doc = [" ".join(doc) for doc in docs]
    with open(os.path.join(save_path, r"processed_corpus.txt"), "w") as fp:
        fp.write("\n".join(processed_doc))

class SumarianBERTDataset(torch.utils.data.Dataset):
    def __init__(self, tokenizer: ByteLevelBPETokenizer, data_path: str, evaluate: bool = False):
        self.evaluate = evaluate
        self.tokenizer = tokenizer
        self.tokenizer._tokenizer.post_processor = BertProcessing(
            ("</s>", tokenizer.token_to_id("</s>")),
            ("<s>", tokenizer.token_to_id("<s>")),
        )
        self.tokenizer.enable_truncation(max_length=512)
        self.training_labels, self.test_labels, self.training_mask, self.test_mask = self.__get_split(data_path)

    def __get_split(self, data_path: str) -> Tuple[list, list]:

        with open(data_path, "r") as file:
            lines = file.read().split("\n")

        lines_tokens = [line for line in self.tokenizer.encode_batch(lines)]

        mask = [x.attention_mask for x in lines_tokens]
        labels = [line.ids for line in lines_tokens]

        indices = np.random.permutation(len(labels))
        split = int(len(labels) * 0.8)
        training_idxs, test_idxs = indices[:split], indices[split:]

        training_labels, test_labels = [], []
        training_mask, test_mask = [], []

        for train_idx in training_idxs:
            training_labels.append(labels[train_idx])
            training_mask.append(mask[train_idx])

        for test_idx in test_idxs:
            test_labels.append(labels[test_idx])
            test_mask.append(mask[test_idx])

        return training_labels, test_labels, training_mask, test_mask

    def __len__(self):
        if self.evaluate:
            return len(self.test_labels)
        else:
            return len(self.training_labels)

    def __getitem__(self, i):
        if self.evaluate:
            return (
                torch.tensor(self.test_labels[i]).type(torch.float),
                torch.tensor(self.test_mask[i]).type(torch.float)
                )
        else:
            return (
                torch.tensor(self.training_labels[i]).type(torch.float),
                torch.tensor(self.training_mask[i]).type(torch.float)
                )

def collate_fn_padd(batch):
    '''
    Padds batch of variable length

    note: it converts things ToTensor manually here since the ToTensor transform
    assume it takes in images rather than arbitrary tensors.
    '''
    labels = [item[0] for item in batch]
    att_mask = [item[1] for item in batch]

    ## get sequence lengths
    lengths = torch.tensor([ t.shape[0] for t in labels ]).to(DEVICE)

    ## padd
    labels = [ torch.Tensor(t).to(DEVICE) for t in labels ]
    labels = torch.nn.utils.rnn.pad_sequence(labels)

    att_mask = [ torch.Tensor(t).to(DEVICE) for t in att_mask ]
    att_mask = torch.nn.utils.rnn.pad_sequence(att_mask)

    ## compute mask
    mask = (labels != 0).to(DEVICE)

    input_ids = labels.detach().clone()
    rand = torch.rand(input_ids.shape)

    mask_arr = (rand < .15) * (input_ids != 0) * (input_ids != 1) * (input_ids != 2)
    for i in range(input_ids.shape[0]):
        selection = torch.flatten(mask_arr[i].nonzero()).tolist()
        input_ids[i, selection] = 3

    return labels.T, att_mask.T, input_ids.T, lengths.T, mask.T

# model = BertModel.from_pretrained("bert-base-multilingual-cased")
# text = "Replace me by any text you'd like."
# encoded_input = tokenizer(text, return_tensors='pt')
# output = model(**encoded_input)

def main():
    SAVE_CORPUS=False
    MAKE_TOKENIZER=False

    dataset = SumerianDataset(DATA_PATH, VOCAB_PATH)

    save_path=r"../data/processed_data/"

    if SAVE_CORPUS:
        save_corpus(save_path, dataset)

    if MAKE_TOKENIZER:
        vocab_size = dataset.get_vocab_size()

        tokenizer = ByteLevelBPETokenizer()

        tokenizer.train(
            files=os.path.join(save_path, r"processed_corpus.txt"),
            vocab_size=vocab_size,
            min_frequency=2,
            special_tokens=[
                "<s>",
                "<pad>",
                "</s>",
                "<unk>",
                "<mask>",
            ])

        try:
            os.mkdir(r"../tokenizer/")
        except FileExistsError:
            print("Tokenizer directory path already exists.")

        tokenizer.save_model(r"../tokenizer/")

    tokenizer = ByteLevelBPETokenizer(
        "../tokenizer/vocab.json",
        "../tokenizer/merges.txt",
    )

    BERT_dataset = SumarianBERTDataset(
        tokenizer,
        os.path.join(save_path, r"processed_corpus.txt"),
        evaluate=False)

    BERT_train_loader = torch.utils.data.DataLoader(
        BERT_dataset,
        batch_size=16,
        shuffle=True,
        collate_fn=collate_fn_padd)

    config = BertConfig(
        vocab_size=dataset.get_vocab_size(),
        max_position_embeddings=512,
        hidden_size=768,
        num_attention_heads=12,
        num_hidden_layers=12,
        type_vocab_size=2
    )

    # config = BertConfig(
    #     vocab_size=dataset.get_vocab_size(),
    #     max_position_embeddings=512,
    #     hidden_size=768,
    #     num_attention_heads=4,
    #     num_hidden_layers=4,
    #     type_vocab_size=1
    # )

    model = BertForMaskedLM(config)

    multling_model = BertModel.from_pretrained("bert-base-multilingual-cased")
    multling_params = multling_model.state_dict()

    # Remove params that are a mismatch with current model.
    del multling_params["embeddings.position_ids"]
    del multling_params['embeddings.word_embeddings.weight']
    del multling_params['embeddings.position_embeddings.weight']
    del multling_params['embeddings.token_type_embeddings.weight']
    del multling_params['embeddings.LayerNorm.weight']
    del multling_params['embeddings.LayerNorm.bias']

    model.load_state_dict(multling_params, strict=False)

    model.to(DEVICE)

    print("Number of parameters: ", end="")
    print(model.num_parameters())

    model.train()
    optim = AdamW(model.parameters(), lr=1e-4)

    epochs = 2

    for epoch in range(epochs):
        # setup loop with TQDM and dataloader
        loop = tqdm(BERT_train_loader, leave=True)
        for batch in loop:
            optim.zero_grad()

            labels, attention_mask, input_ids, lengths, mask = batch

            input_ids.to(DEVICE)
            attention_mask.to(DEVICE)
            labels.to(DEVICE)

            outputs = model(input_ids.long(), attention_mask=attention_mask, labels=labels.long().contiguous())

            loss = outputs.loss
            loss.backward()
            optim.step()

            loop.set_description(f'Epoch {epoch}')
            loop.set_postfix(loss=loss.item())

if __name__=="__main__":
    main()


#/usr/bin/env python
from pwn import *
from Crypto.Util.number import bytes_to_long, long_to_bytes
from Crypto.Cipher import AES
import hashlib
import os
import base64
from gmpy2 import is_prime

class Rng:
  def __init__(self, seed):
    self.seed = seed
    self.generated = b""
    self.num = 0

  def more_bytes(self):
    self.generated += hashlib.sha256(self.seed).digest()
    # increase seed by 1 and ensure the seed is 32 bytes long (prepend with NULL bytes)
    self.seed = long_to_bytes(bytes_to_long(self.seed) + 1, 32)
    self.num += 256

  def getbits(self, num=64):
    while (self.num < num):
      self.more_bytes()
    x = bytes_to_long(self.generated)
    self.num -= num
    self.generated = b""

    # this is not called for our primes
    if self.num > 0:
      self.generated = long_to_bytes(x >> num, self.num // 8)

    # ANDs with 0xffff...ffff to ensure only a NUM length number is returned
    return x & ((1 << num) - 1)

class DiffieHellman:
  def gen_prime(self):
    prime = self.rng.getbits(512)
    iter = 0
    while not is_prime(prime):
      iter += 1
      prime = self.rng.getbits(512)
    print("Generated after", iter, "iterations")
    return prime

  def __init__(self, seed, prime=None):
    self.rng = Rng(seed)
    if prime is None:
      prime = self.gen_prime()

    self.prime = prime
    self.my_secret = self.rng.getbits()
    self.my_number = pow(5, self.my_secret, prime)
    self.shared = 1337

  def set_other(self, x):
    self.shared ^= pow(x, self.my_secret, self.prime)

def pad32(x):
  return (b"\x00"*32+x)[-32:]

def xor32(a, b):
  return bytes(x^y for x, y in zip(pad32(a), pad32(b)))

def bit_flip(x):
  print("bit-flip str:")
  inputstr = b'BA=='
  #inputstr = input().strip()
  flip_str = base64.b64decode(inputstr)
  return xor32(flip_str, x)

def get_values(conn, value):
    # receive the bit-flip str:
    conn.recvline()

    # send the value
    conn.send(value + b'\n')

    # recv num iterations
    num_iter = str(conn.recvline())
    bob_num = conn.recvline()
    iv_num = conn.recvline()
    flag_num = conn.recvline()

    results = [
        int(num_iter.split(" ")[2:3][0]),
        int(bob_num.decode('ascii').split(" ")[2:3][0]),
        base64.b64decode(iv_num.decode('ascii')),
        base64.b64decode(flag_num.decode('ascii'))
    ]
    return results

def get_num_iter(conn, value):
    return get_values(conn, value)[0]

def get_seed(conn):
    # loop over each bit of 64-bit number
    sol = 0
    maxnum = 128 # 128
    for i in range(1, maxnum):
        # get two values one with and without the ith bit set
        n = sol ^ ((2 ** i) - 2)
        m = sol | (1 << i)

        # base64 encode values
        basen = base64.b64encode(bytes(long_to_bytes(n)))
        basem = base64.b64encode(bytes(long_to_bytes(m)))
        iter_n = get_num_iter(conn, basen)
        iter_m = get_num_iter(conn, basem)
        print("N: %s [%d], M: %s [%d]" % (basen, iter_n, basem, iter_m))

        if(iter_n != iter_m + 1):
            sol = sol | (1 << i)
        print("SOL:" + " "*(135-maxnum) + bin(sol)[2:])

    return long_to_bytes(sol, 16)

def main(conn):
    # compute alice_seed
    alice_seed = get_seed(conn)
    print(alice_seed)

    # perform one iteration with arbitrary input to get a sample of values
    results = get_values(conn, b'BA==')
    bobnum = results[1]
    iv = results[2]
    ciphertext = results[3]

    # compute the encryption/decryption key
    alice = DiffieHellman(bit_flip(alice_seed))
    alice.set_other(bobnum)

    # decrypt the ciphertext
    cipher = AES.new(long_to_bytes(alice.shared, 16)[:16], AES.MODE_CBC, IV=iv)
    plaintext = cipher.decrypt(ciphertext)
    print(plaintext)

if __name__ == '__main__':
    HOST = "127.0.0.1"
    PORT = 1337
    conn = remote(HOST, PORT)
    main(conn)