import cv2
import math
import mediapipe as mp
from mediapipe.framework.formats.detection_pb2 import Detection
from dtos import FaceRegions
# mp_face_detection = mp.solutions.face_detection
# mp_drawing = mp.solutions.drawing_utils

class face_detection():
    def __init__(self, image):
        self.image = image
        self.image_width = image.shape[1]
        self.image_height = image.shape[0]
        self.RELATIVE_BOUNDING_BOX = 2
        self.mp_face_detection = mp.solutions.face_detection
        self.regions = []

    #detect faces
    def detect_faces(self):
        """
        Function to detect faces
        -------
        Returns:
            NONE
        """
        # model_selction = 0 -> 속도 빠른 모델, 1 -> 정확도 높은 속도 느린 모델
        # 모델 불러와서 face detect
        with self.mp_face_detection.FaceDetection(
            model_selection=0, min_detection_confidence=0.6) as face_detection:
            # To improve performance, optionally mark the image as not writeable to
            # pass by reference.
            self.image.flags.writeable = False
            self.image = cv2.cvtColor(self.image, cv2.COLOR_BGR2RGB)
            self.results = face_detection.process(self.image)

            self.image.flags.writeable = True
            self.image = cv2.cvtColor(self.image, cv2.COLOR_RGB2BGR)

            self.detections = self.results.detections

    # 다른 노드에 디텍션 정보 종합하기 위함
    # localization_to_region
    # dtos.FaceRegions
    def localization_to_region(self):
        """
        Function to detect objects
        -------
        Returns
            face_full : list
                face regions detected
            core_landmark : list, optional
                key landmarks of face (eyes, nose, mouth)
            all_landmark : list, optional
                all landmarks of face (including ears)
        """
        # 얼굴이 없는 경우도 고려해야 함.
        self.face_full = []
        self.core_landmark = []
        self.all_landmark = []

        if self.detections:
            for detection in self.detections:

                location = detection.location_data
                box = detection.location_data.relative_bounding_box

                # error 발생시켜야 함
                if(location.format != self.RELATIVE_BOUNDING_BOX):
                    print(location.format)
                    print("Face detection input is lacking required relative_bounding_box()")

                # error 발생시켜야 함
                # if(detection.location_data.relative_keypoints.size != 6):
                #     print("Face detection input expected 6 keypoints, has", location.relative_keypoints.size)

                # detection된 얼굴이 여러개인 경우 고려하여
                # 한 클래스를 한 명의 디텍션 정보로 구성하고 이를 리스트로 묶음.

                # face_full
                x = max(float(0), box.xmin)
                y = max(float(0), box.ymin)
                width = min(box.width - abs(x - box.xmin), 1 - x)
                height = min(box.height - abs(y - box.ymin), 1 - y)
                SignalType = "FACE_FULL"
                visual_score = detection.score[0]

                region = FaceRegions(x, y, width, height, SignalType, visual_score)
                self.face_full.append(region)

                # landmark 총 6개 -> 각 랜드마크 당 클래스 하나
                # core는 앞에 4개만
                core_landmark_region = []
                all_landmark_region = []

                for i in range(4):
                    keypoint = location.relative_keypoints[i]
                    x = keypoint.x
                    y = keypoint.y
                    w = self.normalize_x(1)
                    h = self.normalize_y(1)
                    SignalType = "FACE_LANDMARK"

                    region = FaceRegions(x, y, w, h, SignalType, visual_score)
                    region = self.extend_salient_region_with_point(keypoint.x, keypoint.y, region)

                    core_landmark_region.append(region)
                    all_landmark_region.append(region)

                for i in range(4, 6):
                    keypoint = location.relative_keypoints[i]
                    x = keypoint.x
                    y = keypoint.y
                    w = self.normalize_x(1)
                    h = self.normalize_y(1)
                    SignalType = "FACE_LANDMARK"

                    region = FaceRegions(x, y, w, h, SignalType, visual_score)

                    region = self.extend_salient_region_with_point(keypoint.x, keypoint.y, region)

                    all_landmark_region.append(region)

                self.core_landmark.append(core_landmark_region)
                self.all_landmark.append(all_landmark_region)

        return self.face_full, self.core_landmark, self.all_landmark

    def extend_salient_region_with_point(self, x, y, region):
        """
        Function to extend regions in consideration of error
        -------
        Parameters
            x : float
                x of face keypoint
            y : float
                y of face keypoint
            region : dataclass
                class containing face regions
        -------
        Returns
            region : dataclass
                updated regions

        """
        if(region.w is None):
            region.set_w(self.normalize_x(1))
        elif(x < region.x):
            region.set_w(region.w + region.x - x)
        elif(x > region.x + region.w):
            region.set_w(x - region.x)

        if(region.h is None):
            region.set_h(self.normalize_y(1))
        elif(y < region.y):
            region.set_h(region.h + region.y - y)
        elif(y > region.y + region.h):
            region.set_h(y - region.y)

        if(region.x is None):
            region.set_x(x)
        else:
            region.set_x(min(x, region.x))

        if(region.y is None):
            region.set_y(y)
        else:
            region.set_y(min(y, region.y))

        return region

    def normalize_x(self, pixel):
        return pixel / float(self.image_width)

    def normalize_y(self, pixel):
        return pixel / float(self.image_height)


import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
import calibration
from scipy import optimize

import scipy

imgL = cv.imread('imgL.jpeg')  # queryimage # left image
imgM = cv.imread('imgM.jpeg')  # trainimage # middle image
imgR = cv.imread('imgR.jpeg')  # trainimage # right image
imgMR = cv.imread('imgM.jpeg') # Copy of middle image to later reconstruct the object with using 3 images.
imgML = cv.imread('imgM.jpeg') # Copy of middle image to later reconstruct the object with using 3 images.

"""Explanation: L = Left, M = Middle, R = Right
    ML = Middle-Left, MR = Middle-Right"""

sift = cv.SIFT_create(nfeatures=0, nOctaveLayers=3, contrastThreshold=0.01, edgeThreshold=20, sigma=0.5)
# find the keypoints and descriptors with SIFT
[kpL, desL] = sift.detectAndCompute(imgL, None)
[kpM, desM] = sift.detectAndCompute(imgM, None)
[kpR, desR] = sift.detectAndCompute(imgR, None)
# Show keypoints:
img_kpM = imgM.copy()
img_kpL = imgL.copy()
img_kpR = imgR.copy()
img_kpM = cv.drawKeypoints(imgM, kpM,img_kpM) # Draw keypoints found by SIFT algorithm in the middle image.
img_kpL = cv.drawKeypoints(imgL,kpL, img_kpL) # Draw keypoints found by SIFT algorithm in the middle image.
img_kpR = cv.drawKeypoints(imgR, kpR,img_kpR) # Draw keypoints found by SIFT algorithm in the middle image.
plt.figure("Middle Image Keypoints")
plt.imshow(img_kpM)
plt.figure("Left Image Keypoints")
plt.imshow(img_kpL)
plt.figure("Right Image Keypoints")
plt.imshow(img_kpR)

# FLANN parameters
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) # was trees=5 # was trees 10
search_params = dict(checks=50)
flann = cv.FlannBasedMatcher(index_params, search_params)
matches_ML = flann.knnMatch(desL, desM, k=2)  # Find matches between images Left and Middle
matches_MR = flann.knnMatch(desM, desR, k=2)  # Find matches between images Middle and Right

ptsL = []
ptsML = []
ptsMR = []
ptsR = []
# ratio test as per Lowe's paper - for middle and left images
for i, (m, n) in enumerate(matches_ML):
    if m.distance < 0.8 * n.distance: # was 0.7 # was 0.99
      #if m.distance < 400:
        ptsML.append(kpM[m.trainIdx].pt)
        ptsL.append(kpL[m.queryIdx].pt)

# ratio test as per Lowe's paper - for middle and right images

for i, (m, n) in enumerate(matches_MR):
    if m.distance < 0.88 * n.distance: # was 0.7 # was 0.99
      #if m.distance < 400:
        ptsMR.append(kpM[m.queryIdx].pt)
        ptsR.append(kpR[m.trainIdx].pt)

ptsL = np.double(ptsL)
ptsML = np.double(ptsML)
ptsMR = np.double(ptsMR)
ptsR = np.double(ptsR)

"""Now we have the list of best matches from both the images. Let's find the Fundamental Matrix."""

F_ML, mask_ML = cv.findFundamentalMat(ptsML, ptsL, cv.FM_LMEDS,maxIters=50000,confidence = 0.99,ransacReprojThreshold = 3) # Find the Fundamental matrix that matches the middle and left images.
F_MR, mask_MR = cv.findFundamentalMat(ptsR, ptsMR, cv.FM_LMEDS,maxIters=50000,confidence = 0.99,ransacReprojThreshold = 3) # Find the Fundamental matrix that matches the right and middle images.

# We select only inlier points
ptsL = ptsL[mask_ML.ravel() == 1]
ptsML = ptsML[mask_ML.ravel() == 1]
ptsMR = ptsMR[mask_MR.ravel() == 1]
ptsR = ptsR[mask_MR.ravel() == 1]

"""Next we find the epilines. Epilines corresponding to the points in first image is drawn on second image.
So mentioning of correct images are important here.
We get an array of lines. So we define a new function to draw these lines on the images."""

def drawlines(img1, img2, lines, pts1, pts2):
    ''' img1 - image on which we draw the epilines for the points in img2
        lines - corresponding epilines '''
    pts1 = np.int32(pts1)
    pts2 = np.int32(pts2)
    obj = img1.shape
    r, c = obj[0], obj[1]
    # r,c = img1.shape
    # img1 = cv.cvtColor(img1,cv.COLOR_GRAY2BGR)
    # img2 = cv.cvtColor(img2,cv.COLOR_GRAY2BGR)
    for r, pt1, pt2 in zip(lines, pts1, pts2):
        color = tuple(np.random.randint(0, 255, 3).tolist())
        x0, y0 = map(int, [0, -r[2] / r[1]])
        x1, y1 = map(int, [c, -(r[2] + r[0] * c) / r[1]])
        img1 = cv.line(img1, (x0, y0), (x1, y1), color, 1)
        img1 = cv.circle(img1, tuple(pt1), 5, color, -1)
        img2 = cv.circle(img2, tuple(pt2), 5, color, -1)
    return img1, img2

# Find epilines corresponding to points in right image (second image) and
# drawing its lines on left image
lines1 = cv.computeCorrespondEpilines(ptsMR.reshape(-1, 1, 2), 2, F_MR)
lines1 = lines1.reshape(-1, 3)
img5, img6 = drawlines(imgR, imgMR, lines1, ptsR, ptsMR)
# Find epilines corresponding to points in left image (right image) and
# drawing its lines on right image
lines2 = cv.computeCorrespondEpilines(ptsR.reshape(-1, 1, 2), 1, F_MR)
lines2 = lines2.reshape(-1, 3)
img3, img4 = drawlines(imgMR, imgR, lines2, ptsMR, ptsR)
plt.figure("Epilines and matches between images")
plt.subplot(221), plt.imshow(img5)
plt.subplot(222), plt.imshow(img3)

lines3 = cv.computeCorrespondEpilines(ptsL.reshape(-1, 1, 2), 2, F_ML)
lines3 = lines3.reshape(-1, 3)
img7, img8 = drawlines(imgL, imgML, lines3, ptsL, ptsML)
# Find epilines corresponding to points in left image (first image) and
# drawing its lines on right image
lines4 = cv.computeCorrespondEpilines(ptsML.reshape(-1, 1, 2), 1, F_ML)
lines4 = lines4.reshape(-1, 3)
img9, img10 = drawlines(imgML, imgL, lines4, ptsML, ptsL)
plt.subplot(223), plt.imshow(img7)
plt.subplot(224), plt.imshow(img9)
#plt.show()

# Calibrating the camera:
C = calibration.calibrate()
ret,mtx,dist, rvecs,tvecs = C.get_calibration()
K=mtx

# Get P of left image:
E_ML = K.T@F_ML@K
R1_ML,R2_ML,t_ML= cv.decomposeEssentialMat(E_ML)
Rt_ML = np.column_stack((R1_ML,t_ML)) # R2 better 3D reproj
P_ML=np.matmul(K,Rt_ML)

# Get P of right image:
E_MR = K.T@F_ML@K
R1_MR,R2_MR,t_MR = cv.decomposeEssentialMat(E_MR)
Rt_MR = np.column_stack((R1_MR,t_MR))# R2 better 3D reproj
P_MR=np.matmul(K,Rt_MR)

# Get P of middle image:
Rt_M = np.array([[1,0,0,0],
              [0,1,0,0],
              [0,0,1,0]])
P_M = np.matmul(K,Rt_M)

#------------------------------------triangulation-------------------------------------------
#converting pts to floats
kpL_3D = np.ones((3, ptsL.shape[0]))
kpML_3D = np.ones((3, ptsML.shape[0]))
kpMR_3D = np.ones((3, ptsMR.shape[0]))
kpR_3D = np.ones((3, ptsR.shape[0]))
kpL_3D[0], kpL_3D[1] = ptsL[:, 0].copy(), ptsL[:, 1].copy()
kpML_3D[0], kpML_3D[1] = ptsML[:, 0].copy(), ptsML[:, 1].copy()
kpMR_3D[0], kpMR_3D[1] = ptsMR[:, 0].copy(), ptsMR[:, 1].copy()
kpR_3D[0], kpR_3D[1] = ptsR[:, 0].copy(), ptsR[:, 1].copy()

Points4D_ML = cv.triangulatePoints(P_M, P_ML, kpML_3D[:2], kpL_3D[:2])
Points4D_MR = cv.triangulatePoints(P_MR,P_M , kpMR_3D[:2], kpR_3D[:2])

# Normalize the points.
Points4D_ML /= Points4D_ML[3]
Points4D_MR /= Points4D_MR[3]

points_3d_ML = np.transpose(Points4D_ML[:3, :])
fig = plt.figure("3D Image Reconstruction Result")
ax = fig.add_subplot(1, 1, 1, projection='3d')
ax.scatter(points_3d_ML[:,0], points_3d_ML[:,1], points_3d_ML[:,2],color='blue')

points_3d_MR = np.transpose(Points4D_MR[:3, :])
scale_factor = 1
points_3d_MR *= scale_factor
ax.scatter(points_3d_MR[:,0], points_3d_MR[:,1], points_3d_MR[:,2],color='blue')
plt.show()

#---------------------------optimization-------------------------------------------

Points3D_ML_reproj = P_M[:3] @ Points4D_ML
Points3D_L_reproj = P_ML[:3] @ Points4D_ML

Points3D_MR_reproj = P_M[:3] @ Points4D_MR
Points3D_R_reproj = P_MR[:3] @ Points4D_MR

Points3D_ML_reproj /= Points3D_ML_reproj[2]
Points3D_L_reproj /= Points3D_L_reproj[2]

Points3D_MR_reproj /= Points3D_MR_reproj[2]
Points3D_R_reproj /= Points3D_R_reproj[2]

# Calculate reprojection error:
#reproj: [x-x_repoj,y-y_repoj] [pts1[0][0]-Points3D_L_back[0][0],pts1[0][1]-Points3D_L_back[0][1]]
# reproj_ML,J = cv.projectPoints(kpL_3D,R1_ML,t_ML,mtx,dist) #returns image points on image plane + jacobian
# #scipy minimize
#
# err_reproj_L=[]
# err_reproj_ML=[]
# err_reproj_MR=[]
# err_reproj_R=[]
#
# for i in range(kpL_3D.shape[1]):
#     err_reproj_L.append((abs(kpL_3D[0][i]-Points3D_L_reproj[0][i]))**2 + (abs(kpL_3D[1][i]-Points3D_L_reproj[1][i]))**2)
#     err_reproj_ML.append((abs(kpML_3D[0][i] - Points3D_ML_reproj[0][i])) ** 2 + (abs(kpML_3D[1][i] - Points3D_ML_reproj[1][i])) ** 2)
#     # kp[0] = x coordinate, kp[1] = y coordinate
#
#
# for i in range(kpR_3D.shape[1]):
#     err_reproj_R.append((abs(kpR_3D[0][i]-Points3D_R_reproj[0][i]))**2 + (abs(kpR_3D[1][i]-Points3D_R_reproj[1][i]))**2)
#     err_reproj_MR.append((abs(kpMR_3D[0][i] - Points3D_ML_reproj[0][i])) ** 2 + (abs(kpMR_3D[1][i] - Points3D_R_reproj[1][i])) ** 2)
#
# # Calculate Middle-Left loss function:
# err_L = sum(err_reproj_L)/err_reproj_L.__len__()
# err_ML = sum(err_reproj_ML)/err_reproj_ML.__len__()
# loss_ML = err_L + err_ML
#
# # Calculate Middle-Right loss function:
# err_R = sum(err_reproj_R)/err_reproj_R.__len__()
# err_MR = sum(err_reproj_MR)/err_reproj_MR.__len__()
# loss_MR = err_R + err_MR
#
#
# result= optimize.minimize(optimize.rosen,err_repoj_L,method='BFGS',tol=1e-5)
#print(result.x)

# Perform PCA analysis
    #mean = np.empty((0))
    #mean1, eigenvectors1, eigenvalues1 = cv.PCACompute2(data_pts1, mean1)
   # mean2, eigenvectors2, eigenvalues2 = cv.PCACompute2(data_pts2, mean2)


def cipher(text, shift, encrypt=True):
    """Cipher function to encrypt and decrypt a string .

    Parameters
    ----------
    text: str
        A string variable that is a text.
    shift: int
        The number of postions we would like to shift along the alphabet string.
    encrypt: bool
        Whether to encrypt or decrypt the string text.

    Returns
    -------
    str
        The new text string after being enctypted or decrypted.

    Examples
    --------
    >>> cipher('data',1)
    'ebub'

    """

    alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    new_text = ''
    for c in text:
        index = alphabet.find(c)
        if index == -1:
            new_text += c
        else:
            new_index = index + shift if encrypt == True else index - shift
            new_index %= len(alphabet)
            new_text += alphabet[new_index:new_index+1]
    return new_text


hour = 0
minut = 0
seconds = 0
time = int(input('Введите время в секундах '))
if time > 3600:
	hour = int(time / 3600)
minut = int(((time - (hour * 3600)) / 60))
seconds = time - ((hour * 3600) + (minut * 60))
#if hour < 9:
#	hour = '0' + str(hour)
#if minut < 9:
#	minut = '0' + str(minut)
#if seconds < 9:
#	seconds = '0' + str(seconds)
print (f'{hour:02}:{minut:02}:{seconds:02}')


#declaring a variable of type int and assigning some data to it
types_of_people = 10

#Declaring four vars of type string and setting some data
x = f"There are {types_of_people} types of people."

binary = "Binary"
do_not = "don't"
y = f"those who know {binary} and those who {do_not}."

#Printing out the x and y
print(x)
print(y)

#re Printing x and y in addition to some new strings in the beginning of each var line
print(f"I said : {x}")
print(f"I said also : '{y}'")

#Creating new var of type bool and assigning it with "False" date
helarios = False

#New var of type string and initializing it with some data
joke_evaluation = "isn't that joke so funny !? {}"

#printing the joke_evaluation var and utilizing .format wierd staff for yhe first time
print(joke_evaluation.format(helarios))

#Two vars of type string with some data assigned to them
e = "This is the left side of ..."
w = "a string with a right side."

#printing out the vars by adding the sting e to the string w
print(e + w)


#Given an array of integers greater than zero, find if it is possible to split it in two subarrays (without reordering the elements), such that the sum of the two subarrays is the same. Print the two subarrays.

 #Example Usecases
 #Input : Arr[] = [ 1 , 2 , 3 , 4 , 5 , 5  ]
 #Output :  [ 1 2 3 4 ]
 #         [ 5 , 5 ]

 #Input : Arr[] = [ 4, 1, 2, 3 ]
 #Output : [4 1]
 #         [2 3]

# Input : Arr[] = [ 4, 3, 2, 1]
# Output : Not Possible
# [ 1 , 2 , 3 , 4 , 5 , 5, 6 ]

def getSumArray(arr):
  totalLength = len(arr)
  midLength =  mid = int(len(arr)/2)
#   sumLeft =
  for i in range(midLength):
    if(sum(arr[0:mid]) > sum(arr[mid: totalLength])):
      mid -=1
    elif (sum(arr[mid: totalLength]) > sum(arr[0:mid])):
      mid+=1
    else:
      return arr[0:mid], arr[mid:totalLength]
  return 'Not possible'

print(getSumArray([ 2, 3, 4, 1 ]))
print(getSumArray([ 1 , 2 , 3 , 4 , 5 , 5  ]))
print(getSumArray([ 1 , 2 , 3 , 4 , 5 , 5, 6 ]))


# -*- coding: utf_8 -*-
"""Module holding the functions for code analysis."""

import binascii
import hashlib
import logging
import os
import re

from androguard.core.bytecodes.apk import APK
from androguard.util import get_certificate_name_string

from asn1crypto import x509

from oscrypto import asymmetric

from django.utils.html import escape

logger = logging.getLogger(__name__)

def get_hardcoded_cert_keystore(files):
    """Returns the hardcoded certificate keystore."""
    try:
        logger.info('Getting Hardcoded Certificates/Keystores')
        findings = []
        certz = []
        key_store = []
        for file_name in files:
            if '.' not in file_name:
                continue
            ext = file_name.split('.')[-1]
            if re.search('cer|pem|cert|crt|pub|key|pfx|p12|der', ext):
                certz.append(escape(file_name))
            if re.search('jks|bks', ext):
                key_store.append(escape(file_name))
        if certz:
            desc = 'Certificate/Key files hardcoded inside the app.'
            findings.append({'finding': desc, 'files': certz})
        if key_store:
            desc = 'Hardcoded Keystore found.'
            findings.append({'finding': desc, 'files': key_store})
        return findings
    except Exception:
        logger.exception('Getting Hardcoded Certificates/Keystores')

def cert_info(app_dir, app_file):
    """Return certificate information."""
    try:
        logger.info('Reading Code Signing Certificate')
        manifestfile = None
        manidat = ''
        cert_info = ''
        certlist = []
        cert_path = os.path.join(app_dir, 'META-INF/')

        apk_file = os.path.join(app_dir, app_file)
        hashfunctions = {
            'md5': hashlib.md5,
            'sha1': hashlib.sha1,
            'sha256': hashlib.sha256,
            'sha512': hashlib.sha512,
        }
        files = [f for f in os.listdir(
            cert_path) if os.path.isfile(os.path.join(cert_path, f))]
        a = APK(apk_file)
        if a.is_signed():
            certlist.append('APK is signed')
        else:
            certlist.append('Missing certificate')
        certlist.append('v1 signature: {}'.format(a.is_signed_v1()))
        certlist.append('v2 signature: {}'.format(a.is_signed_v2()))
        certlist.append('v3 signature: {}'.format(a.is_signed_v3()))

        certs = set(a.get_certificates_der_v3() + a.get_certificates_der_v2()
                    + [a.get_certificate_der(x)
                       for x in a.get_signature_names()])
        pkeys = set(a.get_public_keys_der_v3() + a.get_public_keys_der_v2())

        if len(certs) > 0:
            certlist.append('Found {} unique certificates'.format(len(certs)))

        for cert in certs:
            x509_cert = x509.Certificate.load(cert)
            certlist.append('Subject: {}'.format(
                get_certificate_name_string(x509_cert.subject, short=True)))
            certlist.append('Signature Algorithm: {}'.format(
                x509_cert.signature_algo))
            certlist.append('Valid From: {}'.format(
                x509_cert['tbs_certificate']['validity']['not_before'].native))
            certlist.append('Valid To: {}'.format(
                x509_cert['tbs_certificate']['validity']['not_after'].native))
            certlist.append('Issuer: {}'.format(
                get_certificate_name_string(x509_cert.issuer, short=True)))
            certlist.append('Serial Number: {}'.format(
                hex(x509_cert.serial_number)))
            certlist.append('Hash Algorithm: {}'.format(x509_cert.hash_algo))
            for k, v in hashfunctions.items():
                certlist.append('{}: {}'.format(k, v(cert).hexdigest()))

        for public_key in pkeys:
            x509_public_key = asymmetric.load_public_key(public_key)
            certlist.append('PublicKey Algorithm: {}'.format(
                x509_public_key.algorithm))
            certlist.append('Bit Size: {}'.format(x509_public_key.bit_size))
            certlist.append('Fingerprint: {}'.format(
                binascii.hexlify(x509_public_key.fingerprint).decode('utf-8')))
        cert_info = '\n'.join(certlist)
        if 'MANIFEST.MF' in files:
            manifestfile = os.path.join(cert_path, 'MANIFEST.MF')
        if manifestfile:
            with open(manifestfile, 'r', encoding='utf-8') as manifile:
                manidat = manifile.read()
        sha256_digest = bool(re.findall(r'SHA-256-Digest', manidat))
        findings = []
        if a.is_signed():
            findings.append((
                'good',
                'Application is signed with a code '
                'signing certificate'))
        else:
            findings.append((
                'bad',
                'Code signing certificate not found'))
        if a.is_signed_v1():
            status = 'bad'
            if a.is_signed_v2() or a.is_signed_v3():
                status = 'warning'
            findings.append((
                status,
                'Application is signed with v1 signature scheme, '
                'making it vulnerable to Janus vulnerability on '
                'Android <7.0'))
        if re.findall(r'CN=Android Debug', cert_info):
            findings.append((
                'bad',
                'Application signed with a debug certificate. '
                'Production application must not be shipped '
                'with a debug certificate.'))
        if re.findall(r'Hash Algorithm: sha1', cert_info):
            status = 'bad'
            desc = (
                'Application is signed with SHA1withRSA. '
                'SHA1 hash algorithm is known to have '
                'collision issues.')
            if sha256_digest:
                status = 'warning'
                desc += (
                    ' The manifest file indicates SHA256withRSA'
                    ' is in use.')
            findings.append((status, desc))
        cert_dic = {
            'certificate_info': cert_info,
            'certificate_findings': findings,
        }
        return cert_dic
    except Exception:
        logger.exception('Reading Code Signing Certificate')
        return {}


import random
import string

def create_school (class_number):
    new_school = []
    used_class_name = set()
    while len(new_school) < class_number:
        class_name = str(random.randint(1, 11)) + random.choice(string.ascii_letters).upper()
        class_scores = []
        class_cnt_people = random.randint(10, 30)
        for _ in range(class_cnt_people):
            class_scores.append(random.randint(2, 5))
        new_class = {}
        new_class['school_class'] = class_name
        new_class['scores'] = class_scores
        if class_name not in used_class_name:
            new_school.append(new_class)
            used_class_name.add(class_name)
    return new_school

def calc_and_print_avg_score_for_class_and_school(school):
    school_scores_sum = 0
    school_people_cnt = 0
    for cur_class in school:
        print(cur_class['school_class'], end=' avg:')
        print(sum(cur_class['scores']) / len(cur_class['scores']))
        school_scores_sum += sum(cur_class['scores'])
        school_people_cnt += len(cur_class['scores'])
    print (f'avg school score: {school_scores_sum / school_people_cnt}')

def main():
    class_number = 20
    school = list(create_school(class_number))
    calc_and_print_avg_score_for_class_and_school(school)

if __name__ == "__main__":
    main()


# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def rotateRight(self, head: ListNode, k: int) -> ListNode:
        # Special case: List is empty
        if head == None:
            return None
        # Special case: List has only one entry
        elif head.next == None:
            return head

        # Finding last node and counting size
        size = 1
        p,q = head, head

        while q.next != None:
            size += 1
            q = q.next

        # Closing loop
        q.next = head

        # Special case: k is greater than size
        k %= size

        # Sever chain at right location
        for i in range(size - k):
            q = q.next

        p = q.next
        q.next = None

        return p


# import lines
#################################
import sys
import math
# import copy
# import ast
# import re
# import time
# import json
# import pprint
from collections import *
# from itertools import *
# from heapq import *
# from datetime import datetime
# from bisect import *
#################################

def mul_mat(n, m, k, mat1, mat2):
    new_mat = [[0 for _ in range(k)] for _ in range(n)]
    for i in range(n):
        for j in range(k):
            for l in range(m):
                new_mat[i][j] += mat1[i][l] * mat2[l][j]
    return new_mat

if __name__ == '__main__':
    input = sys.stdin.readline
    # sys.setrecursionlimit(10**6)

    # input
    n, m = map(int, input().split())
    mat1 = [list(map(int, input().split())) for _ in range(n)]
    m, k = map(int, input().split())
    mat2 = [list(map(int, input().split())) for _ in range(m)]

    # output
    new_mat = mul_mat(n, m, k, mat1, mat2)
    for i in new_mat:
        print(*i)


from typing import List
import os
import yaml
import h5py
import shutil
import numpy as np
import zarr
from scipy.io import wavfile
from matplotlib.pyplot import specgram
import pickle
from .init import _find_singular_file_in_dir
from ._project_config import _set_session_config_value

def create_spectrograms(session: str):
    dirname = f'./{session}'
    with open(f'{dirname}/isa-session.yaml', 'r') as f:
        config = yaml.safe_load(f)
    print('USING CONFIG')
    print(config)

    spectrograms_pkl_fname = f'{dirname}/spectrograms.pkl'
    spectrogram_for_gui_zarr_fname = f'{dirname}/spectrogram_for_gui.zarr'

    duration_sec = config['audio_duration_sec']
    audio_sr_hz = config['audio_sr_hz']

    # freq_range=[130, 230]

    # # between 0 and 100... percentile cutoff in the target freq band
    # # in spectrogram_for_gui
    # # everything below the value is set to zero
    # # affects detection and compressed file size
    # threshold_pct = 99.8

    audio_fname = _find_singular_file_in_dir(dirname, ['.h5', '.wav'])
    if audio_fname is None:
        raise Exception(f'No .h5 or .wav file found in directory: {dirname}')
    print(f'USING AUDIO: {audio_fname}')
    audio_path = f'{dirname}/{audio_fname}'

    print('Extracting audio signals')
    if audio_path.endswith('.h5'):
        with h5py.File(audio_path, 'r') as f:
            ch1 = np.array(f['ai_channels/ai0'])
            ch2 = np.array(f['ai_channels/ai1'])
            ch3 = np.array(f['ai_channels/ai2'])
            ch4 = np.array(f['ai_channels/ai3'])
            X = np.stack([ch1, ch2, ch3, ch4]).T

            # crop to duration
            X = X[0:int(duration_sec * audio_sr_hz)]
    elif audio_path.endswith('.wav'):
        sr, audio = wavfile.read(audio_path)
        # n_samples = audio.shape[0]
        # n_channels = audio.shape[1]
        # crop to duration
        X = audio[0:int(duration_sec * audio_sr_hz)]
    else:
        raise Exception(f'Unknown audio file type: {audio_path}')

    num_channels = X.shape[1]

    print('Computing spectrograms')
    spectrograms = []
    for channel_ind in range(num_channels):
        s, spectrogram_frequencies, spectrogram_times, im = specgram(X[:, channel_ind], NFFT=512, noverlap=256, Fs=audio_sr_hz)
        sr_spectrogram = float(1 / (spectrogram_times[1] - spectrogram_times[0]))
        spectrograms.append(s.T) # Use transpose so we have Nt x Nf
    print(f'Spectrogram sampling rate (Hz): {sr_spectrogram}')
    _set_session_config_value(session, 'spectrogram_sr_hz', sr_spectrogram)
    _set_session_config_value(session, 'spectrogram_num_frequencies', len(spectrogram_frequencies))
    _set_session_config_value(session, 'spectrogram_df', float(spectrogram_frequencies[1] - spectrogram_frequencies[0]))
    spectrogram_for_gui = sum(spectrograms)

    print('Auto detecting maxval')
    maxval = _auto_detect_spectrogram_maxval(spectrogram_for_gui, sr_spectrogram=sr_spectrogram)
    minval = 0
    print(f'Absolute spectrogram max: {np.max(spectrogram_for_gui)}')
    print(f'Auto detected spectrogram max: {maxval}')

    print('Scaling spectogram data')
    # Nf x Nt
    spectrogram_for_gui: np.ndarray = np.floor((spectrogram_for_gui - minval) / (maxval - minval) * 255).astype(np.uint8)

    # threshold = np.percentile(spectrogram_for_gui[freq_range[0]:freq_range[1]], threshold_pct)
    # print(f'Using threshold: {threshold} ({threshold_pct} pct)')
    # spectrogram_for_gui[spectrogram_for_gui <= threshold] = 0

    if os.path.exists(spectrogram_for_gui_zarr_fname):
        shutil.rmtree(spectrogram_for_gui_zarr_fname)

    if os.path.exists(spectrograms_pkl_fname):
        os.remove(spectrograms_pkl_fname)

    print(f'Writing {spectrograms_pkl_fname}')
    with open(spectrograms_pkl_fname, 'wb') as fb:
        pickle.dump({
            'spectrograms': spectrograms,
            'frequencies': spectrogram_frequencies,
            'times': spectrogram_times,
            'spectrogram_for_gui': spectrogram_for_gui
        }, fb)

    print(f'Writing {spectrogram_for_gui_zarr_fname}')
    root_group = zarr.open(spectrogram_for_gui_zarr_fname, mode="w")
    root_group.create_dataset("spectrogram", data=spectrogram_for_gui, chunks=(10000, len(spectrogram_frequencies)))

    ds_factor = 3
    previous_spectrogram = spectrogram_for_gui
    while ds_factor < len(spectrogram_times):
        spectrogram_for_gui_downsampled = downsample_spectrogram_using_max(previous_spectrogram, ds_factor=3)
        root_group.create_dataset(f"spectrogram_ds{ds_factor}", data=spectrogram_for_gui_downsampled, chunks=(10000, len(spectrogram_frequencies)))
        previous_spectrogram = spectrogram_for_gui_downsampled
        ds_factor *= 3

    root_group.attrs['spectrogram_sr_hz'] = sr_spectrogram
    root_group.create_dataset("frequencies", data=spectrogram_frequencies)
    root_group.create_dataset("times", data=spectrogram_times)

def _auto_detect_spectrogram_maxval(spectrogram: np.array, *, sr_spectrogram: float):
    Nt = spectrogram.shape[0]
    Nf = spectrogram.shape[1]
    chunk_num_samples = int(15 * sr_spectrogram)
    chunk_maxvals: List[float] = []
    i = 0
    while i + chunk_num_samples < Nt:
        chunk = spectrogram[i:i + chunk_num_samples]
        chunk_maxvals.append(np.max(chunk))
        i += chunk_num_samples
    v = np.median(chunk_maxvals)
    return v

def downsample_spectrogram_using_max(spectrogram: np.ndarray, *, ds_factor: int):
    Nt = spectrogram.shape[0]
    Nf = spectrogram.shape[1]
    Nt_ds = Nt // ds_factor
    spectrogram_ds = np.zeros((Nt_ds, Nf), dtype=spectrogram.dtype)
    spectrogram = spectrogram[:Nt_ds * ds_factor, :]
    spectrogram_reshaped = spectrogram.reshape((Nt_ds, ds_factor, Nf))
    spectrogram_ds = np.max(spectrogram_reshaped, axis=1)
    return spectrogram_ds


from bs4 import BeautifulSoup as bs
from splinter import Browser
import time
import os
import pandas as pd
import requests
from pprint import pprint

### NASA Mars News
url = "https://mars.nasa.gov/news/"
response = requests.get (url)
response
def init_browser():
    executable_path = {"executable_path": "chromedriver.exe"}
    return Browser("chrome", **executable_path, headless=False)
browser = init_browser()
browser.visit(url)
html = browser.html
time.sleep(4)
soup = bs(html, 'html.parser')
time.sleep(2)
results = soup.find_all("div",class_="list_text")
marsinfo={}
for result in results[:1]:
    try:
        news_title=result.find('div',class_="content_title").a.text
        news_description=result.find('div',class_="article_teaser_body").text
        if(news_description and news_title):
            print("Title:")
            print(news_title)
            print("Description:")
            print(news_description)
    except AttributeError as e:
        print(e)

news_date=result.find('div',class_="list_date").text
print("Date of Article:")
print(news_date)
marsinfo["title"]=news_title
marsinfo["paragraph"]=news_description
marsinfo["date"]=news_date
browser.quit()

### JPL Mars Space Images - Featured Image
url="https://www.jpl.nasa.gov/spaceimages/?search=&category=Mars"
executable_path = {'executable_path': 'chromedriver.exe'}
browser = Browser('chrome', **executable_path)
browser.visit(url)
time.sleep(3)

soup = bs(browser.html, 'html.parser')
featured_image=soup.find('article', class_="carousel_item")
pprint(featured_image)
forurl = featured_image['style'][23:-3]
featured_image_url = 'https://www.jpl.nasa.gov/' + forurl
marsinfo["featured_image"]=featured_image_url
print(featured_image_url)
browser.quit()

### Mars Facts
url = 'https://space-facts.com/mars/'
tables = pd.read_html(url)
pprint(tables)
df = tables[0]
df.columns = ['Data', 'Information']
df
mars_facts = df.to_html('mars_facts.html')
marsinfo["facts"]=mars_facts
pprint(mars_facts)

### Mars Hemispheres
url= "https://astrogeology.usgs.gov/search/results?q=hemisphere+enhanced&k1=target&v1=Mars"
executable_path = {'executable_path': 'chromedriver.exe'}
browser = Browser('chrome', **executable_path)
browser.visit(url)
time.sleep(3)
hemisphere_urls = []

# Get a List of All the Hemispheres
urls = browser.find_by_css("a.product-item h3")
for item in range(len(urls)):
    hemisphere = {}
    browser.find_by_css("a.product-item h3")[item].click()
    hemisphere["title"] = browser.find_by_css("h2.title").text
    findelement = browser.links.find_by_text("Sample").first
    hemisphere["image_link"] = findelement["href"]
    hemisphere_urls.append(hemisphere)
    browser.back()
browser.quit()


month, day = map(int,input().split())

while True:
    if month<= 12 and month >= 1 and day <= 31 and day >= 1:
        smonth = list(map(int,str(month)))
        sday = list(map(int,str(day)))

        if len(smonth) <2 and len(sday) < 2:
            if smonth[0] == sday[0]:
                print("Yes")
                break
            else:
                print("No")
                break
        elif len(smonth) < 2 and len(sday) == 2:
            if smonth[0] == sday[0] and smonth[0] == sday[1] :
                print("Yes")
                break
            else:
                print("No")
                break
        elif len(smonth) == 2 and len(sday) < 2:
            if smonth[0] == smonth[0] and smonth[1] == sday[0] :
                print("Yes")
                break
            else:
                print("No")
                break
        elif len(smonth) == 2 and len(sday) == 2:
            if smonth[0] == smonth[1] and smonth[0] == sday[0] and smonth[0] == sday[1] or smonth[0] == sday[0] and smonth[1] == sday[1]:
                print("Yes")
                break
            else:
                print("No")
                break
        else:
            print("Hello")
    else:
        month = int(input())
        day = int(input())


from django.contrib.auth.models import Permission, User, Group
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import SuspiciousOperation
from django.db import transaction
from django.db.models import Q, Count
from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.cache import cache_page

from guardian.models import UserObjectPermission, GroupObjectPermission
from guardian.shortcuts import get_perms

from igdectk.rest.handler import *
from igdectk.rest.response import HttpResponseRest
from igdectk.module.manager import module_manager
from main.cursor import CursorQuery
from main.models import Entity, Profile

from .filters import GroupFilter, UserFilter
from .utils import get_permissions_for, prefetch_permissions_for

class RestPermission(RestHandler):
    regex = r'^permission/$'
    name = 'permission'

class RestPermissionType(RestPermission):
    regex = r'^type/$'
    suffix = 'type'

class RestPermissionUser(RestPermission):
    regex = r'^user/$'
    suffix = 'user'

class RestPermissionUserCount(RestPermissionUser):
    regex = r'^user/count/$'
    suffix = 'user/count/'

class RestPermissionUserSearch(RestPermissionUser):
    regex = r'^search/$'
    suffix = 'search'

class RestPermissionUserName(RestPermissionUser):
    regex = r'^username/(?P<username>[a-zA-Z0-9\.\-_]+)/$'
    suffix = 'username'

class RestPermissionUserNamePermission(RestPermissionUserName):
    regex = r'^permission/$'
    suffix = 'permission'

class RestPermissionGroup(RestPermission):
    regex = r'^group/$'
    suffix = 'group'

class RestPermissionGroupCount(RestPermission):
    regex = r'^count/$'
    suffix = 'count'

class RestPermissionGroupSearch(RestPermissionGroup):
    regex = r'^search/$'
    suffix = 'search'

class RestPermissionGroupId(RestPermissionGroup):
    regex = r'^(?P<grp_id>[0-9]+)/$'
    suffix = 'name'

class RestPermissionGroupIdUser(RestPermissionGroupId):
    regex = r'^user/$'
    suffix = 'user'

class RestPermissionGroupIdUserName(RestPermissionGroupIdUser):
    regex = r'^username/(?P<username>[a-zA-Z0-9\.\-_]+)/$'
    suffix = 'username'

class RestPermissionGroupIdPermission(RestPermissionGroupId):
    regex = r'^permission/$'
    suffix = 'permission'

class RestPermissionGroupIdPermissionCount(RestPermissionGroupIdPermission):
    regex = r'^permission/count/$'
    suffix = 'count'

class RestPermissionPermission(RestPermission):
    regex = r'^permission/$'
    name = 'permission'

class RestPermissionPermissionEntity(RestPermission):
    regex = r'^(?P<content_type>[a-z\_]+)/(?P<ent_id>[0-9]+)/$'
    name = 'entity'

# Group name validator
GROUP_NAME_VALIDATOR = {"type": "string", "minLength": 3, "maxLength": 80, "pattern": "^[a-zA-Z0-9\-\_]+$"}

# Group name validator optional
GROUP_NAME_VALIDATOR_OPTIONAL = {"type": "string", "minLength": 3, "maxLength": 80, "pattern": "^[a-zA-Z0-9\-\_]+$",
                                 "required": False}

@RestPermissionType.def_request(Method.GET, Format.JSON)
@cache_page(60*60*24, cache='default', key_prefix='collgate-cache')
def get_permission_types(request):
    """
    Get the list of permissions type in JSON
    """
    logger.debug("Cache miss for permission.permission-type")

    ignore_list = [
        'admin.',
        'contenttypes.',
        'guardian.',
        'main.profile.',
        'main.settings.',
        'sessions.',
        'sites.',
    ]

    for module in module_manager.modules:
        if hasattr(module, 'ignored_permission_types'):
            ignore_list.extend(module.ignored_permission_types)

    types = []

    for perm in Permission.objects.all().select_related('content_type'):
        pid = "%s.%s.%s" % (perm.content_type.app_label, perm.content_type.model, perm.codename)
        add = True
        for ignore_pattern in ignore_list:
            if pid.startswith(ignore_pattern):
                add = False
                break

        if add:
            types.append({
                'id': perm.id,
                'value': pid,
                'label': perm.name
            })

    return HttpResponseRest(request, types)

@RestPermissionUser.def_auth_request(Method.GET, Format.JSON, staff=True)
def get_users_list(request):
    results_per_page = int_arg(request.GET.get('more', 30))
    cursor = json.loads(request.GET.get('cursor', 'null'))
    limit = results_per_page
    sort_by = json.loads(request.GET.get('sort_by', '["username"]'))
    order_by = sort_by

    cq = CursorQuery(User)

    if request.GET.get('search'):
        search = json.loads(request.GET['search'])
        cq.filter(search)

    if request.GET.get('filters'):
        filters = json.loads(request.GET['filters'])
        cq.filter(filters)

    cq.cursor(cursor, order_by)
    cq.order_by(order_by).limit(limit)
    cq.set_count('user_permissions')

    user_items = []

    for user in cq:
        user_items.append({
            'id': user.id,
            'username': user.username,
            'first_name': user.first_name,
            'last_name': user.last_name,
            'email': user.email,
            'is_active': user.is_active,
            'is_staff': user.is_staff,
            'is_superuser': user.is_superuser,
            'num_permissions': user.user_permissions.all().count()  # optimized by the set_count
        })

    results = {
        'perms': get_permissions_for(request.user, "auth", "user"),
        'items': user_items,
        'prev': cq.prev_cursor,
        'cursor': cursor,
        'next': cq.next_cursor
    }

    return HttpResponseRest(request, results)

@RestPermissionUserCount.def_auth_request(Method.GET, Format.JSON, staff=True)
def get_users_list_count(request):
    cq = CursorQuery(User)

    if request.GET.get('search'):
        search = json.loads(request.GET['search'])
        cq.filter(search)

    if request.GET.get('filters'):
        filters = json.loads(request.GET['filters'])
        cq.filter(filters)

    results = {
        'perms': [],
        'count': cq.count()
    }

    return HttpResponseRest(request, results)

@RestPermissionGroup.def_auth_request(Method.GET, Format.JSON, staff=True)
def get_groups_list(request):
    results_per_page = int_arg(request.GET.get('more', 30))
    cursor = json.loads(request.GET.get('cursor', 'null'))
    limit = results_per_page
    sort_by = json.loads(request.GET.get('sort_by', '["name"]'))
    order_by = sort_by

    cq = CursorQuery(Group)

    if request.GET.get('search'):
        search = json.loads(request.GET['search'])
        cq.filter(search)

    if request.GET.get('filters'):
        filters = json.loads(request.GET['filters'])
        cq.filter(filters)

    cq.cursor(cursor, order_by)
    cq.order_by(order_by).limit(limit)
    cq.prefetch_related('permissions')
    cq.prefetch_related('user_set')

    # @todo is it prefetch something ?
    prefetch_permissions_for(request.user, cq)

    group_items = []

    for group in cq:
        group_items.append({
            'id': group.id,
            'name': group.name,
            'num_users': group.user_set.all().count(),  # optimized by prefetch_related
            'num_permissions': group.permissions.all().count(),  # optimized by prefetch_related
            'perms': get_permissions_for(request.user, "auth", "group", group),
        })

    results = {
        'perms': get_permissions_for(request.user, "auth", "group"),
        'items': group_items,
        'prev': cq.prev_cursor,
        'cursor': cursor,
        'next': cq.next_cursor
    }

    return HttpResponseRest(request, results)

@RestPermissionGroupCount.def_auth_request(Method.GET, Format.JSON, staff=True)
def get_groups_list_count(request):
    cq = CursorQuery(Group)

    if request.GET.get('search'):
        search = json.loads(request.GET['search'])
        cq.filter(search)

    if request.GET.get('filters'):
        filters = json.loads(request.GET['filters'])
        cq.filter(filters)

    results = {
        'perms': [],
        'count': cq.count()
    }

    return HttpResponseRest(request, results)

@RestPermissionGroup.def_auth_request(Method.POST, Format.JSON, staff=True, content={
    "type": "object",
    "properties": {
        "name": GROUP_NAME_VALIDATOR
    },
})
def add_group(request):
    group_name = request.data['name']

    if Group.objects.filter(name__exact=group_name).exists():
        raise SuspiciousOperation(_("Group name already in usage"))

    group = Group(name=group_name)
    group.save()

    response = {
        'id': group.id,
        'name': group_name,
        'num_users': 0,
        'num_permissions': 0,
        'perms': get_permissions_for(request.user, "auth", "group"),
    }

    return HttpResponseRest(request, response)

@RestPermissionGroupId.def_auth_request(Method.GET, Format.JSON)
def get_group_details(request, grp_id):
    group = get_object_or_404(Group, id=int(grp_id))

    result = {
        'id': group.id,
        'name': group.name,
        'num_users': group.user_set.all().count(),
        'num_permissions': group.permissions.all().count(),
        'perms': get_permissions_for(request.user, "auth", "group", group),
    }

    return HttpResponseRest(request, result)

@RestPermissionGroupId.def_auth_request(Method.DELETE, Format.JSON, staff=True)
def delete_group(request, grp_id):
    group = get_object_or_404(Group, id=int(grp_id))

    if group.user_set.all().count() > 0:
        raise SuspiciousOperation(_("Only empty groups can be deleted"))

    group.delete()

    return HttpResponseRest(request, {})

@RestPermissionGroupId.def_auth_request(
    Method.PATCH, Format.JSON, content={
        "type": "object",
        "properties": {
            "name": GROUP_NAME_VALIDATOR_OPTIONAL
        },
    },
    staff=True)
def patch_group(request, grp_id):
    group = get_object_or_404(Group, id=int(grp_id))
    group_name = request.data.get('name')

    update = False
    result = {'id': group.pk, 'perms': get_permissions_for(request.user, "auth", "group")}

    if group_name and group_name != group.name:
        if Group.objects.filter(name__exact=group_name).exists():
            raise SuspiciousOperation(_("Group name already in usage"))

        group.name = group_name
        group.full_clean()
        result['name'] = group.name

        update = True

    if update:
        group.save()

    return HttpResponseRest(request, result)

@RestPermissionGroupSearch.def_auth_request(Method.GET, Format.JSON, ('filters',))
def search_group(request):
    groups = GroupFilter.search(json.loads(request.GET['filters']))

    items = []

    response = {
        'total_count': groups.count(),
        'page': 1,
        'items': items
    }

    if groups:
        for g in groups:
            items.append({"id": str(g.id), "label": g.name, "value": g.name})

    return HttpResponseRest(request, response)

@RestPermissionUserSearch.def_auth_request(Method.GET, Format.JSON, ('filters',))
def search_user(request):
    users = UserFilter.search(json.loads(request.GET['filters']))

    items = []

    response = {
        'total_count': users.count(),
        'page': 1,
        'items': items
    }

    if users:
        for u in users:
            items.append({"id": str(u.id), "label": "%s (%s)" % (u.get_full_name(), u.username), "value": u.username})

    return HttpResponseRest(request, response)

class Perm:
    def __init__(self, permissions, model, obj, object_name):
        self.permissions = permissions
        self.model = model
        self.object = obj
        self.object_name = object_name

    def __lt__(self, other):
        if self.object_name == other.object_name:
            return self.model < other.model
        else:
            if self.object_name and other.object_name:
                return self.object_name < other.object_name
            elif not self.object_name:
                return self
            else:
                return other.object_name

    def __eq__(self, other):
        return (self.object_name == other.object_name) and (self.model == other.model)

@RestPermissionUserNamePermission.def_auth_request(Method.GET, Format.JSON, staff=True)
def get_user_permissions(request, username):
    user = get_object_or_404(User, username=username)

    permissions = []

    # from classification.models import Taxon
    # content_type = ContentType.objects.get_by_natural_key('classification', 'Taxon')
    # obj = get_object_or_404(Taxon, id=1)
    # UserObjectPermission.objects.assign_perm('change_taxon', user=User.objects.get(username='fscherma'), obj=obj)

    checkout = Permission.objects.filter(user=user).select_related('content_type')
    lookup = {}

    for perm in checkout:
        if perm.content_type.model in lookup:
            perms = lookup[perm.content_type.model]
        else:
            perms = []
            lookup[perm.content_type.model] = perms

        perms.append({
            'id': perm.codename,
            'name': perm.name,
            'app_label': perm.content_type.app_label,
        })

    for k, v in lookup.items():
        permissions.append(Perm(v, k, None, None))

    checkout = UserObjectPermission.objects.filter(user=user).select_related('permission', 'content_type')
    lookup = {}

    for perm in checkout:
        obj_name = perm.content_type.get_object_for_this_type(id=perm.object_pk).name

        if (perm.object_pk, perm.content_type.model, obj_name) in lookup:
            perms = lookup[(perm.object_pk, perm.content_type.model, obj_name)]
        else:
            perms = []
            lookup[(perm.object_pk, perm.content_type.model, obj_name)] = perms

        perms.append({
            'id': perm.permission.codename,
            'name': perm.permission.name,
            'app_label': perm.content_type.app_label,
        })

    for k, v in lookup.items():
        permissions.append(Perm(v, k[1], k[0], k[2]))

    permissions.sort()

    response = {
        'username': user.username,
        'permissions': permissions,
        'perms': get_permissions_for(request.user, "auth", "permission"),
    }

    return HttpResponseRest(request, response)

@RestPermissionUserName.def_admin_request(Method.GET, Format.JSON)
def get_user_info(request, username):
    user = get_object_or_404(User, username=username)

    result = {
        'id': user.pk,
        'username': user.username,
        'first_name': user.first_name,
        'last_name': user.last_name
    }

    return HttpResponseRest(request, result)

@RestPermissionUserName.def_admin_request(Method.PATCH, Format.JSON, content={
    "type": "object",
    "properties": {
        "is_active": {"type": "boolean", "required": False},
        "is_staff": {"type": "boolean", "required": False},
        "is_superuser": {"type": "boolean", "required": False},
    },
})
@transaction.atomic
def patch_user(request, username):
    user = get_object_or_404(User, username=username)
    update = False

    result = {'id': user.pk}

    if 'is_active' in request.data:
        update = True
        user.is_active = request.data['is_active']
        result['is_active'] = user.is_active

        # update the pending state if necessary
        try:
            profile = Profile.objects.get(user=user)
            if user.is_active and profile.pending:
                profile.pending = False
                profile.save()
        except Profile.DoesNotExist:
            pass

    if 'is_staff' in request.data:
        update = True
        user.is_staff = request.data['is_staff']
        result['is_staff'] = user.is_staff

    if 'is_superuser' in request.data:
        update = True
        user.is_superuser = request.data['is_superuser']
        result['is_superuser'] = user.is_superuser

    if update:
        user.save()

    return HttpResponseRest(request, result)

@RestPermissionUserNamePermission.def_auth_request(
    Method.POST, Format.JSON, content={
        "type": "object",
        "properties": {
            "permission": Entity.PERMISSION_VALIDATOR,
            "content_type": Entity.CONTENT_TYPE_VALIDATOR,
            "object": {"type": "integer", 'required': False},
        },
    },
    perms={'auth.change_user': _("You are not allowed to changer a user")},
    staff=True)
def add_user_permission(request, username):
    permission = request.data['permission']
    content_type = request.data['content_type']
    object_id = int(request.data['object']) if 'object' in request.data else None

    if content_type == "auth.permission" and not request.user.is_superuser:
        raise PermissionDenied(_("Only a superuser can change an auth.permission"))

    user = get_object_or_404(User, username=username)

    app_label, model = content_type.split('.')
    # content_type = get_object_or_404(ContentType, app_label=app_label, model=model)
    content_type = ContentType.objects.get_by_natural_key(app_label, model)

    if not object_id:
        perm = get_object_or_404(Permission, codename=permission, content_type=content_type)
        user.user_permissions.add(perm)
    else:
        obj = get_object_or_404(content_type.model, id=object_id)
        UserObjectPermission.objects.assign_perm(permission, user=user, obj=obj)

    return HttpResponseRest(request, {})

@RestPermissionUserNamePermission.def_auth_request(
    Method.PATCH, Format.JSON, content={
        "type": "object",
        "properties": {
            "action": {"type": "string", "pattern": "^(add|remove)$"},
            "target": {"type": "string", "pattern": "^permission$"},
            "permission": Entity.PERMISSION_VALIDATOR,
            "content_type": Entity.CONTENT_TYPE_VALIDATOR,
            "object": {"type": "integer", 'required': False},
        },
    },
    perms={'auth.change_user': _("You are not allowed to changer a user")},
    staff=True)
def delete_user_permission(request, username):
    action = request.data['action']
    permission = request.data['permission']
    content_type = request.data['content_type']
    object_id = int(request.data['object']) if 'object' in request.data else None

    if content_type == "auth.permission" and not request.user.is_superuser:
        raise PermissionDenied(_("Only a superuser can change an auth.permission"))

    user = get_object_or_404(User, username=username)

    app_label, model = content_type.split('.')
    content_type = ContentType.objects.get_by_natural_key(app_label, model)

    if not object_id:
        perm = get_object_or_404(Permission, codename=permission, content_type=content_type)
        if action == "add":
            user.user_permissions.add(perm)
        elif action == "remove":
            user.user_permissions.remove(perm)
        else:
            raise SuspiciousOperation('Invalid patch action')
    else:
        obj = get_object_or_404(content_type.model, id=object_id)

        if action == "add":
            UserObjectPermission.objects.assign_perm(permission, user=user, obj=obj)
        elif action == "remove":
            UserObjectPermission.objects.remove_perm(permission, user=user, obj=obj)
        else:
            raise SuspiciousOperation('Invalid patch action')

    return HttpResponseRest(request, {})

@RestPermissionGroupIdPermission.def_auth_request(Method.GET, Format.JSON, staff=True)
def get_group_permissions(request, grp_id):
    group = get_object_or_404(Group, id=int(grp_id))
    permissions = []

    checkout = Permission.objects.filter(group=group).select_related('content_type')
    lookup = {}

    for perm in checkout:
        if perm.content_type.model in lookup:
            perms = lookup[perm.content_type.model]
        else:
            perms = []
            lookup[perm.content_type.model] = perms

        perms.append({
            'id': perm.codename,
            'name': perm.name,
            'app_label': perm.content_type.app_label,
        })

    for k, v in lookup.items():
        permissions.append(Perm(v, k, None, None))

    checkout = GroupObjectPermission.objects.filter(group=group).select_related('permission', 'content_type')
    lookup = {}

    for perm in checkout:
        obj_name = perm.content_type.get_object_for_this_type(id=perm.object_pk).name

        if (perm.object_pk, perm.content_type.model, obj_name) in lookup:
            perms = lookup[(perm.object_pk, perm.content_type.model, obj_name)]
        else:
            perms = []
            lookup[(perm.object_pk, perm.content_type.model, obj_name)] = perms

        perms.append({
            'id': perm.permission.codename,
            'name': perm.permission.name,
            'app_label': perm.content_type.app_label,
        })

    for k, v in lookup.items():
        permissions.append(Perm(v, k[1], k[0], k[2]))

    permissions.sort()

    response = {
        'id': group.id,
        'name': group.name,
        'permissions': permissions,
        'perms': get_permissions_for(request.user, "auth", "permission"),
    }

    return HttpResponseRest(request, response)

@RestPermissionGroupIdPermission.def_auth_request(
    Method.POST, Format.JSON, content={
        "type": "object",
        "properties": {
            "permission": Entity.PERMISSION_VALIDATOR,
            "content_type": Entity.CONTENT_TYPE_VALIDATOR,
            "object": {"type": "integer", 'required': False},
        },
    },
    perms={'auth.change_group': _("You are not allowed to change a group")},
    staff=True)
def add_group_permission(request, grp_id):
    permission = request.data['permission']
    content_type = request.data['content_type']
    object_id = int(request.data['object']) if 'object' in request.data else None

    if content_type == "auth.permission" and not request.user.is_superuser:
        raise PermissionDenied(_("Only a superuser can change an auth.permission"))

    group = get_object_or_404(Group, id=int(grp_id))

    app_label, model = content_type.split('.')
    content_type = ContentType.objects.get_by_natural_key(app_label, model)

    if not object_id:
        perm = get_object_or_404(Permission, codename=permission, content_type=content_type)
        group.permissions.add(perm)
    else:
        obj = get_object_or_404(content_type.model, id=object_id)
        GroupObjectPermission.objects.assign_perm(permission, group=group, obj=obj)

    return HttpResponseRest(request, {})

@RestPermissionGroupIdPermission.def_auth_request(
    Method.PATCH, Format.JSON, content={
        "type": "object",
        "properties": {
            "action": {"type": "string", "pattern": "^(add|remove)$"},
            "target": {"type": "string", "pattern": "^permission$"},
            "permission": Entity.PERMISSION_VALIDATOR,
            "content_type": Entity.CONTENT_TYPE_VALIDATOR,
            "object": {"type": "integer", 'required': False},
        },
    },
    perms={'auth.change_group': _("You are not allowed to change a group")},
    staff=True)
def change_group_permission(request, grp_id):
    action = request.data['action']
    permission = request.data['permission']
    content_type = request.data['content_type']
    target = request.data['target']
    object_id = int(request.data['object']) if 'object' in request.data else None

    if content_type == "auth.permission" and not request.user.is_superuser:
        raise PermissionDenied(_("Only a superuser can change an auth.permission"))

    group = get_object_or_404(Group, id=int(grp_id))

    app_label, model = content_type.split('.')
    content_type = ContentType.objects.get_by_natural_key(app_label, model)

    if target == "permission":
        if not object_id:
            perm = get_object_or_404(Permission, codename=permission, content_type=content_type)
            if action == "add":
                group.permissions.add(perm)
            elif action == "remove":
                group.permissions.remove(perm)
            else:
                raise SuspiciousOperation('Invalid action')
        else:
            obj = get_object_or_404(content_type.model, id=object_id)

            if action == "add":
                GroupObjectPermission.objects.assign_perm(permission, group=group, obj=obj)
            elif action == "remove":
                GroupObjectPermission.objects.remove_perm(permission, group=group, obj=obj)
            else:
                raise SuspiciousOperation('Invalid action')

    return HttpResponseRest(request, {})

@RestPermissionGroupIdUser.def_auth_request(Method.POST, Format.JSON, content={
        "type": "object",
        "properties": {
            "username": {"type": "string", 'minLength': 3, 'maxLength': 150},
        },
    },
    perms={'auth.change_group': _("You are not allowed to add a user into a group")},
    staff=True)
def group_add_user(request, grp_id):
    group = get_object_or_404(Group, id=int(grp_id))
    user = get_object_or_404(User, username=request.data['username'])

    if user in group.user_set.all():
        raise SuspiciousOperation(_("User already exists into the group"))

    user.groups.add(group)

    response = {
        'id': user.id,
        'username': user.username,
        'first_name': user.first_name,
        'last_name': user.last_name,
        'is_active': user.is_active,
        'is_staff': user.is_staff,
        'is_superuser': user.is_superuser,
        'email': user.email}

    return HttpResponseRest(request, response)

@RestPermissionGroupIdUserName.def_auth_request(
    Method.DELETE, Format.JSON,
    perms={'auth.change_group': _("You are not allowed to remove a user from a group")},
    staff=True)
def group_delete_user(request, grp_id, username):
    group = get_object_or_404(Group, id=int(grp_id))
    user = get_object_or_404(User, username=username)

    if user not in group.user_set.all():
        raise SuspiciousOperation(_("User does not exists into the group"))

    user.groups.remove(group)

    return HttpResponseRest(request, {})

@RestPermissionGroupIdUser.def_auth_request(Method.GET, Format.JSON, staff=True)
def get_users_list_for_group(request, grp_id):
    results_per_page = int_arg(request.GET.get('more', 30))
    cursor = json.loads(request.GET.get('cursor', 'null'))
    limit = results_per_page
    sort_by = json.loads(request.GET.get('sort_by', '["username"]'))
    order_by = sort_by

    group = get_object_or_404(Group, id=int(grp_id))
    cq = CursorQuery(User)

    if request.GET.get('search'):
        search = json.loads(request.GET['search'])
        cq.filter(search)

    if request.GET.get('filters'):
        filters = json.loads(request.GET['filters'])
        cq.filter(filters)

    cq.inner_join(Group, related_name='user_set', group=group.pk)
    cq.cursor(cursor, order_by)
    cq.order_by(order_by).limit(limit)

    user_items = []

    for user in cq:
        user_items.append({
            'id': user.id,
            'username': user.username,
            'first_name': user.first_name,
            'last_name': user.last_name,
            'email': user.email,
            'is_active': user.is_active,
            'is_staff': user.is_staff,
            'is_superuser': user.is_superuser,
        })

    results = {
        'perms': get_permissions_for(request.user, "auth", "group", group),
        'items': user_items,
        'prev': cq.prev_cursor,
        'cursor': cursor,
        'next': cq.next_cursor
    }

    return HttpResponseRest(request, results)

@RestPermissionPermission.def_auth_request(Method.GET, Format.JSON)
def get_self_permissions(request):
    """
    User get its own permissions for its session.
    """
    user = get_object_or_404(User, username=request.user.username)

    permissions = []

    # at user level and groups
    checkout = Permission.objects.filter(
        Q(user=user) | Q(group__in=user.groups.all().values_list('id'))).select_related('content_type')

    for perm in checkout:
        permissions.append({
            'id': perm.codename,
            'name': perm.name,
            'app_label': perm.content_type.app_label,
        })

    return HttpResponseRest(request, permissions)

@RestPermissionPermissionEntity.def_auth_request(Method.GET, Format.JSON)
def get_self_permissions_for_entity(request, content_type, ent_id):
    """
    User get its own permissions for its session for a specific entity
    """
    user = get_object_or_404(User, username=request.user.username)

    permissions = []

    app_label, model = content_type.split('.')
    content_type = ContentType.objects.get_by_natural_key(app_label, model)

    entity = get_object_or_404(content_type.model_class(), int(ent_id))

    perms = get_perms(user, entity)
    permission_details = Permission.objects.find(codename__in=perms)

    lookup = {}

    for perm in permission_details:
        lookup[perm.codename] = perm.name

    for perm in perms:
        perm_detail = lookup.get(perm)

        if perm_detail:
            permissions.append({
                'id': perm,
                'name': perm_detail,
                'app_label': app_label
            })

    return HttpResponseRest(request, permissions)


import os
import tempfile

import configparser
import pytest
from configparser import NoOptionError, NoSectionError

from assertpy import assert_that
from pcluster.config.param_types import Param
from pcluster.config.pcluster_config import PclusterConfig
from tests.pcluster.config.defaults import CFN_CONFIG_NUM_OF_PARAMS, DefaultDict

def get_param_definition(section_definition, param_key):
    param_definition = section_definition.get("params").get(param_key)
    return param_definition, param_definition.get("type", Param)

def merge_dicts(*args):
    """Merge multiple dictionaries into a new dictionary as a shallow copy."""
    merged_dict = {}
    for input_dict in args:
        merged_dict.update(input_dict)
    return merged_dict

def get_pcluster_config_example():
    current_dir = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(current_dir, "..", "..", "..", "pcluster", "examples", "config")

def assert_param_from_file(mocker, section_definition, param_key, param_value, expected_value, expected_message):
    section_label = section_definition.get("default_label")
    section_name = "{0}{1}".format(section_definition.get("key"), " {0}".format(section_label) if section_label else "")
    config_parser = configparser.ConfigParser()
    config_parser.add_section(section_name)

    pcluster_config = get_mocked_pcluster_config(mocker)

    if param_value:
        config_parser.set(section_name, param_key, param_value)

    param_definition, param_type = get_param_definition(section_definition, param_key)

    if expected_message:
        with pytest.raises(SystemExit, match=expected_message):
            param_type(
                section_definition.get("key"), section_label, param_key, param_definition, pcluster_config
            ).from_file(config_parser)
    else:
        param = param_type(
            section_definition.get("key"), section_label, param_key, param_definition, pcluster_config
        ).from_file(config_parser)
        assert_that(param.value, description="{0} assert fail".format(param.key)).is_equal_to(expected_value)

def assert_param_validator(mocker, config_parser_dict, expected_message=None):
    config_parser = configparser.ConfigParser()
    config_parser.read_dict(config_parser_dict)

    mocker.patch("pcluster.config.param_types.get_avail_zone", return_value="mocked_avail_zone")
    mocker.patch.object(PclusterConfig, "_PclusterConfig__check_account_capacity")

    if expected_message:
        with pytest.raises(SystemExit, match=expected_message):
            _ = init_pcluster_config_from_configparser(config_parser)
    else:
        _ = init_pcluster_config_from_configparser(config_parser)

def assert_section_from_cfn(mocker, section_definition, cfn_params_dict, expected_section_dict):

    cfn_params = []
    for cfn_key, cfn_value in cfn_params_dict.items():
        cfn_params.append({"ParameterKey": cfn_key, "ParameterValue": cfn_value})

    pcluster_config = get_mocked_pcluster_config(mocker)

    section_type = section_definition.get("type")
    section = section_type(section_definition, pcluster_config).from_cfn_params(cfn_params)

    if section.label:
        assert_that(section.label).is_equal_to("default")

    # update expected dictionary
    default_dict = DefaultDict[section_definition.get("key")].value
    expected_dict = default_dict.copy()
    if isinstance(expected_section_dict, dict):
        expected_dict.update(expected_section_dict)

    section_dict = {}
    for param_key, param in section.params.items():
        section_dict[param_key] = param.value

    assert_that(section_dict).is_equal_to(expected_dict)

def get_mocked_pcluster_config(mocker):
    return PclusterConfig(config_file="wrong-file")

def assert_section_from_file(mocker, section_definition, config_parser_dict, expected_dict_params, expected_message):
    config_parser = configparser.ConfigParser()
    config_parser.read_dict(config_parser_dict)

    # update expected dictionary
    default_dict_key = section_definition.get("key")
    if default_dict_key == "global":
        default_dict_key += "_"
    default_dict = DefaultDict[default_dict_key].value
    expected_dict = default_dict.copy()
    if isinstance(expected_dict_params, dict):
        expected_dict.update(expected_dict_params)

    pcluster_config = get_mocked_pcluster_config(mocker)

    section_type = section_definition.get("type")
    if expected_message:
        with pytest.raises(SystemExit, match=expected_message):
            _ = section_type(section_definition, pcluster_config).from_file(config_parser)
    else:
        section = section_type(section_definition, pcluster_config).from_file(config_parser)
        section_dict = {}
        for param_key, param in section.params.items():
            section_dict[param_key] = param.value

        assert_that(section_dict).is_equal_to(expected_dict)

def assert_section_to_file(mocker, section_definition, section_dict, expected_config_parser_dict, expected_message):
    expected_config_parser = configparser.ConfigParser()
    expected_config_parser.read_dict(expected_config_parser_dict)

    pcluster_config = get_mocked_pcluster_config(mocker)

    output_config_parser = configparser.ConfigParser()
    section_type = section_definition.get("type")
    section = section_type(section_definition, pcluster_config, section_label="default")

    for param_key, param_value in section_dict.items():
        param_definition, param_type = get_param_definition(section.definition, param_key)
        param = param_type(section_definition.get("key"), "default", param_key, param_definition, pcluster_config)
        param.value = param_value
        section.add_param(param)

    section.to_file(output_config_parser)

    for section_key, section_params in expected_config_parser_dict.items():
        for param_key, param_value in section_params.items():

            assert_that(output_config_parser.has_option(section_key, param_key))
            if expected_message is not None:
                if "No section" in expected_message:
                    with pytest.raises(NoSectionError, match=expected_message):
                        assert_that(output_config_parser.get(section_key, param_key)).is_equal_to(param_value)
                else:
                    with pytest.raises(NoOptionError, match=expected_message):
                        assert_that(output_config_parser.get(section_key, param_key)).is_equal_to(param_value)

            else:
                assert_that(output_config_parser.get(section_key, param_key)).is_equal_to(param_value)

def assert_section_to_cfn(mocker, section_definition, section_dict, expected_cfn_params):

    pcluster_config = get_mocked_pcluster_config(mocker)

    section_type = section_definition.get("type")
    section = section_type(section_definition, pcluster_config)
    for param_key, param_value in section_dict.items():
        param_definition, param_type = get_param_definition(section_definition, param_key)
        param = param_type(section_definition.get("key"), "default", param_key, param_definition, pcluster_config)
        param.value = param_value
        section.add_param(param)
    pcluster_config.add_section(section)

    cfn_params = section.to_cfn()
    assert_that(cfn_params).is_equal_to(expected_cfn_params)

def assert_section_params(mocker, pcluster_config_reader, settings_label, expected_cfn_params):
    if isinstance(expected_cfn_params, SystemExit):
        with pytest.raises(SystemExit):
            PclusterConfig(
                cluster_label="default",
                config_file=pcluster_config_reader(settings_label=settings_label),
                fail_on_file_absence=True,
                fail_on_error=True,
            )
    else:
        pcluster_config = PclusterConfig(
            config_file=pcluster_config_reader(settings_label=settings_label), fail_on_file_absence=True
        )

        cfn_params = pcluster_config.to_cfn()

        assert_that(len(cfn_params)).is_equal_to(CFN_CONFIG_NUM_OF_PARAMS)

        for param_key, _ in cfn_params.items():
            assert_that(cfn_params.get(param_key), description=param_key).is_equal_to(
                expected_cfn_params.get(param_key)
            )

def init_pcluster_config_from_configparser(config_parser, validate=True):
    with tempfile.NamedTemporaryFile(delete=False) as config_file:

        with open(config_file.name, "w") as cf:
            config_parser.write(cf)

        pcluster_config = PclusterConfig(
            config_file=config_file.name, cluster_label="default", fail_on_file_absence=True
        )
        if validate:
            pcluster_config.validate()
    return pcluster_config


import os
import argparse

#   tests 里的是 configs_XXX.sh 后面的 XXX
#   例: configs_example.sh 中的 XXX 为 example
#   如果要同时做多组就写成 tests=['example1','example2','example3',...]
sim_tests=['example']
reload_tests=['example']

parser=argparse.ArgumentParser(description='A tool for simpoint and reload checkpoints')
parser.add_argument("-n","--name",help="use NAME to replace the original test.")
parser.add_argument("-s","--simpoint",help="use simpoint to generate checkpoint",
                    action="store_true")
parser.add_argument("-r","--reload",help="use new parms to reload checkpoint",
                    action="store_true")
args=parser.parse_args()
#print(args)

def simpoint(tests):
    for item in tests:
        #   第一个是进行 Simpoint 模拟的，第二个是正常跑的，是验证 Simpoint 结果准确性的，
        #   理论上生成 Simpoint 就可以了，第二行命令可以注释掉
        #   ">" 后面的是将运行的输出重定向的地址，改成自己的即可
        os.system('nohup time bash process/process_sim.sh '+item+' > \
                /home/data/ChenRuiyang/time_rec/'+item+'_process.txt &')
        #os.system('nohup time bash process/process_normal.sh '+item+' > \
            # /home/data/ChenRuiyang/time_rec/'+item+'_normal.txt &')

def reload(tests):
    for item in tests:
        #   同上，只改了.sh文件的名字，执行重载操作
        #   ">" 后面的是将运行的输出重定向的地址，改成自己的即可
        os.system('nohup time bash process/process_reload.sh '+item+' > \
            /home/data/ChenRuiyang/time_rec/'+item+'_reload.txt &')

if args.name:
    sim_tests=reload_tests=[args.name]
    print("Using [",args.name,"] as the new test suffix.")
    print()

#   这里不能 simpoint 和 reload 同时做，
#   因为 reload 需要 simpoint 的结果.
if args.simpoint:
    print("Starting simpoint!")
    print()
    simpoint(sim_tests)
elif args.reload:
    print("Starting Reload!")
    print()
    reload(reload_tests)
else:
    print("Please give operations.")
    print("Use -h to get help")
    print()


import re
import requests

start = re.compile('(
Available Rooms
)');
pattern = re.compile('(([^< ]*)[^<]*)')
end = re.compile('(
)');

def get_available_rooms():
    r = requests.get('https://simmons-hall.scripts.mit.edu:444/rooming/text', cert='keystore.pem')
    content = r.text
    content = content[start.search(content).end(1):]
    content = content[:end.search(content).start(1)]
    available = set()
    while True:
        match = pattern.search(content)
        if match is None:
            break
        rm_num = match.group(2)
        content = content[match.end(1):]
        available.add(rm_num)
    return available