#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Oct 20 20:05:12 2018
@author: ljk
"""

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import re
from sklearn.preprocessing import OneHotEncoder
from sklearn.feature_selection import VarianceThreshold
from sklearn.preprocessing import LabelEncoder
from sklearn import ensemble
from sklearn.preprocessing import Imputer
from sklearn import linear_model
from sklearn.decomposition import PCA
from sklearn.feature_selection import SelectPercentile
from sklearn.feature_selection import chi2
from sklearn.ensemble import VotingClassifier

def canbebone():
    with open('/home/ljk/下载/kaggle/all (2)/data_description.txt') as f:
        asb=f.read()

    while '\n ' in asb or '\n\t' in asb:
        asb=asb.replace('\n ','\n')
        asb=asb.replace('\n\t','\n')

    aasb=asb.split('\n\n')
    sent=[]
    la=''
    for e in aasb:
        if ':' in e:
            try:
                re.match(' ',e).group()
                la+='\n'+e
            except:
                sent.append(la)
                la=''
                la+=e
        else:
            la+='\n'+e
    sent.append(la)
    sent.pop(0)

    canone=[]
    for se in sent:
        if 'NA' in se:
            canone.append(se)
    wc=[]
    for cn in canone:
        wc.append(re.search('\w+(?=\:)',cn).group())
    return wc
def findnoise(csv,trmax):
    thresh=5
    noiselis=set()
    for qs in csv:
        q=csv[qs]
        if '64' in str(q.dtype):
            mean=q.mean()
            std=q.std()
            for k in q.index:
                if k<=trmax:
                    if q.loc[k]<mean-thresh*std or q.loc[k]>mean+thresh*std:
                        noiselis.add(k)
    return noiselis
def sol(csv,trmax):
    global csvcp,colli
    usv=csv.shape[0]

    csvcp=csv.copy()
    cbn=canbebone()
    csvcp=csvcp.fillna({x:'NA' for x in cbn})
    csvcp=csvcp.dropna(axis=1,thresh=0.5*usv)#非空值少于90%就删去 thresh是非空值的量
    colli=findnoise(csvcp,trmax)
    csvcp.drop(colli,axis=0,inplace=True)
    u=csvcp.columns
    t=csvcp.dtypes
    objlist=['MSSubClass']
    delist=[]
    for k in range(len(u)):
        #print((csvcp[u[k]]).value_counts())
        mostv=(csvcp[u[k]]).value_counts()
        if mostv.iloc[0]>0.98*usv:
            delist.append(u[k])
        if '64' not in str(t[k]) or k=='MSSubClass':
            objlist.append(str(u[k]))
            csvcp.loc[:,u[k]]=csvcp.loc[:,u[k]].fillna(mostv.index[0])
        else:
            means=csvcp.loc[:,u[k]].mode()[0]
            csvcp.loc[:,u[k]]=csvcp.loc[:,u[k]].fillna(means)
    csvcp.drop(delist,axis=1,inplace=True)
    csvcp=pd.get_dummies(csvcp,drop_first=True)
    csvcp=pd.get_dummies(data=csvcp,columns=['MSSubClass'],drop_first=True)
    csvcp=csvcp.apply(lambda x: (x - np.min(x)) / (np.max(x) - np.min(x)))

#    PPP=PCA(n_components=0.5,whiten=True)
#    csvcp=PPP.fit_transform(csvcp)
    return csvcp

train=pd.read_csv('/home/ljk/下载/kaggle/all (2)/train.csv',index_col='Id')
test=pd.read_csv('/home/ljk/下载/kaggle/all (2)/test.csv',index_col='Id')

y=train['SalePrice'].apply(lambda x:np.log1p(x))
trains=train.drop(['SalePrice'],axis=1)
u=pd.concat((trains,test),axis=0)
trmax=train.index[-1]
ut=sol(u,trmax)
#li1=[i for i in test.index]
#li2=[i for i in train.index]

li1=[]
li2=[]
for i in ut.index:
    if i <=trmax:
        li2.append(i)
    else:
        li1.append(i)
y.drop(colli,axis=0,inplace=True)

train1=ut[0:len(li2)]#ut.drop(li2)
test1=ut[len(li2):]#ut.drop(li1)
#
#test1=ut.drop(li2)
#train1=ut.drop(li1)

#usb=SelectPercentile(chi2, percentile=70)
#usb.fit(train1, y)
#train1=usb.transform(train1)
#test1=usb.transform(test1)

#from sklearn import tree

#lr= ensemble.AdaBoostRegressor()

#from sklearn import svm
#lr = svm.SVR()

#from sklearn import ensemble
lr = ensemble.GradientBoostingRegressor(n_estimators=1000)

#from sklearn.ensemble import BaggingRegressor
#glr = BaggingRegressor()

#from sklearn.tree import ExtraTreeRegressor
#lr = ExtraTreeRegressor()

#from sklearn import neighbors
#blr= neighbors.KNeighborsRegressor()
#rlr = ensemble.RandomForestRegressor()#max_depth=7,max_features=143,random_state=2)
#7,151,8
#lr = linear_model.LinearRegression()
#y=train1['SalePrice']
#xx=train1.drop(['SalePrice'],axis=1)

#lr = VotingClassifier(estimators=[('lr', glr), ('rf', rlr), ('gnb', blr)], voting='hard')

lr.fit(train1,y)

test.loc[:,'SalePrice']=lr.predict(test1)

tt=test['SalePrice'].apply(lambda x:np.e**x-1)

tt.to_csv('hpr.csv',header=True)
from sklearn.model_selection import cross_val_predict
from sklearn import metrics
cross_predict = cross_val_predict(lr,train1,y,cv=5)
score=np.sqrt(metrics.mean_squared_error(np.log(np.e**y-1),np.log(np.e**cross_predict-1)))

#
#best=[1,0,0,0,0]
#for i in range(1,10):
#    for h in range(1,10):
#        for j in range(1,279):
#            for k in range(10):
#                cla=ensemble.RandomForestRegressor(max_depth=i, n_estimators=h, max_features=j,random_state=k)
#                cross_predict = cross_val_predict(lr,train1,y,cv=5)
#                score=np.sqrt(metrics.mean_squared_error(np.log(y),np.log(cross_predict)))
#                if score<best[0]:
#                    best=[score,i,h,j,k]
#                print(i,h,j,k)
#with open('sb.txt','w') as f:
#    f.write(str(best))


"""Module use to handle a namelists used by MESA
"""

from typing import Any, Dict, Union

import os
from collections import OrderedDict
from pathlib import Path

from stevdb.io import parse_fortran_value_to_python

class MESANamelists:
    """Namelists of MESA"""

    def __init__(self):
        self.star_namelists = ("star_job", "controls", "pgstar", "eos", "kap")
        self.binary_namelists = ("binary_job", "binary_controls")
        self.bin2dco_namelists = ("bin2dco_controls",)

class MESAMainNamelists:
    """Structure of the most important files for initializing a MESA simulation"""

    def __init__(self):
        self.namelists_for_mesabinary = {
            "binary_job": {
                "read_extra_binary_job_inlist1": True,
                "extra_binary_job_inlist1_name": "#{template}/inlist_project",
            },
            "binary_controls": {
                "read_extra_binary_controls_inlist1": True,
                "extra_binary_controls_inlist1_name": "#{template}/inlist_project",
            },
            "binary_pgstar": {
                "read_extra_binary_pgstar_inlist1": True,
                "extra_binary_pgstar_inlist1_name": "#{template}/inlist_project",
            },
        }

        self.namelists_for_mesabin2dco = {
            "bin2dco_controls": {
                "do_star_plus_star": False,
                "star_plus_star_filename": "inlist_star_plus_star",
                "star_plus_pm_filename": "inlist_star_plus_pm",
                "cc1_inlist_filename": "inlist_cc",
                "cc2_inlist_filename": "inlist_cc",
                "ce1_inlist_filename": "inlist_ce",
                "ce2_inlist_filename": "inlist_ce",
                "stop_after_plus_star": True,
                "do_kicks": False,
                "do_kicks_in_one_run": False,
                "natal_kicks_filename": "",
                "header_lines_to_skip_in_natal_kicks_file": 1,
                "star_info_at_cc_filename": "cc_data/star_at_core_collapse.data",
                "binary_info_at_cc_filename": "cc_data/binary_at_core_collapse.data",
                "add_kick_id_as_suffix": False,
                "termination_codes_directory": "termination_codes",
            },
        }

        self.namelists_for_mesastar = {
            "star_job": {
                "read_extra_star_job_inlist1": True,
                "extra_star_job_inlist1_name": "#{template}/inlist_project",
            },
            "eos": {
                "read_extra_eos_inlist1": True,
                "extra_eos_inlist1_name": "#{template}/inlist_project",
            },
            "kap": {
                "read_extra_kap_inlist1": True,
                "extra_kap_inlist1_name": "#{template}/inlist_project",
            },
            "controls": {
                "read_extra_controls_inlist1": True,
                "extra_controls_inlist1_name": "#{template}/inlist_project",
            },
            "pgstar": {
                "read_extra_pgstar_inlist1": True,
                "extra_pgstar_inlist1_name": "#{template}/inlist_project",
            },
        }

def namelist_defaults(fname: Union[str, Path]) -> Dict[Any, Any]:
    """Get default options for a certain namelist used by MESA

    Parameters
    ----------
    fname : `str / Path`
        Name of the file with the namelist options

    Returns
    -------
    options : `dict`
        Dictionary with options for a MESA namelist
    """

    # always use Path for files
    if isinstance(fname, str):
        fname = Path(fname)

    if not fname.is_file():
        raise FileNotFoundError(f"`{fname}` not found")

    with open(fname) as f:
        lines = [line.strip() for line in f.readlines() if len(line) > 0]

    options = OrderedDict()
    for k, line in enumerate(lines):
        if not line.startswith("!") and "=" in line:
            line = line.split("!", 1)[0]

            if len(line.split("=")) < 2:
                raise ValueError(f"error in line: {line}")
            elif len(line.split("=")) > 2:  # there is just one string in the defaults with two '='
                name, lval, rval = line.split("=")
                value = f"{lval}={rval}"
            else:
                name, value, *extra_words = line.split("=")

            options[name.strip()] = parse_fortran_value_to_python(value=value.strip())

    return options

def get_mesa_defaults(mesa_dir: Union[str, Path] = "") -> Dict[Any, Any]:
    """Obtain all default options of every namelist used by MESA

    Parameters
    ----------
    mesa_dir : `str / Path`
        Path to MESA source directory. also found in shell as MESA_DIR environment variable

    Returns
    -------
    MESADefaults : `dict`
        Dictionary with all MESA defaults
    """

    # if mesa_dir is empty, try to get MESA_DIR from environment variable
    if mesa_dir == "":
        if os.environ.get("MESA_DIR") is None:
            raise ValueError(
                "`mesa_dir` cannot be empty. also it was not find in the environment variable list"
            )

    # use pathlib
    if isinstance(mesa_dir, str):
        mesa_dir = Path(mesa_dir)

    # load namelists for each MESA module
    mesaNamelists = MESANamelists()

    MESADefaults = dict()
    if "bin2dco" in str(mesa_dir):
        fname = mesa_dir / "src/bin2dco_controls.defaults"
        MESADefaults["bin2dco_controls"] = namelist_defaults(fname=fname)

    else:
        for namelist in mesaNamelists.star_namelists:
            # check for proper directory name
            directory_name = "star"
            if "eos" in namelist:
                directory_name = "eos"
            if "kap" in namelist:
                directory_name = "kap"

            fname = mesa_dir / f"{directory_name}/defaults/{namelist}.defaults"
            MESADefaults[namelist] = namelist_defaults(fname=fname)

        for namelist in mesaNamelists.binary_namelists:
            directory_name = "binary"
            fname = mesa_dir / f"{directory_name}/defaults/{namelist}.defaults"
            MESADefaults[namelist] = namelist_defaults(fname=fname)

    return MESADefaults


from django.urls import path
from . import views
from .views import index, ProjectCreateView, ProjectList, ProfileView

app_name = 'teamupweb'

urlpatterns = [
    path('', index.as_view(), name='index'),
    path('test/', views.test, name='test'),
    path('projectList/', ProjectList.as_view(), name='projectlist'),
    path('postproject/', ProjectCreateView.as_view(), name='postproject'),
    path('Detail/<int:pk>/', views.ProjectDetail, name='detail'),
    #path('<int:pk>/delete/', views.Pro, name='projectdelete'),
    path('profile/<str:username>/', ProfileView.as_view(), name='profile'),
    path('help/', views.Help, name='help'),
]


import MeCab, re

data = "私のお気に入りの楽曲は『フワリ、コロリ、カラン、コロン』です。"

m = MeCab.Tagger().parse(data)
lines = m.split("\n")
items = (re.split('[\t,]', line) for line in lines)

print(m)
for i in items:
    print(i)


from ast import literal_eval
from typing import Any, List, Optional, Tuple, Union

# External packages.
from dotenv import dotenv_values
from pandas import DataFrame, to_datetime
import requests
try:
    import xlwings
    from xlwings.utils import rgb_to_int
except ImportError:
    # FIXME: Work on alternatives as xlwings doesn't work in App Engine.
    pass

# Internal packages.
from ..utils.utils import snake_case

def format_values(data: Union[list, dict], columns: List[str]) -> List[dict]:
    """Format response data by given columns. Handles a list or dictionary of data.
    Args:
        data (list,dict): A list of values or a dictionary of values.
        columns (list): A list of column names used to get values from the data.
    Returns:
        (list): Returns a list of items.
    """
    items = []
    try:
        for item in data:
            values = []
            for column in columns:
                values.append(item.get(column))
            items.append(values)
    except AttributeError:
        values = []
        for column in columns:
            values.append(data.get(column))
        items = [values]
    return items

def get_data_block(sheet: Any, coords: str, expand: Optional[str] = None) -> dict:
    """Get a data block.
    Args:
        sheet (Sheet): The worksheet containing the data block.
        coords (str): The inclusive coordinates of the data block.
        expand (str): Optionally expand the range of values.
    Returns
        (dict): A dictionary of the data in the data block.
    """
    data = {}
    values = sheet.range(coords).options(expand=expand).value
    for item in values:
        key = snake_case(item[0])
        value = item[1]
        data[key] = value
    return data

def get_data_model(worksheet: Any, config: dict, model_type: str, ids: List[str]) -> Any:
    """Get a specific data model from the Cannlytics API.
    Args:
        worksheet (Worksheet): An xlwings Excel worksheet instance.
        config (dict): A dictionary of user configuration.
        model_type (str): The data model name.
        ids (list): Specific IDs to retrieve from the API.
    Returns:
        (HTTPResponse): An HTTP response from the Cannlytics API.
    """
    base = config['api_url']
    org_id = worksheet.range(config['org_id_cell']).value
    env_variables = dotenv_values(config['env_path'])
    api_key = env_variables['CANNLYTICS_API_KEY']
    headers = {
        'Authorization': 'Bearer %s' % api_key,
        'Content-type': 'application/json',
    }
    if len(ids) == 1:
        url = f'{base}/{model_type}/{ids[0]}?organization_id={org_id}'
    else:
        url = f'{base}/{model_type}?organization_id={org_id}&items={str(ids)}'
    response = requests.get(url, headers=headers)
    return response

def increment_row(coords: str) -> str:
    """Increment a row given its starting coordinates.
    Args:
        coords (str):
    Returns:
        (str): The incremented row coordinates.
    """
    column = ''.join([i for i in coords if not i.isdigit()])
    seq_type = type(coords)
    row = int(seq_type().join(filter(seq_type.isdigit, coords))) + 1
    return column + str(row)

def import_worksheet(
        filename: str,
        sheetname: str,
        range_start: Optional[str] = 'A1',
    ) -> List[dict]:
    """Read the data from a given worksheet using xlwings.
    Args:
        filename (str): The name of the Excel workbook to read.
        sheetname (str): The name of the worksheet to import.
        range_start (str): Optional starting cell.
    Returns:
        list(dict): A list of dictionaries.
    """
    app = xlwings.App(visible=False)
    book = xlwings.Book(filename)
    sheet = book.sheets(sheetname)
    excel_data = sheet.range(range_start).expand('table').value
    keys = [snake_case(key) for key in excel_data[0]]
    data = [dict(zip(keys, values)) for values in excel_data[1:]]
    book.close()
    app.quit()
    return data

@xlwings.sub
def import_worksheet_data(model_type: str):
    """A function called from Excel to import data by IDs in the worksheet
    from Firestore into the Excel workbook.
    Args:
        model_type (str): The data model at hand.
    """

    # Initialize the workbook.
    worksheet, config = initialize_workbook()
    status_cell = config['status_cell']
    show_status_message(
        worksheet,
        coords=status_cell,
        message='Importing %s data...' % model_type,
        background=config['success_color'],
    )

    # Read the IDs.
    id_cell = increment_row(config['table_cell'])
    ids = worksheet.range(id_cell).options(expand='down', ndim=1).value

    # Get the worksheet columns.
    columns = worksheet.range(config['table_cell']).options(expand='right', ndim=1).value
    columns = [snake_case(x) for x in columns]

    # Get data using model type and ID through the API.
    response = get_data_model(worksheet, config, model_type, ids)
    if response.status_code != 200:
        show_status_message(
            worksheet,
            coords=status_cell,
            message='Error importing data.',
            background=config['error_color']
        )
        return

    # Format the values.
    try:
        data = response.json()['data']
        items = format_values(data, columns)
    except TypeError:
        show_status_message(
            worksheet,
            coords=status_cell,
            message='No data found.',
            background=config['error_color']
        )
        return

    # Insert all rows at the same time.
    worksheet.range(id_cell).value = items

    # Show success status message.
    show_status_message(
        worksheet,
        coords=status_cell,
        message='Imported %i %s.' % (len(ids), model_type),
    )

def initialize_workbook() -> Tuple:
    """Initialize an xlwings workbook and return the config worksheet data.
    Returns:
        (Worksheet): Returns the active worksheet.
        (dict): Returns a dictionary of user configuration.
    """
    book = xlwings.Book.caller()
    worksheet = book.sheets.active
    config_sheet = book.sheets['cannlytics.conf']
    config = get_data_block(config_sheet, 'A1', expand='table')
    return worksheet, config

def read_table_data(worksheet: Any, cell: str) -> dict:
    """Read table data from a worksheet and clean the columns and data.
    Args:
        worksheet (Worksheet): A worksheet containing the table data.
        cell (str): The cell range of the table.
    Returns:
        (dict): Returns the data in the worksheet table as a dictionary.
    """
    table = worksheet.range(cell)
    data = table.options(DataFrame, index=False, expand='table').value
    data.columns = list(map(snake_case, data.columns))
    for column in data.columns:
        if column.endswith('_at'):
            try:
                data[column] = to_datetime(data[column]).dt.strftime('%Y-%m-%dT%H:%M%:%SZ')
            except:
                pass
    return data.fillna('')

@xlwings.sub
def upload_worksheet_data(model_type):
    """A function called from Excel to import data by IDs in the worksheet
    from Firestore into the Excel workbook."""

    # Initialize the workbook.
    worksheet, config = initialize_workbook()
    status_cell = config['status_cell']
    show_status_message(
        worksheet,
        coords=status_cell,
        message='Uploading %s data...' % model_type,
        background=config['success_color'],
    )

    # Read the table data, cleaning the column names.
    data = read_table_data(worksheet, config['table_cell'])

    # Determine the model type and the organization.
    org_id = worksheet.range(config['org_id_cell']).value
    model_singular = data.columns[0].replace('_id', '')
    if not org_id:
        show_status_message(
            worksheet,
            coords=status_cell,
            message='Organization ID required.',
            background=config['error_color']
        )
        return

    # Get Cannlytics API key from .env using env_path in config.
    env_variables = dotenv_values(config['env_path'])
    api_key = env_variables['CANNLYTICS_API_KEY']

    # TODO: Split this into a separate function.
    # Upload data using model type, ID, and data through the API.
    headers = {
        'Authorization': 'Bearer %s' % api_key,
        'Content-type': 'application/json',
    }
    base = config['api_url']
    for _, row in data.iterrows():
        # Optional: Clean based on data model fields.
        json = row.to_dict()
        doc_id = json[f'{model_singular}_id']
        if not doc_id:
            continue
        url = f'{base}/{model_type}?organization_id={org_id}'
        response = requests.post(url, json=json, headers=headers)
        if response.status_code == 200:
            show_status_message(
                worksheet,
                coords=status_cell,
                message='Uploaded %s' % doc_id,
            )
        else:
            show_status_message(
                worksheet,
                coords=status_cell,
                message='Error uploading %s. Check your organization, internet connection and API key.' % doc_id, # pylint:disable=line-too-long
                background=config['error_color']
            )
            return

    # Show success status message.
    show_status_message(
        worksheet,
        coords=status_cell,
        message='Uploaded %i %s.' % (len(data), model_type),
    )

def show_status_message(sheet, coords, message, background=None, color=None):
    """Show a status message in an Excel spreadsheet.
    Args:
        sheet (Sheet): The sheet where the status message will be written.
        coords (str): The location of the status message.
        message (str): A status message to write to Excel.
        background (tuple): Optional background color.
        color (tuple): Optional font color.
    """
    sheet.range(coords).value = message
    if background:
        sheet.range(coords).color = literal_eval(background)
    if color:
        sheet.range(coords).api.Font.Color = rgb_to_int(literal_eval(color))

# openpyxl and pandas methods for reading data.

# def get_worksheet_headers(sheet):
#     """Get the headres of a worksheet.
#     Args:
#         sheet (Worksheet): An openpyx; Excel file object.
#     Returns:
#         headers (list): A list of header strings.
#     """
#     headers = []
#     for cell in sheet[1]:
#         headers.append(snake_case(cell.value))
#     return headers

# def get_worksheet_data(sheet, headers):
#     """Get the data of a worksheet.
#     Args:
#         sheet (Worksheet): An openpyx; Excel file object.
#         headres (list): A list of headers to map the values.
#     Returns:
#         list(dict): A list of dictionaries.
#     """
#     data = []
#     for row in sheet.iter_rows(min_row=2):
#         values = {}
#         for key, cell in zip(headers, row):
#             values[key] = cell.value
#         data.append(values)
#     return data

# def read_worksheet(path, filename='Upload'):
#     """Read the imported data, iterating over the rows and
#     getting value from each cell in row.
#     Args:
#         path (str or InMemoryFile): An Excel workbook to read.
#         filename (str): The name of the worksheet to upload.
#     Returns:
#         (DataFrame): A Pandas DataFrame of the results.
#     """
#     # try:
#     #     workbook = openpyxl.load_workbook(path, data_only=True)
#     #     sheet = workbook.get_sheet_by_name(filename)
#     #     headers = get_worksheet_headers(sheet)
#     #     return pd.DataFrame(get_worksheet_data(sheet, headers))
#     # except:
#     data = pd.read_csv(path)
#     data.columns = [snake_case(x) for x in data.columns]
#     return data


import tweepy
import time
import logging

class TweetsFetcher(object):

    def __init__(self, auth, user, process_name):
        """
        Class constructor
        :param auth: Tweepy Auth object
        :param user: User to search
        :param process_name: Name of the process to create
        """
        self.api = tweepy.API(auth)
        self.process_name = process_name
        try:
            self.api.get_user(user)
        except Exception:
            raise Exception('User does not exists')
        self.user_cursor = tweepy.Cursor(self.api.user_timeline, screen_name=user)

    def get_tweets(self):
        """
        Generator used to retrieve tweets from the user
        :return:
        """
        while True:
            try:
                yield self.user_cursor.pages().next()
            except tweepy.RateLimitError:
                logging.info("[%s] Timeout Reached, Sleep for 15 minutes before restart" % self.process_name)
                time.sleep(15 * 60)
                logging.info("[%s] Waking up. Try again" % self.process_name)
            except StopIteration:
                logging.info("[%s] Stop Iteration, process complete" % self.process_name)
                break
            except Exception as e:
                logging.info("[%s] Generic Error, restart in 60 seconds: %s" % (self.process_name, e))
                time.sleep(60)


import configparser
from collections import OrderedDict
import numpy as np
from scipy.integrate import quad
import os
import sys
import io
import re

UNITS = OrderedDict()
UNITS['T'] = 'K'                    # temperature
UNITS['Cv'] = 'kB'                  # heat capacity in kB
UNITS['Kappa_min'] = 'W/(m*K)'      # minimum limit kappa under tau=pi/omega
UNITS['Kappa_min_A'] = 'W/(m*K)'    # contribution of acoustic branches
UNITS['Kappa_min_O'] = 'W/(m*K)'    # contribution of optical branches
UNITS['vs'] = 'km/s'                # average sound velocity, vs = (3/(2/vT**3+1/vL**3))**(1/3)
UNITS['Tau_min'] = 'ps'             # Kappa_min/(1/3*Cv*vs^2)
UNITS['MFP_min'] = 'A'              # Kappa_min/(1/3*Cv*vs)
UNITS['Omega_a_T'] = 'rad/ps'       # Cut-off angular frequency of TA
UNITS['Omega_a_L'] = 'rad/ps'       # Cut-off angular frequency of LA
UNITS['T_a_T'] = 'K'                # Debye temperature of TA
UNITS['T_a_L'] = 'K'                # Debye temperature of LA

def _kernel(x):
    '''
    x^2*exp(x)/(exp(x)-1)^2
    '''
    p = np.power(x, 2) * np.exp(-x)
    q = np.power(1-np.exp(-x), 2)
    v = np.divide(p, q,
                  out=np.ones_like(p+q),
                  where=(np.absolute(q)>1E-4))
    return v

def _core_cv(x):
    '''
    3*t^2
    '''
    v = 3 * x**2
    return v

def _core_debye(x):
    '''
    3*t
    '''
    v = 3 * x
    return v

def _core_bvk(x):
    '''
    3 * x^2 * (cos(pi/2 * x))^2 / sin(pi/2 * t)
    '''
    p = 3 * x**2 * np.cos(np.pi/2 * x)**2
    q = np.sin(np.pi/2 * x)
    v = np.divide(p, q,
                  out=np.zeros_like(p+q),
                  where=(np.absolute(q)>1E-4))
    return v

def _quad_t(func, Tr):
    '''
    Calculate integral in reduced k-space with an additional parameter
    '''
    def itg(Trx):
        return quad(func, 0, 1, args=(Trx,))[0]
    itg_v = np.vectorize(itg)
    return itg_v(Tr)

def Debye(vT, vL, Natom, Vcell, T):
    '''
    Calculate Debye-Cahill minimum limit to thermal conductivity.
    All  parameters in common units.
    '''

    # define constants for matching common units
    kB = 13.80649
    hb = 105.457182

    # define some factors and integrals
    Vatom = Vcell/Natom     # [A^3]
    Kc = np.power(6*np.pi*np.pi/Vatom, 1/3)  # [1/A]
    WcT = vT * Kc * 10       # [km/s * 1/A] = [10 rad/ps] to [rad/ps]
    WcL = vL * Kc * 10
    TaT = hb/kB * WcT   # [K]
    TaL = hb/kB * WcL
    vs = (3/(2/vT**3+1/vL**3))**(1/3)
    factor_cv = 3       # [kB]
    factor_kmT = (kB*vT*vT)/Vatom * np.pi/WcT  # [W/m.K]
    factor_kmL = (kB*vL*vL)/Vatom * np.pi/WcL
    # factor_tmT = np.pi/WcT      # [ps]
    # factor_tmL = np.pi/WcL
    # factor_mfp = np.pi/Kc       # [A]

    # calculate
    out = dict()
    if isinstance(T, float) and (T == float('inf')):
        # kernel --> 1
        # factor_itg = quad(_core_debye, 0, 1)[0]
        factor_itg = 3/2
        out['T'] = T
        out['Cv'] = factor_cv
        out['Kappa_min'] = (2*factor_kmT+factor_kmL)/3 * factor_itg
        out['Omega_a_T'] = WcT
        out['Omega_a_L'] = WcL
        out['T_a_T'] = TaT
        out['T_a_L'] = TaL
        out['vs'] = vs
    else:
        T = np.array(T)
        f_cv = lambda t, u: _core_cv(t)*_kernel(u*t)
        f_km = lambda t, u: _core_debye(t)*_kernel(u*t)
        CrT = _quad_t(f_cv, TaT/T)
        CrL = _quad_t(f_cv, TaL/T)
        KMrT = _quad_t(f_km, TaT/T)
        KMrL = _quad_t(f_km, TaL/T)
        out['T'] = T
        out['Cv'] = factor_cv * (2*CrT+CrL)/3
        out['Kappa_min'] = (2*factor_kmT*KMrT+factor_kmL*KMrL)/3
        out['Omega_a_T'] = WcT*np.ones_like(T)
        out['Omega_a_L'] = WcL*np.ones_like(T)
        out['T_a_T'] = TaT*np.ones_like(T)
        out['T_a_L'] = TaL*np.ones_like(T)
        out['vs'] = vs*np.ones_like(T)

    out['Kappa_min_A'] = out['Kappa_min']
    out['Kappa_min_O'] = 0 * out['Kappa_min']
    out['Tau_min'] = out['Kappa_min']/(1/3 * out['Cv']*kB/Vatom * out['vs']**2)     # [ps]
    out['MFP_min'] = out['Tau_min'] * out['vs'] * 10 # [ps*km/s] = [ps*nm/ps] = [nm] to [A]
    return out

def BvK(vT, vL, Natom, Vcell, T):
    '''
    Calculate BvK-Cahill minimum limit to thermal conductivity.
    All  parameters in common units.
    '''

    # define constants for matching common units
    kB = 13.80649
    hb = 105.457182

    # define some factors and integrals
    Vatom = Vcell/Natom     # [A^3]
    Kc = np.power(6*np.pi*np.pi/Vatom, 1/3)  # [1/A]
    WcT = 2/np.pi * vT * Kc * 10    # [km/s * 1/A] = [10 rad/ps] to [rad/ps]
    WcL = 2/np.pi * vL * Kc * 10
    TaT = hb/kB * WcT   # [K]
    TaL = hb/kB * WcL
    factor_cv = 3       # [kB]
    vs = (3/(2/vT**3+1/vL**3))**(1/3)
    factor_kmT = (kB*vT*vT)/Vatom * np.pi/WcT  # [W/m.K]
    factor_kmL = (kB*vL*vL)/Vatom * np.pi/WcL
    # factor_tmT = np.pi/WcT      # [ps]
    # factor_tmL = np.pi/WcL
    # factor_mfp = (np.pi/Kc) * np.pi/2   # [A]

    # calculate
    out = dict()
    if isinstance(T, float) and (T == float('inf')):
        # kernel --> 1
        # factor_itg = quad(_core_bvk, 0, 1)[0]
        factor_itg = 0.31456063126172384
        out['T'] = T
        out['Cv'] = factor_cv
        out['Kappa_min'] = (2*factor_kmT+factor_kmL)/3 * factor_itg
        out['Omega_a_T'] = WcT
        out['Omega_a_L'] = WcL
        out['T_a_T'] = TaT
        out['T_a_L'] = TaL
        out['vs'] = vs
    else:
        T = np.array(T)
        f_cv = lambda t, u: _core_cv(t)*_kernel(u*np.sin(np.pi/2 * t))
        f_km = lambda t, u: _core_bvk(t)*_kernel(u*np.sin(np.pi/2 * t))
        CrT = _quad_t(f_cv, TaT/T)
        CrL = _quad_t(f_cv, TaL/T)
        KMrT = _quad_t(f_km, TaT/T)
        KMrL = _quad_t(f_km, TaL/T)
        out['T'] = T
        out['Cv'] = factor_cv * (2*CrT+CrL)/3
        out['Kappa_min'] = (2*factor_kmT*KMrT+factor_kmL*KMrL)/3
        out['Omega_a_T'] = WcT*np.ones_like(T)
        out['Omega_a_L'] = WcL*np.ones_like(T)
        out['T_a_T'] = TaT*np.ones_like(T)
        out['T_a_L'] = TaL*np.ones_like(T)
        out['vs'] = vs*np.ones_like(T)

    out['Kappa_min_A'] = out['Kappa_min']
    out['Kappa_min_O'] = 0 * out['Kappa_min']
    out['Tau_min'] = out['Kappa_min']/(1/3 * out['Cv']*kB/Vatom * out['vs']**2)     # [ps]
    out['MFP_min'] = out['Tau_min'] * out['vs'] * 10 # [ps*km/s] = [ps*nm/ps] = [nm] to [A]
    return out

def Pei(vT, vL, Natom, Vcell, T):
    '''
    Calculate Pei-Cahill minimum limit to thermal conductivity.
    All  parameters in common units.
    '''

    vs = (3/(2/vT**3+1/vL**3))**(1/3)
    out = BvK(vT=vs,
              vL=vs,
              Natom=1,
              Vcell=Vcell,
              T=T)

    # same as BvK model when Natom = 1
    if Natom == 1:
        return out
    # else:
    #     raise NotImplementedError('Only support Natom = 1')

    # for Natom != 1
    # define constants for matching common units
    kB = 13.80649
    hb = 105.457182

    # define some factors and integrals
    Vatom = Vcell/Natom     # [A^3]
    Kc = np.power(6*np.pi*np.pi/Vatom, 1/3)  # [1/A], Kc ~ Vatom, Kcc ~ Vcell
    Wc = 2/np.pi * vs * Kc * 10     # [km/s * 1/A] = [10 rad/ps] to [rad/ps]
    To = hb/kB * Wc     # [K]
    factor_cv = 3       # [kB]
    factor_km = (kB*vs*vs)/Vcell * np.pi/Wc  # [W/m.K], here Vcell=Natom*Natom
    # factor_tm = np.pi/Wc      # [ps]
    # factor_mfp = (np.pi/Kc) * np.pi/2   # [A]

    # calculate
    kir = [(np.power(i/Natom, 1/3)+np.power((i+1)/Natom, 1/3))/2 for i in range(1,round(Natom))]
    if isinstance(T, float) and (T == float('inf')):
        kir = np.array(kir)
        wr = np.sin(np.pi/2 * kir)
        vr = np.cos(np.pi/2 * kir)
        km_O = factor_km * vr**2 / wr
        out['Kappa_min_O'] = np.sum(km_O)
        out['Kappa_min'] = out['Kappa_min_A'] + out['Kappa_min_O']
    else:
        T = out['T']
        shp = [-1,]+[1 for _ in range(T.ndim)]
        kir = np.array(kir).reshape(shp)
        wr = np.sin(np.pi/2 * kir)
        vr = np.cos(np.pi/2 * kir)
        km_O = factor_km * vr**2 / wr * _kernel(To/T*wr)
        cv_O = factor_cv * _kernel(To/T*wr)
        out['Kappa_min_O'] = np.sum(km_O, axis=0)
        out['Kappa_min'] = out['Kappa_min_A'] + out['Kappa_min_O']
        out['Cv'] = (out['Cv']+np.sum(cv_O, axis=0))/Natom

    out['Tau_min'] = out['Kappa_min']/(1/3 * out['Cv']*kB/Vatom * out['vs']**2)     # [ps]
    out['MFP_min'] = out['Tau_min'] * out['vs'] * 10 # [ps*km/s] = [ps*nm/ps] = [nm] to [A]
    return out

def fileparser(filename, ktypes=None):
    '''
    Parser the configuration file and return a ConfigParser() object.
    '''
    # read config file
    config = configparser.ConfigParser(inline_comment_prefixes=('#',))
    config.SECTCRE = re.compile(r"\[ *(?P<header>[^]]+?) *\]")  # ignore blanks in section name
    config.read(filename)

    # optional: refine config file
    if ktypes is None:
        return config
    else:
        config2 = configparser.ConfigParser()
        for sect in config.sections():
            for ktype in ktypes:
                if sect.lower() == ktype.lower():
                    config2[ktype] = config[sect]
        return config2

def _section_parser(config, modeltype):
    '''
    Parser parameters from a specific model-section.
    '''

    # TODO: config = fileparser(config) if is string else config
    # keys = ['vT', 'vL', 'Natom', 'Vcell', 'T']

    paras = dict()

    # parser float
    for key in ['vT', 'vL', 'Natom', 'Vcell']:
        paras[key] = config.getfloat(modeltype, key)

    # parser temperature
    valueT = config[modeltype]['T']
    isStep, valueT = _sequence_parser(valueT, func=float, defaultstep=1)
    if isStep:
        start, step, end = valueT
        valueT = np.arange(start, end+0.01, step)

    # check type and return
    if len(valueT) == 0:
        raise ValueError('Failed to read temperature [T].')
    elif len(valueT) == 1:
        isSingle = True
        paras['T'] = valueT[0]
    else:
        isSingle = False
        paras['T'] = valueT
    return isSingle, paras

def _sequence_parser(value, func=float, defaultstep=1):
    '''
    Parser a sequence or slice from a string.
    '''

    if ':' in value:
        # sequence with step
        values = value.strip().split(':')
        if func is not None:
            values = list(map(func, values))
        if len(values) == 2:
            start, end = values
            step = defaultstep
        elif len(values) == 3:
            start, step, end = values
        else:
            raise ValueError('Failed to parser the sequence data.')
        isStep = True
        return isStep, (start, step, end)
    else:
        # any sequence
        values = value.strip().split()
        if func is not None:
            values = map(func, values)
        isStep = False
        return isStep, list(values)

def _savedat_to_file(filename, datas, keys=None,
                     fmt='%.6f', header='auto',
                     isSingle=None):
    '''
    Save output of model calculation to a file.
    Default header(='auto') is Properties & Units, while is ignored if it is None.
    '''

    # TODO: fix isSingle check bug if datas['Kappa_min'] not a ndarray

    # check default
    if keys is None:
        keys = UNITS.keys()
    if isSingle is None:
        if datas['Kappa_min'].ndim == 0:
            isSingle = True
        else:
            isSingle = False
    if header.lower().startswith('auto'):
        props = []
        units = []
        for prop in keys:
            unit = UNITS[prop]
            Nmax = max(map(len, [prop, unit]))
            props.append(prop.rjust(Nmax))
            units.append(unit.rjust(Nmax))
        propsline = ', '.join(props)
        unitsline = ', '.join(units)
        header = '\n'.join([propsline, unitsline])

    # access output datas
    out = [datas[key] for key in keys]
    if isSingle:
        out = np.atleast_2d(out)
    else:
        out = np.vstack(out).T
    s = io.StringIO()
    np.savetxt(s, out, fmt=fmt, header=header)
    rst = s.getvalue().replace('\ninf', '\ninf       ')
    with open(filename, 'w') as f:
        f.write(rst)

def execute(filename=None, toFile=True, hasReturn=False):
    '''
    Read configuration file and do calculation.
    '''

    # TODO: allow muilt-output result when muilt-model

    # access filename of config
    ktypes = ['Debye', 'BvK', 'Pei']
    if filename is None:
        # auto-detect filename
        prefix = 'KAPPAMIN'
        suffix = ['cfg', 'ini', 'txt']
        for fn in ['{}.{}'.format(prefix, suf) for suf in suffix]:
            if os.path.exists(fn):
                filename = fn
                break
        else:
            raise FileNotFoundError('Failed to find configuration file')
    config = fileparser(filename, ktypes)

    # parser config file and calculate
    if 'Debye' in config.sections():
        fileout = 'Kappamin_Debye.dat'
        isSingle, paras = _section_parser(config, 'Debye')
        out = Debye(**paras)
    elif 'BvK' in config.sections():
        fileout = 'Kappamin_BvK.dat'
        isSingle, paras = _section_parser(config, 'BvK')
        out = BvK(**paras)
    elif 'Pei' in config.sections():
        fileout = 'Kappamin_Pei.dat'
        isSingle, paras = _section_parser(config, 'Pei')
        out = Pei(**paras)
    else:
        raise ValueError('Unknown method.(Valid: %s)', ', '.join(ktypes))

    # output and(or) save to file
    if hasReturn:
        return out
    if toFile:
        _savedat_to_file(fileout, out, isSingle=isSingle)

if __name__ == '__main__':
    if len(sys.argv) > 1:
        filename = sys.argv[1]
    else:
        filename = None
    execute(filename)


from scipy import random
import numpy as np
import matplotlib.pyplot as plt

i = 4
B = 6
R = 5
a1 = -R
b1 = R
a2 = 0
b2 = np.pi
N = 1000

def f(x):
    return 1
def g(x):
    return np.sin(x)

array1 = np.zeros(N)
array2 = np.zeros(N)

for i in range(N):
    array1[i] = random.uniform(a1, b1)
    array2[i] = random.uniform(a2, b2)

integral_straight = 0.0
integral_semicirc = 0.0

for i in array1:
    integral_straight += f(i)

for i in array2:
    integral_semicirc += g(i)

straight = ((b1-a1)/float(N))*integral_straight
semicirc = ((b2-a2)/float(N))*integral_semicirc

f_net = -i*B*straight+i*B*R*semicirc

print('The_net_force is %0.06f'%f_net, 'N.')


from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from database_setup import User, Base, CatalogItem, Categories

engine = create_engine('sqlite:///catalogwithusers.db')
# Bind the engine to the metadata of the Base class so that the
# declaratives can be accessed through a DBSession instance
Base.metadata.bind = engine

DBSession = sessionmaker(bind=engine)
# A DBSession() instance establishes all conversations with the database
# and represents a "staging zone" for all the objects loaded into the
# database session object. Any change made against the objects in the
# session won't be persisted into the database until you call
# session.commit(). If you're not happy about the changes, you can
# revert all of them back to the last commit by calling
# session.rollback()
session = DBSession()

User1 = User(name="Robo Barista", email="tinnyTim@udacity.com",
             picture='https://pbs.twimg.com/profile_images/2671170543/18debd694829ed78203a5a36dd364160_400x400.png')
session.add(User1)
session.commit()

User2 = User(name="Meya G", email="mg@udacity.com",
             picture='https://plus.google.com/u/1/photos/114888950754511941808/albums/profile/6335022156608751730')
session.add(User2)
session.commit()

# create a category
makeup = Categories(user_id=1, name="Makeup")

session.add(makeup)
session.commit()

skin = Categories(user_id=1, name="Skin Care")

session.add(skin)
session.commit()

hair = Categories(user_id=1, name="Hair care")

session.add(hair)
session.commit()

item2 = CatalogItem(user_id=1, name="Too Faced Mascara", description="Too Faced: Better than sex mascara",
                     price="$23.00", category=makeup)

session.add(item2)
session.commit()

item2 = CatalogItem(user_id=1, name="NARS Blush", description="Shimmery blush",
                     price="$24.00", category=makeup)

session.add(item2)
session.commit()

item2 = CatalogItem(user_id=1, name="Clinique", description="Moisture surge extended",
                     price="$29.99", category=skin)

session.add(item2)
session.commit()

item2 = CatalogItem(user_id=1, name="Tatcha", description="The water cream",
                     price="$68.00", category=skin)

session.add(item2)
session.commit()

item2 = CatalogItem(user_id=1, name="Alterna Haircare", description="10-in-1 complete correction",
                     price="$68.00", category=hair)

session.add(item2)
session.commit()

item2 = CatalogItem(user_id=1, name="Bumble and Bumble oil", description="Invisible oil primer",
                     price="$68.00", category=hair)

session.add(item2)
session.commit()


from PyQt5 import QtCore, QtGui, QtWidgets
import os
from PyPDF3 import PdfFileReader, PdfFileMerger

def checkEncryption(filename):
    obj = PdfFileReader(filename)
    global trueFalse
    trueFalse = obj.getIsEncrypted()
    return trueFalse

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(506, 427)
        MainWindow.setMinimumSize(QtCore.QSize(506, 427))
        MainWindow.setMaximumSize(QtCore.QSize(506, 427))
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(10, 10, 491, 51))
        self.label.setStyleSheet("QLabel{font-size:40px;font-family:\'Times New Roman\', cursive;color:white;background-color:#000;border-radius:20px;}")
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget,clicked=self.extractFromFolder)
        self.pushButton.setGeometry(QtCore.QRect(10, 80, 241, 51))
        self.pushButton.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.pushButton.setStyleSheet("QPushButton{font-size:20px;font-family:\'Times New Roman\', cursive;color:white;background-color:#000;border-radius:20px;}QPushButton:hover{background-color:crimson;color:gold;font-weight:bold;}")
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget,clicked=self.selectFiles)
        self.pushButton_2.setGeometry(QtCore.QRect(270, 80, 231, 51))
        self.pushButton_2.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.pushButton_2.setStyleSheet("QPushButton{font-size:20px;font-family:\'Times New Roman\', cursive;color:white;background-color:#000;border-radius:20px;}QPushButton:hover{background-color:crimson;color:gold;font-weight:bold;}")
        self.pushButton_2.setObjectName("pushButton_2")
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setGeometry(QtCore.QRect(10, 150, 221, 201))
        self.groupBox.setStyleSheet("border:2px solid #000;")
        self.groupBox.setObjectName("groupBox")
        self.listWidget = QtWidgets.QListWidget(self.groupBox)
        self.listWidget.setGeometry(QtCore.QRect(10, 20, 201, 171))
        self.listWidget.setStyleSheet("border:0;")
        self.listWidget.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.listWidget.setObjectName("listWidget")
        self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_2.setGeometry(QtCore.QRect(290, 150, 211, 201))
        self.groupBox_2.setStyleSheet("border:2px solid #000;")
        self.groupBox_2.setObjectName("groupBox_2")
        self.listWidget_2 = QtWidgets.QListWidget(self.groupBox_2)
        self.listWidget_2.setGeometry(QtCore.QRect(10, 20, 191, 171))
        self.listWidget_2.setStyleSheet("border:0;")
        self.listWidget_2.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.listWidget_2.setObjectName("listWidget_2")
        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget,clicked=self.mergePDFFile)
        self.pushButton_3.setGeometry(QtCore.QRect(10, 360, 491, 51))
        self.pushButton_3.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.pushButton_3.setStyleSheet("QPushButton{font-size:20px;font-family:\'Times New Roman\', cursive;color:white;background-color:#000;border-radius:20px;}QPushButton:hover{background-color:crimson;color:gold;font-weight:bold;}")
        self.pushButton_3.setObjectName("pushButton_3")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(240, 170, 41, 41))
        self.label_2.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.label_2.setText("")
        self.label_2.setPixmap(QtGui.QPixmap("transferFileIcon.png"))
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(240, 300, 41, 41))
        self.label_3.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.label_3.setText("")
        self.label_3.setPixmap(QtGui.QPixmap("backupFileIcon.png"))
        self.label_3.setObjectName("label_3")
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        self.mainPDFDictionary = {}
        self.mergePDFDictionary = {}
        self.label_2.mousePressEvent=self.transferFile
        self.label_3.mousePressEvent=self.reverseTransferFile

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "PDF Merger"))
        self.label.setText(_translate("MainWindow", "PDF MERGER"))
        self.pushButton.setText(_translate("MainWindow", "Select folder"))
        self.pushButton_2.setText(_translate("MainWindow", "Select multiple PDF Files"))
        self.groupBox.setTitle(_translate("MainWindow", "Files Found"))
        self.groupBox_2.setTitle(_translate("MainWindow", "Files to be merged"))
        self.pushButton_3.setText(_translate("MainWindow", "Merge"))

    def selectFiles(self):
        listPdfFiles = QtWidgets.QFileDialog.getOpenFileNames(None,'Select PDF Files','/','PDF (*.pdf)')

        if listPdfFiles[0]!=[]:
            for i in listPdfFiles[0]:
                checkEncryption(i)
                if trueFalse==False:
                    self.listWidget.addItem(i.split('/')[-1])
                    self.mainPDFDictionary[i.split('/')[-1]]=i

    def extractFromFolder(self):
        pdfInsideFolderListPath = QtWidgets.QFileDialog.getExistingDirectory(None,'Select folder which contains PDF','/')

        if pdfInsideFolderListPath!='':
            for i in os.listdir(pdfInsideFolderListPath):
                if i.endswith('.pdf'):
                    checkEncryption(pdfInsideFolderListPath+'/'+str(i))
                    if trueFalse==False:
                        self.listWidget.addItem(str(i))
                        self.mainPDFDictionary[str(i)]=pdfInsideFolderListPath+'/'+str(i)

    def transferFile(self,e):
        try:
            transferFileName = self.listWidget.currentIndex().data()
            curr_selected=self.listWidget.currentRow()
            self.listWidget.takeItem(curr_selected)

            self.listWidget_2.addItem(transferFileName)
            self.mergePDFDictionary[transferFileName]=self.mainPDFDictionary.pop(transferFileName)
        except KeyError:
            pass

    def reverseTransferFile(self,e):
        try:
            transferFileName = self.listWidget_2.currentIndex().data()
            curr_selected=self.listWidget_2.currentRow()
            self.listWidget_2.takeItem(curr_selected)

            self.listWidget.addItem(transferFileName)
            self.mainPDFDictionary[transferFileName]=self.mergePDFDictionary.pop(transferFileName)
        except KeyError:
            pass

    def mergePDFFile(self):
        try:
            if self.mergePDFDictionary!={}:
                saveFileName = QtWidgets.QFileDialog.getSaveFileName(None,'Save As','/','PDF (*.pdf)')
                if saveFileName[0]:
                    merger = PdfFileMerger()
                    [merger.append(self.mergePDFDictionary[i]) for i in self.mergePDFDictionary]
                    merger.write(saveFileName[0])
                    merger.close()

                    self.listWidget.clear()
                    self.listWidget_2.clear()
                    self.mainPDFDictionary={}
                    self.mergePDFDictionary={}
            else:
                QtWidgets.QMessageBox.information(None,'!-Error-!','Oops!, No files found to be merged.',QtWidgets.QMessageBox.StandardButton(1),QtWidgets.QMessageBox.StandardButton(1))
        except KeyError:
            pass

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())


import nltk
from nltk.stem import PorterStemmer
import sys
import xml.etree.ElementTree as ET
import re
import math
from collections import OrderedDict
import operator
import numpy as np
from numpy import linalg as LA
stop_list = None

# function to check only 'letters', ''' and '-'
def checkForCharacters(word):
    if(word.isalpha()):
        return True
    for letter in word:
        if letter in "~`!@#$%^&*()_=+|\\]{[}:;/\"<>,.?1234567890":
            return False
    return True

def main():

    #Managing the arguments
    if str(sys.argv[1]=="--score"):
        if str(sys.argv[2]) == "BM25":
            print("BM25")
            g=1
        elif str(sys.argv[2]) == "OkapiTF":
            print("OkapiTF")
            g=3
        elif str(sys.argv[2]) == "TF-IDF":
            print("TF-IDF")
            g=4
        elif str(sys.argv[2]) == "Jelinek-Mercer":
            print("Jelinek-Mercer")
            g=2
        else:
            print("Invalid Evaluation Method \nsetting to BM25 \nAvailable options are BM25, OkapiTF, TF-IDF and Jelinek-Mercer\n")
            g=1
    else:
        print("Invalid Method \nsetting to BM25 \nAvailable options are BM25, OkapiTF, TF-IDF and Jelinek-Mercer\n")
        g=1

    filename = str(sys.argv[3])

    # filename = "ranking.txt"
    # g=1
    # reading stop-words
    global stop_list
    f2 = open("stoplist.txt", "r")
    if f2.mode == 'r':
        stop_list = f2.read()
        stop_list = nltk.word_tokenize(stop_list)
        f2.close()

    # reading index and term-ids
    f = open("termids.txt", "r", encoding="iso-8859-1")
    f2 = open("term_index.txt", "r")
    if f2.mode == 'r' and f.mode == 'r':
        termIds = f.read()
        termIds = nltk.word_tokenize(termIds)
        lines = f2.readlines()
        f.close()
        f2.close()

    # reading doc-lengths and doc-ids
    f = open("docids.txt", "r")
    f2 = open("docLengths.txt", "r")
    if f2.mode == 'r' and f.mode == 'r':
        documentIds = f.read()
        documentIds = nltk.word_tokenize(documentIds)
        lengths = f2.readlines()
        f.close()
        f2.close()

    # opening ranking.txt to write ranks
    ranking = open(filename, "w+")
    ranking.close()

    # finding average length of docs
    avgLen = 0
    totaldocs = len(lengths)
    for l in range(totaldocs):
        avgLen += int(lengths[l])
    avgLen = avgLen/totaldocs

    # finding total word count in corpus
    wordcount = 0
    for t in lines:
        freq = nltk.word_tokenize(str(t))
        wordcount += int(freq[1])

    # parsing query doc
    tree = ET.parse("topics.xml")
    root = tree.getroot()

    # loop for getting the average length of the queries
    gt = 0
    queryLengthCount = 0
    query_text_array =  []
    for child in root:
        x = root.find("./topic[@number=\""+child.attrib['number']+"\"]/")
        wordList = x.text.lower().rstrip().split(' ')
        text = x.text

        # tokenizing text
        text = nltk.word_tokenize(text)

        ps = PorterStemmer()
        final_text = []

        # adding words to final text if it conatins only 'letters', ''' and '-'
        for word in text:
            if (checkForCharacters(word) and re.match("[A-Za-z]", word)):
                if word not in stop_list:
                    final_text.append(ps.stem(word))
        #print(len(final_text))
        queryLengthCount += len(final_text)
        gt += 1
        query_text_array.append(final_text)

    avgQueryLength = queryLengthCount/gt

    # loop for each query
    for child in root:
        x = root.find("./topic[@number=\""+child.attrib['number']+"\"]/")
        wordList = x.text.lower().rstrip().split(' ')
        print(child.attrib['number'], x.text)
        text = x.text

        # tokenizing text
        text = nltk.word_tokenize(text)

        ps = PorterStemmer()
        final_text = []

        # adding words to final text if it conatins only 'letters', ''' and '-'
        for word in text:
            if (checkForCharacters(word) and re.match("[A-Za-z]", word)):
                if word not in stop_list:
                    final_text.append(ps.stem(word))

        score = {}
        query = list(range(len(final_text)))
        queryLength = len(final_text)
        count = 0
        q_score = []
        d_score = {}
        # loop for each query term
        for term in final_text:

            # in-case the word is found
            if term in termIds:

                # reading the index of the term from file
                term_index = termIds.index(term)

                # reading the term_id
                term_id = int(termIds[term_index - 1])

                # tokenizing the exact line where the term index is placed
                line = lines[term_id]
                docIds = (str(line))
                docIds = [x.split(',') for x in docIds.split(' ')]

                # calculating frequecy of term in all documents
                query[count] = {}
                num = 0
                for a in range(len(docIds)-3):
                    num += int(docIds[a+3][0])
                    if num in query[count]:
                        query[count][num] += 1
                    else:
                        query[count][num] = 1

            # calculating score for each doc
            docfreq = len(query[count])
            for d in query[count]:
                #g = 3
                # Okapi BM25 scoring  str(sys.argv[1]) == "BM25"

                if (g==1):
                    K = 1.2*((1-0.75)+0.75*(int(lengths[d])/avgLen))
                    result = math.log(((totaldocs + 0.5)/docfreq+0.5),2)
                    result *= ((1+1.2)*query[count][d])/(K+query[count][d])
                    result *= ((1+900)*1)/900+1
                    if d in score:
                        score[d] += result
                    else:
                        score[d] = result

                # Jelinik Mercer
                elif(g==2):
                    N = int(lengths[d])
                    myLambda =  0.6
                    freqDoc = query[count][d]
                    freqCorpus = int(docIds[1][0])
                    result = myLambda*(freqDoc/N)
                    result2 = (1-myLambda)*(freqCorpus/wordcount)
                    result3 = result+result2
                    if d in score:
                        score[d] *= result3
                    else:
                        score[d] = result3
                # Okapi TF
                elif(g==3):
                    termFreq = query[count][d]
                    okt_f = termFreq/(termFreq+0.5+(1.5*(int(lengths[d])/avgLen)))
                    if d in d_score:
                        d_score[d][count]= okt_f
                    else:
                        buckets = []
                        for i in range(0,queryLength):
                            buckets.append(0)
                        d_score[d] = buckets
                        d_score[d][count]= okt_f
                #TF-IDF
                elif(g==4):
                    termFreq = query[count][d]
                    okt_f = termFreq/(termFreq+0.5+(1.5*(int(lengths[d])/avgLen)))
                    if d in d_score:
                        d_score[d][count]= okt_f
                    else:
                        buckets = []
                        for i in range(0,queryLength):
                            buckets.append(0)
                        d_score[d] = buckets
                        result = okt_f*math.log(totaldocs/docfreq)
                        d_score[d][count]= okt_f

            count += 1
        if g==3:
            oktf_q = 1/(1+0.5+(1.5*(queryLength/avgQueryLength)))
            for i in range(0,queryLength):
                q_score.append(oktf_q)
            for d_s in d_score:
                key1 = d_s
                oo = d_score[d_s]
                p_d = LA.norm(oo)
                p_q = LA.norm(q_score)
                dtprdct = np.dot(oo,q_score)
                result = dtprdct/(p_d*p_q)
                score[d_s]=result
            #print("ok")
        elif g==4:
            oktf_q = 1/(1+0.5+(1.5*(queryLength/avgQueryLength)))
            for query_word_n in final_text:

                # in-case the word is found
                if query_word_n in termIds:
                    h = 0
                    for q_lines in query_text_array:
                        if query_word_n in q_lines:
                            h+=1

                    q_score.append(oktf_q*math.log(gt/h))
           # print("ok")

            for d_s in d_score:
                key1 = d_s
                oo = d_score[d_s]
                p_d = LA.norm(oo)
                p_q = LA.norm(q_score)
                dtprdct = np.dot(oo,q_score)
                result = dtprdct/(p_d*p_q)
                score[d_s]=result
            print("ok")
        # sorting on the basis of score
        scoring = sorted(
            score.items(), key=operator.itemgetter(1), reverse=True)
        counter = 1
        ranking = open(filename, "a+")

        # printing and writing in ranking.txt
        for s in scoring:
            fileIdentifier_index = documentIds.index(str(s[0]))
            file_identifier = str(documentIds[fileIdentifier_index + 1])
            print(child.attrib['number'] + " 0 " + file_identifier + " " +
                  str(counter) + " " + str(s[1]) + " run1")
            ranking.write(child.attrib['number'] + " 0 " + file_identifier + " " +
                          str(counter) + " " + str(s[1]) + " run1\n")
            counter += 1
        ranking.close()

if __name__ == "__main__":
    main()


import subprocess
import os
import requests

def get_gpu_meta(video_path:str, log_file):

    process = subprocess.Popen(
        [exe, video_path],
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        universal_newlines=True,
    )

    for output in process.stdout:

        if ("gps" in output.strip()) or ("GPS" in output.strip()):
            print(f"{video_path}: gps exists")
            log_file.write(f"{video_path}: gps exists\n")
            global num_have_gps
            num_have_gps += 1
            break

    global cnt_checked
    cnt_checked += 1
    print(f"({cnt_checked}/{cnt_total}) {video_path}: gps does not exist")

if __name__=="__main__":

    if not os.path.exists("Image-ExifTool-12.64.tar.gz"):
        print("Donwloading exiftool...")
        exiftool_url = "https://exiftool.org/Image-ExifTool-12.64.tar.gz"
        response = requests.get(exiftool_url)
        open("Image-ExifTool-12.64.tar.gz", "wb").write(response.content)
        untar_cmd = "tar -xzf Image-ExifTool-12.64.tar.gz"
        os.system(untar_cmd)

    root = "/Users/heesukim/Downloads"
    # poc_ver = "poc_01"
    # poc_ver = "poc_02"  # no gps info at all
    # poc_ver = "poc_03"
    poc_ver = "poc_04"
    # poc_ver = "poc_10"
    # poc_ver = "poc_11"
    exe = "Image-ExifTool-12.64/exiftool"

    video_root = os.path.join(root, poc_ver)
    video_files = os.listdir(video_root)
    video_paths = [os.path.join(video_root, file) for file in video_files]

    global cnt_total, cnt_checked, num_have_gps
    cnt_total = len(video_paths)
    cnt_checked = 0
    num_have_gps = 0

    # Open the log file
    with open(f'logfile_{poc_ver}.txt', 'w') as log_file:

        for video_path in video_paths:
            get_gpu_meta(video_path, log_file)

        log_file.write(f"num_have_gps: {num_have_gps}\n")
        log_file.write("done\n")

    print("num_have_gps:", num_have_gps)
    print("done")


import logging
import mock
import unittest
from datetime import datetime, timedelta
from logging import LogRecord
from mock import patch
from mock import MagicMock, PropertyMock

from google.api.monitored_resource_pb2 import MonitoredResource
from google.cloud.logging_v2.proto.log_entry_pb2 import LogEntryOperation
from google.protobuf import json_format as gcp_json_format, any_pb2 as gcp_any_pb2
import pytz

from curation_logging import curation_gae_handler
from curation_logging.curation_gae_handler import GCPStackDriverLogger, LogCompletionStatusEnum
from curation_logging.curation_gae_handler import GAE_LOGGING_MODULE_ID, GAE_LOGGING_VERSION_ID

LOG_BUFFER_SIZE = 3
SEVERITY_DEBUG = 100  # 100 is the equivalence of logging.DEBUG
SEVERITY_INFO = 200  # 200 is the equivalence of logging.INFO
SEVERITY_ERROR = 300  # 300 is the equivalence of logging.ERROR

class GCPStackDriverLoggerTest(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        print('**************************************************************')
        print(cls.__name__)
        print('**************************************************************')

    def setUp(self):
        self.project_id = 'aou-res-curation-test'
        self.request_method = 'GET'
        self.request_full_path = '/admin/v1/RemoveExpiredServiceAccountKeys'
        self.request_user_agent = 'AppEngine-Google; (+http://code.google.com/appengine)'
        self.request_ip = '0.1.0.1'
        self.request_host_name = 'py3.aou-res-curation-test.appspot.com'
        self.request_log_id = 'fake_request_id'
        self.request_trace_id = 'fake_trace_id'
        self.request_trace = 'projects/{0}/traces/{1}'.format(
            self.project_id, self.request_trace_id)

        self.request_start_time = pytz.utc.localize(datetime(2020, 1, 1))
        self.request_end_time = pytz.utc.localize(datetime(
            2020, 1, 1)) + timedelta(minutes=1)
        self.request_log_entry_ts = self.request_start_time + timedelta(
            seconds=10)
        self.log_record_created = self.request_start_time - timedelta(
            seconds=10)

        self.mock_get_application_id_patcher = patch(
            'app_identity.get_application_id')
        self.mock_get_application_id = self.mock_get_application_id_patcher.start(
        )
        self.mock_get_application_id.return_value = self.project_id

        # Mock a flask request for testing
        self.request = MagicMock()
        type(self.request).method = PropertyMock(
            return_value=self.request_method)
        type(self.request).full_path = PropertyMock(
            return_value=self.request_full_path)
        type(self.request).user_agent = PropertyMock(
            return_value=self.request_user_agent)

        headers = dict()
        headers['X-Appengine-User-Ip'] = self.request_ip
        headers['X-Appengine-Default-Version-Hostname'] = self.request_host_name
        headers['X-Appengine-Request-Log-Id'] = self.request_log_id
        headers['X-Appengine-Taskname'] = None
        headers['X-Appengine-Queuename'] = None
        headers['X-Cloud-Trace-Context'] = self.request_trace_id

        type(self.request).headers = PropertyMock(return_value=headers)

        # Define the log records for testing
        self.file_path = 'data_steward/validation/main'
        self.file_name = 'main'
        self.info_log_record = self.create_log_record(
            'info', self.log_record_created, logging.INFO, self.file_name,
            self.file_path, 10, 'info message')
        self.debug_log_record = self.create_log_record(
            'debug', self.log_record_created, logging.DEBUG, self.file_name,
            self.file_path, 11, 'debug message')
        self.error_log_record = self.create_log_record(
            'error', self.log_record_created, logging.ERROR, self.file_name,
            self.file_path, 12, 'error message')

        self.info_log_line = {
            'logMessage': 'info message',
            'severity': SEVERITY_INFO,
            'time': self.log_record_created.isoformat(),
            'sourceLocation': {
                'file': self.file_path,
                'functionName': self.file_name,
                'line': 10
            }
        }

        self.debug_log_line = {
            'logMessage': 'debug message',
            'severity': SEVERITY_DEBUG,
            'time': self.log_record_created.isoformat(),
            'sourceLocation': {
                'file': self.file_path,
                'functionName': self.file_name,
                'line': 11
            }
        }

        self.error_log_line = {
            'logMessage': 'error message',
            'severity': SEVERITY_ERROR,
            'time': self.log_record_created.isoformat(),
            'sourceLocation': {
                'file': self.file_path,
                'functionName': self.file_name,
                'line': 12
            }
        }

        self.mock_logging_service_client_patcher = patch(
            'curation_logging.curation_gae_handler.gcp_logging_v2.LoggingServiceV2Client'
        )
        self.mock_logging_service_client = self.mock_logging_service_client_patcher.start(
        )

    def tearDown(self):
        self.mock_logging_service_client_patcher.stop()
        self.request.stop()

    @staticmethod
    def create_log_record(name, record_created, level_no, func_name, pathname,
                          lineno, msg):
        log_record = LogRecord(name=name,
                               levelno=level_no,
                               lineno=lineno,
                               func=func_name,
                               pathname=pathname,
                               msg=msg,
                               level=level_no,
                               args={},
                               exc_info={})
        log_record.created = record_created
        return log_record

    @mock.patch('curation_logging.curation_gae_handler.datetime')
    def test_gcp_stackdriver_logger(self, mock_datetime):
        mock_datetime.now.return_value.isoformat.return_value = self.request_start_time.isoformat(
        )
        mock_datetime.utcnow.return_value = self.request_start_time
        mock_datetime.utcfromtimestamp.return_value = self.log_record_created

        # Initialize GCPStackDriverLogger
        self.gcp_stackdriver_logger = GCPStackDriverLogger(LOG_BUFFER_SIZE)
        self.gcp_stackdriver_logger.setup_from_request(self.request)

        self.assertIsNone(self.gcp_stackdriver_logger._first_log_ts)
        self.assertEqual(self.gcp_stackdriver_logger._start_time,
                         self.request_start_time.isoformat())
        self.assertEqual(self.gcp_stackdriver_logger._request_method,
                         self.request_method)
        self.assertEqual(self.gcp_stackdriver_logger._request_resource,
                         self.request_full_path)
        self.assertEqual(self.gcp_stackdriver_logger._request_agent,
                         self.request_user_agent)
        self.assertEqual(self.gcp_stackdriver_logger._request_remote_addr,
                         self.request_ip)
        self.assertEqual(self.gcp_stackdriver_logger._request_host,
                         self.request_host_name)
        self.assertEqual(self.gcp_stackdriver_logger._request_log_id,
                         self.request_log_id)
        self.assertEqual(self.gcp_stackdriver_logger._trace, self.request_trace)

        self.gcp_stackdriver_logger.log_event(self.info_log_record)
        self.gcp_stackdriver_logger.log_event(self.debug_log_record)
        self.gcp_stackdriver_logger.log_event(self.error_log_record)

        self.assertEqual(
            len(self.gcp_stackdriver_logger._buffer), 0,
            'expected log buffer to flush itself after being filled')
        self.assertEqual(
            self.mock_logging_service_client.return_value.write_log_entries.
            call_count, 1)

        self.gcp_stackdriver_logger.finalize()
        self.assertIsNone(self.gcp_stackdriver_logger._first_log_ts)
        self.assertEqual(self.gcp_stackdriver_logger._start_time, None)
        self.assertEqual(self.gcp_stackdriver_logger._request_method, None)
        self.assertEqual(self.gcp_stackdriver_logger._request_resource, None)
        self.assertEqual(self.gcp_stackdriver_logger._request_agent, None)
        self.assertEqual(self.gcp_stackdriver_logger._request_remote_addr, None)
        self.assertEqual(self.gcp_stackdriver_logger._request_host, None)
        self.assertEqual(self.gcp_stackdriver_logger._request_log_id, None)
        self.assertEqual(self.gcp_stackdriver_logger._trace, None)

    @mock.patch('curation_logging.curation_gae_handler.get_gcp_logger')
    def test_initialize_logging(self, mock_get_gcp_logger):
        with patch.dict('os.environ', {'GAE_ENV': ''}):
            curation_gae_handler.initialize_logging(logging.DEBUG)
            logging.info(self.info_log_record)
            logging.debug(self.debug_log_line)
            logging.error(self.error_log_record)
            self.assertEqual(3, mock_get_gcp_logger.call_count)

    @mock.patch('requests.get')
    def test_setup_logging_zone(self, mock_requests_get):
        with patch.dict('os.environ', {'GAE_SERVICE': ''}):
            timezone = 'test time zone'
            mock_response = MagicMock()
            type(mock_response).status_code = PropertyMock(return_value=200)
            type(mock_response).text = timezone
            mock_requests_get.return_value = mock_response
            actual_time_zone = curation_gae_handler.setup_logging_zone()
            self.assertEqual(actual_time_zone, timezone)

            type(mock_response).status_code = PropertyMock(return_value=500)
            actual_time_zone = curation_gae_handler.setup_logging_zone()
            self.assertEqual(actual_time_zone, 'local-machine')

        with patch.dict('os.environ', dict()):
            actual_time_zone = curation_gae_handler.setup_logging_zone()
            self.assertEqual(actual_time_zone, 'local-machine')

    @mock.patch('curation_logging.curation_gae_handler.setup_logging_zone')
    def test_setup_logging_resource(self, mock_setup_logging_zone):
        timezone = 'test time zone'
        mock_setup_logging_zone.return_value = timezone
        actual_resource = curation_gae_handler.setup_logging_resource()
        expected_resource = MonitoredResource(
            type='gae_app',
            labels={
                'project_id': self.project_id,
                'module_id': GAE_LOGGING_MODULE_ID,
                'version_id': GAE_LOGGING_VERSION_ID,
                'zone': timezone
            })
        self.assertEqual(expected_resource, actual_resource)

    @mock.patch('curation_logging.curation_gae_handler.datetime')
    @mock.patch(
        'curation_logging.curation_gae_handler.gcp_logging._helpers._normalize_severity'
    )
    def test_setup_log_line(self, mock_normalize_severity, mock_datetime):
        mock_datetime.utcfromtimestamp.return_value = self.log_record_created
        mock_normalize_severity.side_effect = [
            SEVERITY_INFO, SEVERITY_DEBUG, SEVERITY_ERROR
        ]

        actual_info_log_line = curation_gae_handler.setup_log_line(
            self.info_log_record)
        self.assertDictEqual(self.info_log_line, actual_info_log_line)

        actual_debug_log_line = curation_gae_handler.setup_log_line(
            self.debug_log_record)
        self.assertDictEqual(self.debug_log_line, actual_debug_log_line)

        actual_error_log_line = curation_gae_handler.setup_log_line(
            self.error_log_record)
        self.assertDictEqual(self.error_log_line, actual_error_log_line)

    def test_get_highest_severity_level_from_lines(self):
        lines = [self.info_log_line, self.debug_log_line, self.error_log_line]
        actual_severity_level = curation_gae_handler.get_highest_severity_level_from_lines(
            lines)
        self.assertEqual(SEVERITY_ERROR, actual_severity_level)

    def test_setup_proto_payload(self):
        lines = [self.info_log_line, self.debug_log_line, self.error_log_line]

        proto_payload_args = {
            'startTime': self.request_start_time.isoformat(),
            'endTime': self.request_end_time.isoformat(),
            'method': self.request_method,
            'resource': self.request_full_path,
            'userAgent': self.request_user_agent,
            'host': self.request_host_name,
            'ip': self.request_ip,
            'responseSize': None
        }

        actual_proto_payload = curation_gae_handler.setup_proto_payload(
            lines, LogCompletionStatusEnum.PARTIAL_BEGIN, **proto_payload_args)

        expected_dict = dict(
            {
                '@type': curation_gae_handler.REQUEST_LOG_TYPE,
                'first': True,
                'finished': False,
                'line': lines
            }, **proto_payload_args)

        expected_proto_payload = gcp_json_format.ParseDict(
            expected_dict, gcp_any_pb2.Any())

        self.assertEqual(expected_proto_payload, actual_proto_payload)

    def test_update_long_operation(self):
        expected_operation = LogEntryOperation(
            id=self.request_log_id,
            producer='appengine.googleapis.com/request_id',
            first=True,
            last=True)

        actual_operation = curation_gae_handler.update_long_operation(
            self.request_log_id, LogCompletionStatusEnum.COMPLETE)
        self.assertEqual(expected_operation, actual_operation)

        expected_operation = LogEntryOperation(
            id=self.request_log_id,
            producer='appengine.googleapis.com/request_id',
            first=True,
            last=False)

        actual_operation = curation_gae_handler.update_long_operation(
            self.request_log_id, LogCompletionStatusEnum.PARTIAL_BEGIN)
        self.assertEqual(expected_operation, actual_operation)

        expected_operation = LogEntryOperation(
            id=self.request_log_id,
            producer='appengine.googleapis.com/request_id',
            first=False,
            last=False)

        actual_operation = curation_gae_handler.update_long_operation(
            self.request_log_id, LogCompletionStatusEnum.PARTIAL_MORE)
        self.assertEqual(expected_operation, actual_operation)


import magic
import json
import os
from django.shortcuts import render, get_object_or_404, HttpResponse, HttpResponseRedirect, reverse, Http404
from django.contrib.auth import get_user_model
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import JsonResponse
from django.conf import settings

# Importing token
from .tokens import account_activation_token

from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode

# Import for sending mail
from django.core import mail
from django.template.loader import render_to_string
from django.utils.html import strip_tags

from game.models import GameHistory, Participant
from .models import UserProfile

from .forms import AvatarUploadForm

User = get_user_model()

def user_profile_view(request, username):

    visited_user_qs = User.objects.filter(username=username)
    if not visited_user_qs:
        message = f"User with username {username} not found!"
        return render(request, '404.html', {"message": message})

    visitor = request.user
    visited_user = visited_user_qs[0]
    # if visitor.is_authenticated:
    visited_profile = UserProfile.objects.get(user=visited_user)
    avatar_upload_form = AvatarUploadForm()

    current_league = visited_profile.current_league
    current_rating = visited_profile.current_rating
    current_league_progress = 100 * (current_rating / UserProfile.RATING_THRESHOLDS[current_league])
    public_games_played = visited_profile.total_public_games_count
    public_games_won = visited_profile.won_public_games_count
    custom_games_played = visited_profile.total_custom_games_count
    custom_games_won = visited_profile.won_custom_games_count
    total_games_played = public_games_played + custom_games_played
    total_games_won = public_games_won + custom_games_won

    overall_win_rate = 100 * (total_games_won / total_games_played) if total_games_played > 0 else -1
    public_win_rate = 100 * (public_games_won / public_games_played) if public_games_played > 0 else -1
    custom_win_rate = 100 * (custom_games_won / custom_games_played) if custom_games_played > 0 else -1

    xp = visited_profile.xp
    level, xp_threshold = visited_profile.get_current_level_and_xp_threshold()
    xp_progress = 100 * (xp / xp_threshold)
    print(xp, level, xp_progress)
    stats = {
        "current_league_progress": int(current_league_progress),
        "overall_win_rate": int(overall_win_rate),
        "public_win_rate": int(public_win_rate),
        "custom_win_rate": int(custom_win_rate),
        "level": int(level),
        "xp_progress": int(xp_progress),
        "xp_threshold": int(xp_threshold),
    }

    history = get_history(username=username)
    context = {
        "visited_user": visited_user,
        "visited_profile": visited_profile,
        "avatar_upload_form": avatar_upload_form,
    }
    context.update(history)
    context.update(stats)

    return render(request, 'user_profile/profile_new.html', context=context)

@login_required
def verify_email(request, username):
    """
        This function sends a verification link to your email.
    """
    requested_user_qs = User.objects.filter(username=username)
    if not requested_user_qs:
        message = f"User with username {username} not found!"
        return render(request, '404.html', {"message": message})

    requested_user = requested_user_qs[0]

    user = request.user
    if user == requested_user:
        email = requested_user.email
        host = request.get_host()
        subject = 'Activate your UNO Game account.'

        email_context = {
            'user': user,
            'host': host,
            'uid': urlsafe_base64_encode(force_bytes(user.pk)),
            'token': account_activation_token.make_token(user),
        }
        html_message = render_to_string('user_profile/mail_template_email_verification.html', context=email_context)
        plain_message = strip_tags(html_message)

        from_email = "noreply@django_unchained"
        to = str(email)
        try:
            mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)
        except mail.BadHeaderError:
            messages.info(request, f"Invalid Header found, mail not sent!")

        return HttpResponse('Verification link has been sent to your email. '
                            'Please confirm your email address to complete the registration.')
    message = f"You are not authorised to visit this page."
    return render(request, '404.html', {"message": message})

def activate(request, uidb64, token):
    """
        A function that verifies email through activation link.
        It decodes the encoded pk (primary key).
    """
    try:
        uid = force_text(urlsafe_base64_decode(uidb64))
        user = User.objects.get(pk=uid)
    except(TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None
    if user is not None and account_activation_token.check_token(user, token):
        if request.user == user:
            if user.is_authenticated:
                profile = UserProfile.objects.get(user=user)

                profile.is_email_verified = True
                profile.save()

                messages.success(request, f"Your email has been verified.")
                return HttpResponseRedirect(reverse('home'))
            messages.success(request, f"Login to verify email.")
            return HttpResponseRedirect(reverse('home'))
    return HttpResponse('Activation link is invalid!')

def clean_file(request, form):
    file = form.cleaned_data['avatar']
    if file.size > 5242880:
        return False
    return True

def check_in_memory_mime(request):
    mime = magic.from_buffer(request.FILES.get('avatar').read(), mime=True)
    return mime

def delete_existing_avatar(username):
    """
    Function to delete existing avatar (if exists) of user before uploading new avatar.
    :param username: username of user whose avatar is to be deleted.
    :return:
    """
    try:
        media_url = str(settings.MEDIA_URL)[1:]
        path = f"{media_url}img/profile_avatars/{username}"
        files = os.listdir(path=path)
        for file_ in files:
            os.remove(f"{path}/{file_}")
        print(f"Existing avatar deleted.")
        return
    except OSError:
        return

@login_required
def avatar_upload(request, username):
    """
        This function uploads/re-uploads profile picture of a user.
    """
    if request.method == 'POST':
        avatar_form = AvatarUploadForm(request.POST, request.FILES)
        print(request.FILES)
        if request.FILES:
            if avatar_form.is_valid():
                user = User.objects.get(username=username)
                user_prof = UserProfile.objects.get(user=user)
                if clean_file(request, avatar_form):
                    mime = check_in_memory_mime(request)
                    if mime == 'image/jpg' or mime == 'image/jpeg' or mime == 'image/png':
                        img = avatar_form.cleaned_data['avatar']

                        # Deleting existing avatar of user.
                        delete_existing_avatar(username=username)

                        user_prof.avatar = img
                        user_prof.save()
                        message = f"Avatar uploaded successfully!"
                        messages.success(request, message=message)
                        return HttpResponseRedirect(reverse("user_profile", kwargs={'username': username}))
                    else:
                        messages.success(request, f"Please upload an Image File only of jpeg/jpg/png format only...")
                        return HttpResponseRedirect(reverse("user_profile", kwargs={'username': username}))
                else:
                    messages.success(request, f"File too Large to be uploaded...")
                    return HttpResponseRedirect(reverse("user_profile", kwargs={'username': username}))
            else:
                if avatar_form.errors:
                    for field in avatar_form:
                        for error in field.errors:
                            print(error)
                            messages.success(request, error)
                return HttpResponseRedirect(reverse("user_profile", kwargs={'username': username}))
        else:
            message = f"Please choose a file before uploading."
            messages.error(request, message)
            return HttpResponseRedirect(reverse("user_profile", kwargs={'username': username}))
    else:
        message = None
        return render(request, '404.html', {"message": message})

def get_history(username):
    """
    Function to fetch history of game.
    :param username:
    :return:
    """
    user = User.objects.get(username=username)
    participant_qs = Participant.objects.filter(user=user)
    response = {}
    if participant_qs:
        all_games = []
        for participant in participant_qs:
            game_room = participant.game_room
            all_games.append(game_room)

        all_games.reverse()

        all_game_data = []
        for game in all_games:
            winner_username = game.winner_username
            winner = User.objects.get(username=winner_username)
            player_qs = Participant.objects.filter(game_room=game)
            data = {
                "game": game,
                "participants": player_qs,
                "winner": winner,
            }
            all_game_data.append(data)

        response = {
            "all_game_data": all_game_data,
        }
    return response

@login_required
def edit_profile(request, username):
    """
    Method to updated edited personal details.
    :param request:
    :param username:
    :return:
    """
    user = request.user
    if user.username != username:
        message = f"{user.username}, why are you trying to edit {username}'s profile?"
        return render(request, '404.html', {"message": message})

    if request.method == "POST":

        user_profile = UserProfile.objects.get(user=user)
        all_users_qs = User.objects.all()

        # Fetching the edited values
        edited_first_name = request.POST["first_name"]
        edited_last_name = request.POST["last_name"]
        edited_email = request.POST["email"]

        # Updating the values
        user.first_name = edited_first_name
        user.last_name = edited_last_name

        # If user has edited the email, set is_email_verified to false
        print(user.email, edited_email)
        if user.email != edited_email:
            for user_ in all_users_qs:
                if user_.email == edited_email:
                    message = f"This email is already taken. Try again!"
                    messages.info(request, message)
                    response = {
                        "status": "error",
                        "message": "Request Failed!",
                    }
                    return JsonResponse(response)
            user.email = edited_email
            user_profile.is_email_verified = False
            user_profile.save()

        user.save()

        response = {
            "status": "success",
            "message": "Request Received Successfully!",
        }
        messages.success(request, f"Details have been updated successfully.")
        return JsonResponse(response)


from setuptools import setup

with open('README.rst', 'r') as f:
    README = f.read()

setup(name='aftershocks',
      version='0.1.0',
      description='Plot recent earthquakes in Japan by region',
      long_description=README,
      long_description_content_type='text/x-rst',
      url='http://github.com/juseg/aftershocks',
      author='Julien Seguinot',
      license='gpl-3.0',
      py_modules=['aftershocks'],
      install_requires=['matplotlib', 'pandas'],
      scripts=['aftershocks.py'],
      zip_safe=False)


from django.contrib.auth.decorators import login_required
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.urls import reverse

from .models import Favorite
from products.models import Product

@login_required(login_url='login')
def add_product_to_favorite(request, product_id):
    try:
        favorite, _ = Favorite.objects.get_or_create(user=request.user)
        product = get_object_or_404(Product, id=product_id)

        favorite.products.add(product)

        redirect_url = request.META.get('HTTP_REFERER', reverse('catalog'))

        return HttpResponseRedirect(redirect_url)

    except (Favorite.DoesNotExist, Product.DoesNotExist):
        return render(request, 'main/400.html', {'error': 'Что-то пошло не так'}, status=400)

def remove_favorite(request, product_id):
    if request.user.is_authenticated:
        favorite = get_object_or_404(Favorite, user=request.user)
        product = get_object_or_404(Product, id=product_id)
        favorite.products.remove(product)

        redirect_url = request.META.get('HTTP_REFERER', reverse('personal_data'))

        return HttpResponseRedirect(redirect_url)


import pygame
from pygame.locals import *
import time
pygame.init()
white = (255, 255, 255)
green = (0, 255, 0)
blue = (0, 0, 128)
RED=(255,0,0)
X = 800
Y = 400
color=(230,230,0)
# def make_button():
#     text = pygame.font.Font('freesansbold.ttf', 25).render('Next', True, (0,0,255),(255,165,0))
#     textRect = text.get_rect()
#     textRect.center = (500,200)
#     display_surface.blit(text, textRect)
#     if event.type == pygame.MOUSEBUTTONDOWN:
#         if textRect.collidepoint(event.pos):
#             pass

display_surface = pygame.display.set_mode((X, Y))
text = pygame.font.Font('freesansbold.ttf', 25).render('Next', True, (0,0,255),(255,165,0))
textRect = text.get_rect()
textRect.center = (500,200)
run=True
while run:#main loop for running of game until pressed close

    for event in pygame.event.get():#for taking all the input inside of game
        if event.type==pygame.QUIT:
            run=False
        if event.type == pygame.MOUSEBUTTONDOWN:
                if textRect.collidepoint(event.pos):
                    color=(230,230,230)
        display_surface.fill(color)
    display_surface.blit(text, textRect)
    pygame.display.update()
pygame.quit()