import os
from yaml import  load
from configparser import ConfigParser
import json
from  copy import copy
import hashlib
import platform
from requests.structures import CaseInsensitiveDict
from mlib.logger import  myLog
from mlib.build_in import do_validation
from mconf.setting import PARAM_PATH
from collections import OrderedDict
from mlib.m_expection   import *
import re
logger = myLog.getLog()

variable_regexp = r"\$([\w_]+)"

#获取可变参数
def extract_variables(content):
    """ extract all variable names from content, which is in format $variable
    @param (str) content
    @return (list) variable name list

    e.g. $variable => ["variable"]
         /blog/$postid => ["postid"]
         /$var1/$var2 => ["var1", "var2"]
         abc => []
    """
    try:
        result_list=re.findall(variable_regexp, content)
        return result_list[0]
    except TypeError:
        return []
# 操作文件类
class Operate_File():

    def __init__(self,file_name):
        if not file_name:
            logger.m_error('文件名不能为空,文件名为{}'.format(file_name))
        else:
            self.file_name=file_name
    #获取路径
    def get_path(self):
        path=os.path.dirname( __file__)
        parent_path=os.path.dirname(path)
        grand_path=os.path.join(parent_path,self.file_name)
        if platform.system() == 'Windows':
            logger.m_debug('系统为windows')
            if '\..' in grand_path:
                final_path=grand_path.replace('\../','/')
                return final_path
        elif platform.system() == 'Linux':
            if '/../' in grand_path:
                final_path = grand_path.replace('/../','/')

                logger.m_debug('linux上地址为{}'.format(grand_path))
                return final_path
        else:
            logger.m_error('暂未考虑其他平台的处理')
    #读取文件
    def read_file(self):
        path=self.get_path()
        logger.m_debug('路径为{}'.format(path))
        if  'yaml'in self.file_name:
            try:
                with open(path, 'rb') as pf:
                    data=load(pf)
                return data
            except Exception as e:
                logger.m_error('读取出错了，{}'.format(e))
                return  e
        elif 'ini' in self.file_name:
            config=ConfigParser()
            try:
                config.read(path)
                return config
            except Exception as e:
                logger.m_error('读取出错了，{}'.format(e))
                return  e

def query_json(query,json_content,  delimiter='.'):
    """ Do an xpath-like query with json_content.
    @param (json_content) json_content
        json_content = {
            "ids": [1, 2, 3, 4],
            "person": {
                "name": {
                    "first_name": "Leo",
                    "last_name": "Lee",
                },
                "age": 29,
                "cities": ["Guangzhou", "Shenzhen"]
            }
        }
    @param (str) query
        "person.name.first_name"  =>  "Leo"
        "person.cities.0"         =>  "Guangzhou"
    @return queried result
    """
    if json_content == "":
        raise ResponseError("response content is empty!")

    try:
        for key in query.split(delimiter):
            if isinstance(json_content, list):
                json_content = json_content[int(key)]
            elif isinstance(json_content, (dict, CaseInsensitiveDict)):
                json_content = json_content[key]
            else:
                raise ParseResponseError(
                    "response content is in text format! failed to query key {}!".format(key))
    except (KeyError, ValueError, IndexError):
        raise ParseResponseError("failed to query json when extracting response!")

    return json_content

#解决接口参数依赖上个接口返回的问题
def assemble_parm(data_dic):
    if isinstance(data_dic,dict):
        for k, v in data_dic.items():
            if str(v).startswith('$'):
                logger.m_info('v是需要提替换%s'%v)
                tmp = fetch_extract()
                v=v[1:]
                logger.m_info('tmp为%s'%tmp)
                data_dic[k] = tmp[v]
    elif isinstance(data_dic,str):
        if '$' in data_dic:
            tmp = fetch_extract()#获取上个接口返回的参数，字典形式
            parm_str = extract_variables(data_dic)#提取参数
            new_str = tmp[parm_str]
            old_str='$'+parm_str
            data_dic = data_dic.replace(old_str,new_str)

        logger.m_info('最终结果为%s'%data_dic)
    return data_dic

# 提取依赖参数
def extract_response(query,response):
    if  not isinstance(query,list):
        raise ParamsError('1should be list')
    result_list = {}
    for item in query:
        if not isinstance(item, dict):
            raise ParamsError('2should be list')
        for k, v in item.items():

            #print('v是%s' %v)
            item[k] = query_json(v,response)
            result_list.update(item)

    return result_list

def keep_extract(result_list,response):
    if not isinstance(result_list,list):
        raise ParamsError('1should be list')
    e = extract_response(result_list, response)
    with open(PARAM_PATH, 'w') as f:
        f.write(json.dumps(e))
def fetch_extract():
    with open(PARAM_PATH, 'r') as f:
        result = f.read()
        content = json.loads(result)

        return content

# 从接口提取返回值，为做验证用
def validate_response(query,response):
    if  not isinstance(query,list):
        raise ParamsError('1should be list')
    result_list = []
    for item in query:
        if not isinstance(item, dict):
            raise ParamsError('2should be list')
        for k, v in item.items():
            tmp = copy(v)
            if not isinstance(v,list):
                raise ParamsError('3should be list')
            qe = v[0]

            tmp[0] = query_json(qe,response)
            tmp.insert(0,k)
            result_list.append(tmp)

    return result_list

# 验证期望值和返回值
def m_check(mapping):
    if  not isinstance(mapping,list):
        raise ParamsError('should be list')
    for item in mapping:
        s=do_validation(item[0],item[1],item[2])
        return s

#md5加密
def md5_str(str):
    b_str=bytes(str,encoding='utf-8')
    return hashlib.md5(b_str).hexdigest()

if __name__=='__main__':
    #op =operate_File('../TestData/gm/valid.yaml')
    #d=op.read_file()

    check_data={
            'test_name':'用户信息查询',
            'parm':{
                'service':'bind_url',
                'body':[{
                    'index':{
                        'name':'shen',
                        'vals':[111111,222222]
                    }
                    }]
                }

            }

    #op = operate_File('../data/test_one/extract')
    #op.write_file(json.dumps(check_data))

    p_str = 'parm.body.0.index.vals.1'

    #print(query_json(p_str,check_data))
    print(fetch_extract())


from flask import Flask, redirect, url_for, render_template, request
import pandas as pd
import numpy as np
from PIL import Image, ImageShow
import os
import cv2
from processing import combined_inference
from load_model_v2 import get_classification_model, get_segmentation_model
import matplotlib.pyplot as plt
from mask_visualization import save_mask_image

app = Flask(__name__)
classification_model = get_classification_model()
segmentation_model = get_segmentation_model()

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/display_result')
def display():
    return render_template('display.html')

@app.route('/display_no_defect_found')
def display_no_defect_found():
    return render_template('display_no_defect_found.html')

@app.route('/processor', methods=['POST'])
def preprocessing():
    global classification_model, segmentation_model
    f = request.files['image_file']
    img = Image.open(f)
    img = np.asarray(img)

    # In case of grayScale images the len(img.shape) == 2
    if len(img.shape) > 2 and img.shape[2] == 4:
        #convert the image from RGBA2RGB
        img = cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)
    in_img = Image.fromarray(img)
    in_img.save('static/input_img.png')

    output = combined_inference(img, classification_model, segmentation_model)

    if output is not None:
        save_mask_image(img.copy(), output, 'output_img.png')
        return redirect(url_for('display'))

    return redirect(url_for('display_no_defect_found'))

if __name__ == '__main__':
    app.run(host='0.0.0.0',port=8080, debug=True)


def tokenize(text):
    tokens_by_slash = str(text.encode('utf-8')).split('/')	#get tokens after splitting by slash
    all_tokens = []
    for i in tokens_by_slash:
        tokens = str(i).split('-')	#get tokens after splitting by dash
        tokens_by_dot = []
        for j in range(0, len(tokens)):
            temp_tokens = str(tokens[j]).split('.')	#get tokens after splitting by dot
            tokens_by_dot = tokens_by_dot + temp_tokens
        all_tokens = all_tokens + tokens + tokens_by_dot
    all_tokens = list(set(all_tokens))	#remove redundant tokens

    return all_tokens


SLOW_DOWN_TRAP = 0
DAMAGE_TRAP = 1

class TrapInfo(object):
    _trap_count = 0
    _trap_set = []

    @classmethod
    def add_new_trap(cls, trap):
        cls._trap_set.append(trap)

    @classmethod
    def reset(cls):
        cls._trap_count = 0
        del cls._trap_set[:]

    @classmethod
    def get_traps(cls):
        return cls._trap_set

    def __init__(self, trap_type, position, rotation):
        self.trap_type = trap_type
        self.position = position
        self.rotation = rotation
        self.trap_id = TrapInfo._trap_count
        TrapInfo._trap_count += 1


#!/usr/bin/env python3
import logging

import rebrand_lib as lib

# Three / four letter abbreviation of new block chain. Example: kor, nano, ban
abbreviation = lib.get_env_variable('ABBREVIATION')

# Default boompow payout address
boompow_payout_address = lib.get_env_variable('BOOMPOW_PAYOUT_ADDRESS')

# Fully qualified domain name
domainsvc = lib.get_env_variable('DOMAINSVC')

work_threshold = lib.get_env_variable('WORK_THRESHOLD')
work_thresholds = work_threshold.split(",")
work_threshold_default = lib.get_env_variable('WORK_THRESHOLD_DEFAULT')

ignore_list = [
    "build",
    "git",
    "github",
    "miniupnp",
    "crypto",
    "lmd",
    "gtest",
    "cpptoml",
    "flatbuffers",
    "rocksd",
    "idea",
    "docker",
    "venv",
    "cmake-build-debug",
    "rebrand_nault.py",
    "gitmodules",
    "gitignore",
    "README.md",
    "SECURITY.md",
    "rep_weights_beta",
    "rep_weights_live",
    "clang-format",
    "env_local",
    "env_example",
    "node_modules",
    "nanocurrency-js"
]

words = [
    [b"previous, difficulty='fffffff800000000'", b"previous, difficulty='%s'" % str.encode(work_threshold_default)],
    [b"base_difficulty='fffffe0000000000'", b"base_difficulty='%s'" % str.encode(work_thresholds[0])],
    [b"DEFAULT_WORK_DIFFICULTY = 'fffffe0000000000'", b"DEFAULT_WORK_DIFFICULTY = '%s'" % str.encode(work_thresholds[0])],
    [b'"difficulty": "fffffe0000000000"', b'"difficulty": "%s"' % str.encode(work_thresholds[0])],
    [b'default `fffffe0000000000`', b'default `%s`' % str.encode(work_thresholds[0])],
]
lib.replace_all(words, ignore_list, "/NanoRPCProxy")

bananoPublicAddress = "    p = re.compile('^(ban)_[13]{1}[13456789abcdefghijkmnopqrstuwxyz]{59}$')"
bananoPublicAddressReplace = "    p = re.compile('^(%s)_[13]{1}[13456789abcdefghijkmnopqrstuwxyz]{59}$')" % abbreviation
lib.find_and_replace("%sboompow/client/config_parse.py" % lib.cwd(),
                 str.encode(bananoPublicAddress),
                 str.encode(bananoPublicAddressReplace))

payoutAddress = "ban_1boompow14irck1yauquqypt7afqrh8b6bbu5r93pc6hgbqs7z6o99frcuym"
payoutAddressReplace = "%s_123...1234" % abbreviation
lib.find_and_replace("%sboompow/client/run_windows.bat" % lib.cwd(),
                 str.encode(payoutAddress),
                 str.encode(payoutAddressReplace))

notAValidAddress = 'msg = "%r is not a valid BANANO address" % string'
notAValidAddressReplace = 'msg = "%r is not a valid address" % string'
lib.find_and_replace("%sboompow/client/config_parse.py" % lib.cwd(),
                 str.encode(notAValidAddress),
                 str.encode(notAValidAddressReplace))

addressRegex = "address_regex = '(?:ban)(?:_)(?:1|3)(?:[13456789abcdefghijkmnopqrstuwxyz]{59})'"
addressRegexReplace = "address_regex = '(?:%s)(?:_)(?:1|3)(?:[13456789abcdefghijkmnopqrstuwxyz]{59})'" % abbreviation
lib.find_and_replace("%sboompow/server/bpow/validators.py" % lib.cwd(),
                 str.encode(addressRegex),
                 str.encode(addressRegexReplace))

abbreviation_len = len(abbreviation)
address_len = 64

if abbreviation_len == 3:
    address_len = 64
elif abbreviation_len == 4:
    address_len = 65
else:
    logging.error("Wrong abbreviation length!")

validateChecksumxrb1 = "if len(address) == 64 and address[:4] == 'ban_':"
validateChecksumxrb1Replace = "if len(address) == %s and address[:%s] == '%s_':" % (address_len,
                                                                                str(abbreviation_len+1),
                                                                                abbreviation)
lib.find_and_replace("%sboompow/server/bpow/validators.py" % lib.cwd(),
                 str.encode(validateChecksumxrb1),
                 str.encode(validateChecksumxrb1Replace))

validateChecksumxrb2 = "acrop_key = address[4:-8]"
validateChecksumxrb2Replace = "acrop_key = address[%s:-8]" % str(abbreviation_len+1)
lib.find_and_replace("%sboompow/server/bpow/validators.py" % lib.cwd(),
                 str.encode(validateChecksumxrb2),
                 str.encode(validateChecksumxrb2Replace))

requirementsSerever = """ujson
uvloop
aiohttp
aioredis
amqtt
websockets
requests
asyncio-throttle
nanolib
bitstring
redis"""
requirementsSereverReplace = """aiohttp==3.7.4.post0
aioredis==1.3.1
amqtt==0.10.0a3
async-timeout==3.0.1
asyncio-throttle==1.0.2
attrs==21.2.0
bitstring==3.1.7
certifi==2021.5.30
chardet==4.0.0
docopt==0.6.2
ed25519-blake2b==1.4
hiredis==2.0.0
idna==2.10
multidict==5.1.0
nanolib==0.4.3
passlib==1.7.4
py-cpuinfo==8.0.0
PyYAML==5.4.1
redis==3.5.3
requests==2.25.1
six==1.16.0
transitions==0.8.8
typing-extensions==3.10.0.0
ujson==4.0.2
urllib3==1.26.5
uvloop==0.15.2
websockets==8.1
yarl==1.6.3"""
lib.find_and_replace("%sboompow/server/requirements.txt" % lib.cwd(),
                     str.encode(requirementsSerever),
                     str.encode(requirementsSereverReplace))
# replace urls
urls = [
    [b"bpow.banano.cc", b"%s-bpow.%s" % (str.encode(abbreviation), str.encode(domainsvc))],
    [b"chat.banano.cc", b"%s-chat.%s" % (str.encode(abbreviation), str.encode(domainsvc))],
    [b"https://banano.cc", b"https://%s.%s" % (str.encode(abbreviation), str.encode(domainsvc))],
]
lib.replace_all(urls, ignore_list, "/boompow")


import os
import json
import click
from datetime import datetime
from flask_migrate import Migrate
from app import create_app, db
from app.models import User, Event, Exercise

app = create_app(os.getenv('FLASK_CONFIG') or 'default')
migrate = Migrate(app, db)

@app.shell_context_processor
def make_shell_context():
    return dict(db=db, User=User, Exercise=Exercise)

@app.cli.command()
def test():
    """Run the unit tests."""
    # import unittest
    # tests = unittest.TestLoader().discover('tests')
    # unittest.TextTestRunner(verbosity=2).run(tests)

    import pytest
    pytest.main(['tests/'])

@app.cli.command()
@click.option('--drop_first', default=False)
def createdb(drop_first):
    """Creates a database."""
    if drop_first:
        db.drop_all()
    db.create_all()

@app.cli.command()
def seeddb():
    user = User(email='ben@domain.com',
                first_name='Ben',
                last_name='Randerson')
    user.set_password('test')
    db.session.add(user)
    EVENTS = json.load(open('events.json'))
    for event in EVENTS:
        date = datetime.strptime(EVENTS[event]['date'], '%Y-%m-%d').date()
        d = EVENTS[event]['date']
        e = Event(name=event,
                  distance=EVENTS[event]['distance'],
                  date=date)
        db.session.add(e)
    db.session.commit()

@app.cli.command()
def clean():
    """Remove *.pyc and *.pyo files recursively starting at current directory.
    """
    for dirpath, dirnames, filenames in os.walk('.'):
        for filename in filenames:
            if filename.endswith('.pyc') or filename.endswith('.pyo'):
                full_pathname = os.path.join(dirpath, filename)
                print('Removing {}'.format(full_pathname))
                os.remove(full_pathname)


from django.conf.urls import url

from django.conf import settings
from django.conf.urls.static import static

from . import views

app_name = 'app'
urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^sort_by_id/$', views.sort_by_id, name='sort_by_id'),
    url(r'^sort_by_partner/$', views.sort_by_partner, name='sort_by_partner'),
    url(r'^(?P<status>[0-9]+)/$', views.filter_status, name='filter_status'),
    url(r'^edit/(?P<project_id>[0-9]+)/$', views.edit, name='edit'),
    url(r'^add/$', views.add, name='add'),
    url(r'^add_device/$', views.add_device, name='add_device'),
    url(r'^search/$', views.search, name='search'),
    url(r'^report/$', views.report, name='report'),

    # url(r'^add/$', views.AddView.as_view(), name='add'),
    # url(r'^get_name/$', views.get_name, name='get_name'),
    # url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),

] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


import numpy as np
from pandas import DataFrame
from scipy.stats import f
from numpy.typing import NDArray

def sumsq_total(df_long: DataFrame, values: str) -> NDArray:
    """
    calculates the sum of square total
    the difference between each value and the global mean
    :param df_long: A pandas DataFrame in long format.
    :param values: variable string for values containing scores
    :return:
    """
    return np.sum((df_long[values] - df_long[values].mean()) ** 2)

def sumsq_within(df_long: DataFrame, sessions: str, values: str, n_subjects: int) -> NDArray:
    """
    calculates the sum of squared Intra-subj variance,
    the average session value subtracted from overall avg of values
    :param df_long: A pandas DataFrame in long format (e.g scores across subjects and 1+ sessions)
    :param sessions: session (repeated measurement) variable in df, string
    :param values: variable for values for subjects across sessions, str
    :param n_subjects: number of subjects
    :return: returns sumsqured within
    """

    return np.sum(
        ((df_long[values].mean() -
          df_long[[sessions, values]].groupby(by=sessions)[values].mean()) ** 2) * n_subjects
    )

def sumsq_btwn(df_long: DataFrame, subj: str, values: str, n_sessions: int) -> NDArray:
    """
    calculates the sum of squared between-subj variance,
    the average subject value subtracted from overall avg of values

    :param df_long: A pandas DataFrame in long format (e.g scores across subjects and 1+ sessions)
    :param subj: subj variable in df, string
    :param values: variable for values for subjects across sessions, str
    :param n_sessions: number of sessions
    :return: returns sumsqured within
    """
    return np.sum(
        ((df_long[values].mean() - df_long[[subj, values]].groupby(by=subj)[values].mean()) ** 2) * n_sessions
    )

def check_icc_type(icc_type, allowed_types=None):
    if allowed_types is None:
        allowed_types = ['icc_1', 'icc_2', 'icc_3']
    assert icc_type in allowed_types, \
        f'ICC type should be in {",".join(allowed_types)}' \
        f'{icc_type} entered'

def icc_confint(msbs: float, msws: float, mserr: float, msc: float,
                n_subjs: int, n_sess: int, icc_2=None, alpha=0.05, icc_type='icc_3'):
    """
    Calculates the confidence interval for ICC(1), ICC(2,1), or ICC(3,1) using the F-distribution method.
    Default = 95% CI. Adopts technique from Pinguin's (https://pingouin-stats.org/build/html/index.html) ICC
    confidence interval calculation

    :param msbs: The mean square between-subject (float)
    :param msws: The mean square within-subject.
    :param mserr: The mean square error.
    :param msc: The mean square for the rater effect.
    :param n_subjs: The number of subjects.
    :param n_sess: The number of raters.
    :param icc_2: ICC(2,1) estimate to be used in calculating upper/lower CI
    :param alpha: The significance level for the confidence interval. Default is 0.05.
    :param icc_type: Confidence interval for specified ICC, default ICC(3,1)

    Returns
    -------
    icc1_ci, icc21_ci or icc31_ci : tuple
        The 95% confidence intervals for ICC(1), ICC(2,1), and ICC(3,1), respectively.
    """
    check_icc_type(icc_type)

    # Calculate F, df, and p-values
    f_stat1 = msbs / msws
    df1 = n_subjs - 1
    df1kd = n_subjs * (n_sess - 1)

    f_stat3 = msbs / mserr
    df2kd = (n_subjs - 1) * (n_sess - 1)

    # Calculate ICC Confident interval
    if icc_type == 'icc_1':
        f_lb = f_stat1 / f.ppf(1 - alpha / 2, df1, df1kd)
        f_ub = f_stat1 * f.ppf(1 - alpha / 2, df1kd, df1)
        lb_ci = (f_lb - 1) / (f_lb + (n_sess - 1))
        ub_ci = (f_ub - 1) / (f_ub + (n_sess - 1))
    elif icc_type == 'icc_2':
        fc = msc / mserr
        vn = df2kd * ((n_sess * icc_2 * fc + n_subjs * (1 + (n_sess - 1) * icc_2) - n_sess * icc_2)) ** 2
        vd = df1 * n_sess ** 2 * icc_2 ** 2 * fc ** 2 + (n_subjs * (1 + (n_sess - 1) * icc_2) - n_sess * icc_2) ** 2
        v = vn / vd
        f2u = f.ppf(1 - alpha / 2, n_subjs - 1, v)
        f2l = f.ppf(1 - alpha / 2, v, n_subjs - 1)
        lb_ci = n_subjs * (msbs - f2u * mserr) / (
                f2u * (n_sess * msc + (n_sess * n_subjs - n_sess - n_subjs) * mserr) + n_subjs * msbs)
        ub_ci = n_subjs * (f2l * msbs - mserr) / (
                n_sess * msc + (n_sess * n_subjs - n_sess - n_subjs) * mserr + n_subjs * f2l * msbs)
    elif icc_type == 'icc_3':
        f_lb = f_stat3 / f.ppf(1 - alpha / 2, df1, df2kd)
        f_ub = f_stat3 * f.ppf(1 - alpha / 2, df2kd, df1)
        lb_ci = (f_lb - 1) / (f_lb + (n_sess - 1))
        ub_ci = (f_ub - 1) / (f_ub + (n_sess - 1))

    return lb_ci, ub_ci

def sumsq_icc(df_long: DataFrame, sub_var: str,
              sess_var: str, value_var: str, icc_type: str = 'icc_3'):
    """ This ICC calculation uses the SS calculation, which are similar to ANOVA, but fewer estimates are used.
    It takes in a long format pandas DF, where subjects repeat for sessions
    The total variance (SS_T) is squared difference each value and the overall mean.
    This is then decomposed into INTER (between) and INTRA (within) subject variance.

    :param df_long: Data of subjects & sessions, long format (i.e., subjs repeating, for 1+ sessions).
    :param sub_var: str of column in dataframe w/ subject identifying variable
    :param sess_var: str of column in dataframe that is repeat session variables
    :param value_var: str in dataframe that contains values for each session
    :param icc_type: default is ICC(3,1), alternative is ICC(1,1) via icc_1 or ICC(2,1) via icc_2
    :return: icc calculation, icc low bound conf, icc upper bound conf, msbs, msws
    """
    assert sub_var in df_long.columns, \
        f'sub_var {sub_var} must be a column in the data frame'
    assert sess_var in df_long.columns, \
        f'sess_var {sess_var} must be a column in the data frame'
    assert value_var in df_long.columns, \
        f'value_var {value_var} must be a column in the data frame'

    check_icc_type(icc_type)

    # check replace missing
    nan_in_vals = df_long.isna().any().any()
    if nan_in_vals:
        # Using mean based replacement; calc mean of values column
        # Note: pinguin in python & ICC in R converts data to wide --> listwise deletion --> convert to long
        mean_vals = df_long[value_var].mean()
        # Replace NaN or missing values with the column mean
        df_long[value_var].fillna(mean_vals, inplace=True)

    # num_subjs = number of subjs, num_sess = number of sessions/ratings
    num_subjs = df_long[sub_var].nunique()
    num_sess = df_long[sess_var].nunique()
    DF_r = (num_subjs - 1) * (num_sess - 1)

    # Sum of square errors
    SS_Total = sumsq_total(df_long=df_long, values=value_var)
    SS_Btw = sumsq_btwn(df_long=df_long, subj=sub_var, values=value_var, n_sessions=num_sess)
    SS_C = sumsq_within(df_long=df_long, sessions=sess_var, values=value_var, n_subjects=num_subjs)
    SS_Err = SS_Total - SS_Btw - SS_C
    SS_Wth = SS_C + SS_Err

    # Mean Sum of Squares
    MSBtw = SS_Btw / (num_subjs - 1)
    MSWtn = SS_Wth / (DF_r + (num_sess - 1))
    MSc = SS_C / (num_sess - 1)
    MSErr = SS_Err / DF_r

    # Calculate ICCs
    lowerbound, upperbound = None, None  # set to None in case they are skipped
    if icc_type == 'icc_1':
        # ICC(1), Model 1
        try:
            estimate = (MSBtw - MSWtn) / (MSBtw + (num_sess - 1) * MSWtn)
        except RuntimeWarning:
            estimate = 0

        if MSWtn > 0 and MSErr > 0:
            lowerbound, upperbound = icc_confint(msbs=MSBtw, msws=MSWtn, mserr=MSErr, msc=MSc,
                                                 n_subjs=num_subjs, n_sess=num_sess, alpha=0.05, icc_type='icc_1')

    elif icc_type == 'icc_2':
        # ICC(2,1)
        try:
            estimate = (MSBtw - MSErr) / (MSBtw + (num_sess - 1) * MSErr + num_sess * (MSc - MSErr) / num_subjs)
        except RuntimeWarning:
            estimate = 0

        if MSWtn > 0 and MSErr > 0:
            lowerbound, upperbound = icc_confint(msbs=MSBtw, msws=MSWtn, mserr=MSErr, msc=MSc,
                                                 n_subjs=num_subjs, n_sess=num_sess, icc_2=estimate, alpha=0.05,
                                                 icc_type='icc_2')

    elif icc_type == 'icc_3':
        # ICC(3,1)
        try:
            estimate = (MSBtw - MSErr) / (MSBtw + (num_sess - 1) * MSErr)
        except RuntimeWarning:
            estimate = 0

        if MSWtn > 0 and MSErr > 0:
            lowerbound, upperbound = icc_confint(msbs=MSBtw, msws=MSWtn, mserr=MSErr, msc=MSc,
                                                 n_subjs=num_subjs, n_sess=num_sess, alpha=0.05, icc_type='icc_3')

    return estimate, lowerbound, upperbound, MSBtw, MSWtn


import os
import mock
import yaml
import json
import logging
from unittest import TestCase
from importlib import import_module

import grpc
from pyfakefs.fake_filesystem_unittest import TestCase as FileTestCase

import google.ads.google_ads.client
from google.ads.google_ads.errors import GoogleAdsException

latest_version = google.ads.google_ads.client._DEFAULT_VERSION
valid_versions = google.ads.google_ads.client._VALID_API_VERSIONS

errors = import_module('google.ads.google_ads.%s.proto.errors' % latest_version)
error_protos = errors.errors_pb2
services = import_module('google.ads.google_ads.%s.proto.services' %
                         latest_version)
google_ads_service_pb2 = services.google_ads_service_pb2

class ModuleLevelTest(TestCase):

    def test_parse_metadata_to_json(self):
        mock_metadata = [
            ('x-goog-api-client',
             'gl-python/123 grpc/123 gax/123'),
            ('developer-token', '0000000000'),
            ('login-customer-id', '9999999999')]

        result = (google.ads.google_ads.client.
                  _parse_metadata_to_json(mock_metadata))

        self.assertEqual(result, '{\n'
                                 '  "developer-token": "REDACTED",\n'
                                 '  "login-customer-id": "9999999999",\n'
                                 '  "x-goog-api-client": "gl-python/123 '
                                 'grpc/123 gax/123"\n'
                                 '}')

    def test_parse_metadata_to_json_with_none(self):
        mock_metadata = None

        result = (google.ads.google_ads.client.
                  _parse_metadata_to_json(mock_metadata))

        self.assertEqual(result, '{}')

class GoogleAdsClientTest(FileTestCase):
    """Tests for the google.ads.googleads.client.GoogleAdsClient class."""

    def _create_test_client(self, endpoint=None):
        with mock.patch('google.oauth2.credentials') as mock_credentials:
            mock_credentials_instance = mock_credentials.return_value
            mock_credentials_instance.refresh_token = self.refresh_token
            mock_credentials_instance.client_id = self.client_id
            mock_credentials_instance.client_secret = self.client_secret
            client = google.ads.google_ads.client.GoogleAdsClient(
                mock_credentials_instance, self.developer_token,
                endpoint=endpoint)
            return client

    def setUp(self):
        self.setUpPyfakefs()
        self.developer_token = 'abc123'
        self.client_id = 'client_id_123456789'
        self.client_secret = 'client_secret_987654321'
        self.refresh_token = 'refresh'
        self.login_customer_id = '1234567890'

    def test_load_from_storage_login_customer_id(self):
        config = {
            'developer_token': self.developer_token,
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'refresh_token': self.refresh_token,
            'login_customer_id': self.login_customer_id
        }

        file_path = os.path.join(os.path.expanduser('~'), 'google-ads.yaml')
        self.fs.create_file(file_path, contents=yaml.safe_dump(config))

        with mock.patch('google.ads.google_ads.client.GoogleAdsClient'
                        '.__init__') as mock_client_init, \
            mock.patch(
                 'google.oauth2.credentials.Credentials') as mock_credentials:
            mock_client_init.return_value = None
            mock_credentials_instance = mock.Mock()
            mock_credentials.return_value = mock_credentials_instance
            (google.ads.google_ads.client.GoogleAdsClient.load_from_storage())
            mock_client_init.assert_called_once_with(
                credentials=mock_credentials_instance,
                developer_token=self.developer_token,
                endpoint=None,
                login_customer_id=self.login_customer_id,
                logging_config=None)

    def test_load_from_storage_login_customer_id_as_None(self):
        config = {
            'developer_token': self.developer_token,
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'refresh_token': self.refresh_token,
            'login_customer_id': None
        }

        file_path = os.path.join(os.path.expanduser('~'), 'google-ads.yaml')
        self.fs.create_file(file_path, contents=yaml.safe_dump(config))

        with mock.patch('google.ads.google_ads.client.GoogleAdsClient'
                        '.__init__') as mock_client_init, \
            mock.patch(
                 'google.oauth2.credentials.Credentials') as mock_credentials:
            mock_client_init.return_value = None
            mock_credentials_instance = mock.Mock()
            mock_credentials.return_value = mock_credentials_instance
            (google.ads.google_ads.client.GoogleAdsClient.load_from_storage())
            mock_client_init.assert_called_once_with(
                credentials=mock_credentials_instance,
                developer_token=self.developer_token,
                endpoint=None,
                login_customer_id=None,
                logging_config=None)

    def test_load_from_storage_invalid_login_customer_id(self):
        config = {
            'developer_token': self.developer_token,
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'refresh_token': self.refresh_token,
            'login_customer_id': '123-456-7890'
        }

        file_path = os.path.join(os.path.expanduser('~'), 'google-ads.yaml')
        self.fs.create_file(file_path, contents=yaml.safe_dump(config))

        with mock.patch(
                'google.oauth2.credentials.Credentials') as mock_credentials:
            mock_credentials_instance = mock.Mock()
            mock_credentials.return_value = mock_credentials_instance
            self.assertRaises(
                    ValueError,
                    google.ads.google_ads.client.GoogleAdsClient
                    .load_from_storage)

    def test_load_from_storage_too_short_login_customer_id(self):
        config = {
            'developer_token': self.developer_token,
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'refresh_token': self.refresh_token,
            'login_customer_id': '123'
        }

        file_path = os.path.join(os.path.expanduser('~'), 'google-ads.yaml')
        self.fs.create_file(file_path, contents=yaml.safe_dump(config))

        with mock.patch(
                'google.oauth2.credentials.Credentials') as mock_credentials:
            mock_credentials_instance = mock.Mock()
            mock_credentials.return_value = mock_credentials_instance
            self.assertRaises(
                    ValueError,
                    google.ads.google_ads.client.GoogleAdsClient
                    .load_from_storage)

    def test_load_from_storage(self):
        config = {
            'developer_token': self.developer_token,
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'refresh_token': self.refresh_token
        }

        file_path = os.path.join(os.path.expanduser('~'), 'google-ads.yaml')
        self.fs.create_file(file_path, contents=yaml.safe_dump(config))

        with mock.patch('google.ads.google_ads.client.GoogleAdsClient'
                        '.__init__') as mock_client_init, \
            mock.patch(
                 'google.oauth2.credentials.Credentials') as mock_credentials:
            mock_client_init.return_value = None
            mock_credentials_instance = mock.Mock()
            mock_credentials.return_value = mock_credentials_instance
            (google.ads.google_ads.client.GoogleAdsClient
             .load_from_storage())
            mock_client_init.assert_called_once_with(
                credentials=mock_credentials_instance,
                developer_token=self.developer_token,
                endpoint=None,
                login_customer_id=None,
                logging_config=None)

    def test_load_from_storage_custom_endpoint(self):
        endpoint = 'alt.endpoint.com'
        config = {
            'developer_token': self.developer_token,
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'refresh_token': self.refresh_token,
            'endpoint': endpoint
        }

        file_path = os.path.join(os.path.expanduser('~'), 'google-ads.yaml')
        self.fs.create_file(file_path, contents=yaml.safe_dump(config))

        with mock.patch('google.ads.google_ads.client.GoogleAdsClient'
                        '.__init__') as mock_client_init, \
            mock.patch(
                'google.oauth2.credentials.Credentials') as mock_credentials:
            mock_client_init.return_value = None
            mock_credentials_instance = mock.Mock()
            mock_credentials.return_value = mock_credentials_instance
            google.ads.google_ads.client.GoogleAdsClient.load_from_storage()
            mock_client_init.assert_called_once_with(
                credentials=mock_credentials_instance,
                developer_token=self.developer_token,
                endpoint=endpoint,
                login_customer_id=None,
                logging_config=None)

    def test_load_from_storage_custom_path(self):
        config = {
            'developer_token': self.developer_token,
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'refresh_token': self.refresh_token
        }

        file_path = 'test/google-ads.yaml'
        self.fs.create_file(file_path, contents=yaml.safe_dump(config))

        with mock.patch('google.ads.google_ads.client.GoogleAdsClient'
                        '.__init__') as mock_client_init, \
            mock.patch(
                'google.oauth2.credentials.Credentials') as mock_credentials:
            mock_client_init.return_value = None
            mock_credentials_instance = mock.Mock()
            mock_credentials.return_value = mock_credentials_instance
            (google.ads.google_ads.client.GoogleAdsClient
             .load_from_storage(path=file_path))
            mock_client_init.assert_called_once_with(
                credentials=mock_credentials_instance,
                developer_token=self.developer_token,
                endpoint=None,
                login_customer_id=None,
                logging_config=None)

    def test_load_from_storage_file_not_found(self):
        wrong_file_path = 'test/wrong-google-ads.yaml'

        self.assertRaises(
            IOError,
            google.ads.google_ads.client.GoogleAdsClient.load_from_storage,
            path=wrong_file_path)

    def test_load_from_storage_required_config_missing(self):
        config = {
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'refresh_token': self.refresh_token
        }

        file_path = 'test/google-ads.yaml'
        self.fs.create_file(file_path, contents=yaml.safe_dump(config))

        self.assertRaises(
            ValueError,
            google.ads.google_ads.client.GoogleAdsClient.load_from_storage,
            path=file_path)

    def test_get_service(self):
        # Retrieve service names for all defined service clients.
        for ver in valid_versions:
            services_path = 'google.ads.google_ads.%s' % ver
            service_names = [
                '%s%s' % (name.rsplit('ServiceClient')[0], 'Service')
                for name in dir(import_module(services_path))
                if 'ServiceClient' in name]

            client = self._create_test_client()

            # Iterate through retrieval of all service clients by name.
            for service_name in service_names:
                client.get_service(service_name)

    def test_get_service_custom_endpoint(self):
        service_name = 'GoogleAdsService'
        service_module_base = 'google_ads_service'
        grpc_transport_class_name = '%sGrpcTransport' % service_name
        grpc_transport_module_name = '%s_grpc_transport' % service_module_base
        transport_create_channel_path = (
            'google.ads.google_ads.%s.services.transports.%s.%s.create_channel'
            % (google.ads.google_ads.client._DEFAULT_VERSION,
               grpc_transport_module_name,
               grpc_transport_class_name))
        endpoint = 'alt.endpoint.com'
        client = self._create_test_client(endpoint=endpoint)

        # The GRPC transport's create_channel method is what allows the
        # GoogleAdsClient to specify a custom endpoint. Here we mock the
        # create_channel method in order to verify that it was given the
        # endpoint specified by the client.
        with mock.patch(transport_create_channel_path) as mock_create_channel:
            # A new channel is created during initialization of the service
            # client.
            client.get_service(service_name)
            mock_create_channel.assert_called_once_with(
                address=endpoint, credentials=client.credentials)

    def test_get_service_not_found(self):
        client = self._create_test_client()
        self.assertRaises(ValueError, client.get_service, 'BadService')

    def test_get_service_invalid_version(self):
        client = self._create_test_client()
        self.assertRaises(ValueError, client.get_service, 'GoogleAdsService',
                          version='v0_bad')

    def test_get_service_with_version(self):
        client = self._create_test_client()
        try:
            client.get_service('GoogleAdsService', version=latest_version)
        except Exception:
            self.fail('get_service with a valid version raised an error')

    def test_get_type(self):
        for ver in valid_versions:
            # Retrieve names for all types defined in pb2 files.
            type_path = 'google.ads.google_ads.%s.types' % ver
            type_names = import_module(type_path).names

            # Iterate through retrieval of all types by name.
            for name in type_names:
                google.ads.google_ads.client.GoogleAdsClient.get_type(
                    name, version=ver)

    def test_get_type_not_found(self):
        self.assertRaises(
            ValueError, google.ads.google_ads.client.GoogleAdsClient.get_type,
            'BadType')

    def test_get_type_invalid_version(self):
        self.assertRaises(
            ValueError, google.ads.google_ads.client.GoogleAdsClient.get_type,
            'GoogleAdsFailure', version='v0_bad')

class MetadataInterceptorTest(TestCase):

    def setUp(self):
        self.mock_developer_token = '1234567890'
        self.mock_login_customer_id = '0987654321'

    def test_init(self):
        interceptor = google.ads.google_ads.client.MetadataInterceptor(
            self.mock_developer_token,
            self.mock_login_customer_id)

        self.assertEqual(
            interceptor.developer_token_meta,
            ('developer-token', self.mock_developer_token))

        self.assertEqual(
            interceptor.login_customer_id_meta,
            ('login-customer-id', self.mock_login_customer_id)
        )

    def test_init_no_login_customer_id(self):
        interceptor = google.ads.google_ads.client.MetadataInterceptor(
            self.mock_developer_token,
            None)

        self.assertEqual(
            interceptor.developer_token_meta,
            ('developer-token', self.mock_developer_token))

        self.assertEqual(
            interceptor.login_customer_id_meta,
            None
        )

    def test_update_client_call_details_metadata(self):
        interceptor = google.ads.google_ads.client.MetadataInterceptor(
            self.mock_developer_token,
            self.mock_login_customer_id)

        mock_metadata = list([('test-key', 'test-value')])
        mock_client_call_details = mock.Mock()

        client_call_details = interceptor._update_client_call_details_metadata(
            mock_client_call_details, mock_metadata)

        self.assertEqual(client_call_details.metadata, mock_metadata)

    def test_intercept_unary_unary(self):
        interceptor = google.ads.google_ads.client.MetadataInterceptor(
            self.mock_developer_token,
            self.mock_login_customer_id)

        mock_continuation = mock.Mock(return_value=None)
        mock_client_call_details = mock.Mock()
        mock_client_call_details.method = 'test/method'
        mock_client_call_details.timeout = 5
        mock_client_call_details.metadata = [('apples', 'oranges')]
        mock_request = mock.Mock()

        with mock.patch.object(
            interceptor,
            '_update_client_call_details_metadata',
            wraps=interceptor._update_client_call_details_metadata
        ) as mock_updater:
            interceptor.intercept_unary_unary(
                mock_continuation,
                mock_client_call_details,
                mock_request)

            mock_updater.assert_called_once_with(
                mock_client_call_details, [mock_client_call_details.metadata[0],
                                           interceptor.developer_token_meta,
                                           interceptor.login_customer_id_meta])

            mock_continuation.assert_called_once()

class LoggingInterceptorTest(TestCase):
    """Tests for the google.ads.googleads.client.LoggingInterceptor class."""

    _MOCK_CONFIG = {'test': True}
    _MOCK_ENDPOINT = 'www.test-endpoint.com'
    _MOCK_INITIAL_METADATA = [('developer-token', '123456'),
                              ('header', 'value')]
    _MOCK_CUSTOMER_ID = '123456'
    _MOCK_REQUEST_ID = '654321xyz'
    _MOCK_METHOD = 'test/method'
    _MOCK_TRAILING_METADATA = (('request-id', _MOCK_REQUEST_ID),)
    _MOCK_ERROR_MESSAGE = 'Test error message'
    _MOCK_TRANSPORT_ERROR_MESSAGE = u'Received RST_STREAM with error code 2'
    _MOCK_DEBUG_ERROR_STRING = u'{"description":"Error received from peer"}'

    def _create_test_interceptor(self, config=_MOCK_CONFIG,
                                 endpoint=_MOCK_ENDPOINT):
        """Creates a LoggingInterceptor instance.

        Accepts parameters that are used to override defaults when needed
        for testing.

        Returns:
            A LoggingInterceptor instance.

        Args:
            config: A dict configuration
            endpoint: A str representing an endpoint
        """
        return google.ads.google_ads.client.LoggingInterceptor(config, endpoint)

    def _get_mock_client_call_details(self):
        """Generates a mock client_call_details object for use in tests.

        Returns:
            A Mock instance with "method" and "metadata" attributes.
        """
        mock_client_call_details = mock.Mock()
        mock_client_call_details.method = self._MOCK_METHOD
        mock_client_call_details.metadata = self._MOCK_INITIAL_METADATA
        return mock_client_call_details

    def _get_mock_request(self):
        """Generates a mock request object for use in tests.

        Returns:
            A Mock instance with a "customer_id" attribute.
        """
        mock_request = mock.Mock()
        mock_request.customer_id = self._MOCK_CUSTOMER_ID
        return mock_request

    def _get_trailing_metadata_fn(self):
        """Generates a mock trailing_metadata function used for testing.

        Returns:
            A function that returns a tuple of mock metadata.
        """
        def mock_trailing_metadata_fn():
            return self._MOCK_TRAILING_METADATA

        return mock_trailing_metadata_fn

    def _get_mock_exception(self):
        """Generates a mock GoogleAdsException exception instance for testing.

        Returns:
            A Mock instance with the following attributes - "message",
            "request_id", "failure", and "error." The "failure" attribute has an
            "error" attribute that is an array of mock error objects, and the
            "error" attribute is an object with a "trailing_metadata" method
            that returns a tuble of mock metadata.
        """
        exception = mock.Mock()
        error = mock.Mock()
        error.message = self._MOCK_ERROR_MESSAGE
        exception.request_id = self._MOCK_REQUEST_ID
        exception.failure = mock.Mock()
        exception.failure.errors = [error]
        exception.error = mock.Mock()
        exception.error.trailing_metadata = self._get_trailing_metadata_fn()
        return exception

    def _get_mock_transport_exception(self):
        """Generates a mock gRPC transport error.

        Specifically an error not generated by the Google Ads API and that
        is not an instance of GoogleAdsException.

        Returns:
            A Mock instance with mock "debug_error_string," "details," and
            trailing_metadata" methods.
        """
        def _mock_debug_error_string():
            return self._MOCK_DEBUG_ERROR_STRING

        def _mock_details():
            return self._MOCK_TRANSPORT_ERROR_MESSAGE

        def _mock_trailing_metadata():
            return self._MOCK_TRAILING_METADATA

        exception = mock.Mock()
        exception.debug_error_string = _mock_debug_error_string
        exception.details = _mock_details
        exception.trailing_metadata = _mock_trailing_metadata
        # These attributes are explicitly deleted because they will otherwise
        # get mocked automatically and not generate AttributeErrors that trigger
        # default values in certain helper methods.
        del exception.error
        del exception.failure
        return exception

    def _get_mock_response(self, failed=False):
        """Generates a mock response object for use in tests.

        Accepts a "failed" param that tells the returned mocked response to
        mimic a failed response.

        Returns:
            A Mock instance with mock "exception" and "trailing_metadata"
            methods

        Args:
            failed: a bool indicating whether the mock response should be in a
            failed state or not. Default is False.
        """
        def mock_exception_fn():
            if failed:
                return self._get_mock_exception()
            return None

        mock_response = mock.Mock()
        mock_response.exception = mock_exception_fn
        mock_response.trailing_metadata = self._get_trailing_metadata_fn()
        return mock_response

    def _get_mock_continuation_fn(self, fail=False):
        """Generates a mock continuation function for use in tests.

        Accepts a "failed" param that tell the function to return a failed
        mock response or not.

        Returns:
            A function that returns a mock response object.

        Args:
            failed: a bool indicating whether the function should return a
            response that mocks a failure.
        """
        def mock_continuation_fn(client_call_details, request):
            mock_response = self._get_mock_response(fail)
            return mock_response

        return mock_continuation_fn

    def test_init_no_config(self):
        """Unconfigured LoggingInterceptor should not call logging.dictConfig.
        """
        with mock.patch('logging.config.dictConfig') as mock_dictConfig:
            interceptor = google.ads.google_ads.client.LoggingInterceptor()
            mock_dictConfig.assert_not_called()

    def test_init_with_config(self):
        """Configured LoggingInterceptor should call logging.dictConfig.
        """
        config = {'test': True}
        with mock.patch('logging.config.dictConfig') as mock_dictConfig:
            interceptor = google.ads.google_ads.client.LoggingInterceptor(
                config)
            mock_dictConfig.assert_called_once_with(config)

    def test_intercept_unary_unary_unconfigured(self):
        """No _logger methods should be called.

        When intercepting requests, no logging methods should be called if
        LoggingInterceptor was initialized without a configuration.
        """
        mock_client_call_details = self._get_mock_client_call_details()
        mock_continuation_fn = self._get_mock_continuation_fn()
        mock_request = self._get_mock_request()

        with mock.patch(
                'google.ads.google_ads.client.MessageToJson') as mock_formatter:
            # Since logging configuration is global it needs to be reset here
            # so that state from previous tests does not affect these assertions
            logging.disable(logging.CRITICAL)
            logger_spy = mock.Mock(wraps=google.ads.google_ads.client._logger)
            interceptor = google.ads.google_ads.client.LoggingInterceptor()
            interceptor.intercept_unary_unary(
                mock_continuation_fn,
                mock_client_call_details,
                mock_request)

            logger_spy.debug.assert_not_called()
            logger_spy.info.assert_not_called()
            logger_spy.warning.assert_not_called()

    def test_intercept_unary_unary_successful_request(self):
        """_logger.info and _logger.debug should be called.

        LoggingInterceptor should call _logger.info and _logger.debug with
        a specific str parameter when a request succeeds.
        """
        mock_client_call_details = self._get_mock_client_call_details()
        mock_continuation_fn = self._get_mock_continuation_fn()
        mock_request = self._get_mock_request()
        mock_json_message = '{"test": "request-response"}'
        mock_response = mock_continuation_fn(
            mock_client_call_details, mock_request)
        mock_trailing_metadata = mock_response.trailing_metadata()

        with mock.patch('logging.config.dictConfig'), \
            mock.patch('google.ads.google_ads.client._logger') as mock_logger, \
            mock.patch(
                'google.ads.google_ads.client.MessageToJson') as mock_formatter:
            mock_formatter.return_value = mock_json_message
            interceptor = self._create_test_interceptor()
            interceptor.intercept_unary_unary(
                mock_continuation_fn,
                mock_client_call_details,
                mock_request)

            mock_logger.info.assert_called_once_with(
                interceptor._SUMMARY_LOG_LINE
                % (self._MOCK_CUSTOMER_ID, self._MOCK_ENDPOINT,
                    mock_client_call_details.method, self._MOCK_REQUEST_ID,
                    False, None))

            initial_metadata = (google.ads.google_ads.client.
                                _parse_metadata_to_json(
                                    mock_client_call_details.metadata))
            trailing_metadata = (google.ads.google_ads.client.
                                 _parse_metadata_to_json(
                                     mock_trailing_metadata))

            mock_logger.debug.assert_called_once_with(
                interceptor._FULL_REQUEST_LOG_LINE
                % (self._MOCK_METHOD, self._MOCK_ENDPOINT, initial_metadata,
                    mock_json_message, trailing_metadata, mock_json_message))

    def test_intercept_unary_unary_failed_request(self):
        """_logger.warning and _logger.info should be called.

        LoggingInterceptor should call _logger.warning and _logger.info with
        a specific str parameter when a request fails.
        """
        mock_client_call_details = self._get_mock_client_call_details()
        mock_continuation_fn = self._get_mock_continuation_fn(fail=True)
        mock_request = self._get_mock_request()
        mock_json_message = '{"test": "request-response"}'
        mock_response = mock_continuation_fn(
            mock_client_call_details, mock_request)
        mock_trailing_metadata = mock_response.trailing_metadata()

        with mock.patch('logging.config.dictConfig'), \
            mock.patch('google.ads.google_ads.client._logger') as mock_logger, \
            mock.patch(
                'google.ads.google_ads.client.MessageToJson') as mock_formatter:
            mock_formatter.return_value = mock_json_message
            interceptor = self._create_test_interceptor()
            interceptor.intercept_unary_unary(
                mock_continuation_fn,
                mock_client_call_details,
                mock_request)

            mock_logger.warning.assert_called_once_with(
                interceptor._SUMMARY_LOG_LINE
                % (self._MOCK_CUSTOMER_ID, self._MOCK_ENDPOINT,
                    mock_client_call_details.method, self._MOCK_REQUEST_ID,
                    True, self._MOCK_ERROR_MESSAGE))

            initial_metadata = (google.ads.google_ads.client.
                                _parse_metadata_to_json(
                                    mock_client_call_details.metadata))
            trailing_metadata = (google.ads.google_ads.client.
                                 _parse_metadata_to_json(
                                     mock_trailing_metadata))

            mock_logger.info.assert_called_once_with(
                interceptor._FULL_FAULT_LOG_LINE
                % (self._MOCK_METHOD, self._MOCK_ENDPOINT, initial_metadata,
                    mock_json_message, trailing_metadata, mock_json_message))

    def test_get_initial_metadata(self):
        """_Returns a tuple of metadata from client_call_details."""
        with mock.patch('logging.config.dictConfig'):
            mock_client_call_details = mock.Mock()
            mock_client_call_details.metadata = self._MOCK_INITIAL_METADATA
            interceptor = self._create_test_interceptor()
            result = interceptor._get_initial_metadata(mock_client_call_details)
            self.assertEqual(result, self._MOCK_INITIAL_METADATA)

    def test_get_initial_metadata_none(self):
        """Returns an empty tuple if initial_metadata isn't present."""
        with mock.patch('logging.config.dictConfig'):
            mock_client_call_details = {}
            interceptor = self._create_test_interceptor()
            result = interceptor._get_initial_metadata(mock_client_call_details)
            self.assertEqual(result, tuple())

    def test_get_call_method(self):
        """Returns a str of the call method from client_call_details"""
        with mock.patch('logging.config.dictConfig'):
            mock_client_call_details = mock.Mock()
            mock_client_call_details.method = self._MOCK_METHOD
            interceptor = self._create_test_interceptor()
            result = interceptor._get_call_method(mock_client_call_details)
            self.assertEqual(result, self._MOCK_METHOD)

    def test_get_call_method_none(self):
        """Returns None if method is not present on client_call_details."""
        with mock.patch('logging.config.dictConfig'):
            mock_client_call_details = {}
            interceptor = self._create_test_interceptor()
            result = interceptor._get_call_method(mock_client_call_details)
            self.assertEqual(result, None)

    def test_get_request_id(self):
        """Returns a request ID str from a response object."""
        with mock.patch('logging.config.dictConfig'):
            mock_response = self._get_mock_response()
            mock_exception = None
            interceptor = self._create_test_interceptor()
            result = interceptor._get_request_id(mock_response, mock_exception)
            self.assertEqual(result, self._MOCK_REQUEST_ID)

    def test_get_request_id_google_ads_failure(self):
        """Returns a request ID str from a GoogleAdsException instance."""
        with mock.patch('logging.config.dictConfig'):
            mock_response = self._get_mock_response(failed=True)
            mock_exception = mock_response.exception()
            interceptor = self._create_test_interceptor()
            result = interceptor._get_request_id(mock_response, mock_exception)
            self.assertEqual(result, self._MOCK_REQUEST_ID)

    def test_get_request_id_transport_failure(self):
        """Returns None if there is no request_id on the exception."""
        with mock.patch('logging.config.dictConfig'):
            mock_response = self._get_mock_response(failed=True)
            mock_exception = mock_response.exception()
            # exceptions on transport errors have no request_id because they
            # don't interact with a server that can provide one.
            del mock_exception.request_id
            interceptor = self._create_test_interceptor()
            result = interceptor._get_request_id(mock_response, mock_exception)
            self.assertEqual(result, None)

    def test_parse_response_to_json(self):
        """Calls MessageToJson with a successful response message."""
        with mock.patch('logging.config.dictConfig'), \
            mock.patch(
                'google.ads.google_ads.client.MessageToJson') as mock_formatter:
            mock_response = self._get_mock_response()
            mock_exception = mock_response.exception()
            interceptor = self._create_test_interceptor()
            interceptor._parse_response_to_json(mock_response, mock_exception)
            mock_formatter.assert_called_once_with(mock_response.result())

    def test_parse_response_to_json_google_ads_failure(self):
        """Calls MessageToJson with a GoogleAdsException."""
        with mock.patch('logging.config.dictConfig'), \
            mock.patch(
                'google.ads.google_ads.client.MessageToJson') as mock_formatter:
            mock_response = mock.Mock()
            mock_exception = self._get_mock_exception()
            interceptor = self._create_test_interceptor()
            interceptor._parse_response_to_json(mock_response, mock_exception)
            mock_formatter.assert_called_once_with(mock_exception.failure)

    def test_parse_response_to_json_transport_failure(self):
        """ Calls _parse_to_json with transport error's debug_error_string."""
        with mock.patch('logging.config.dictConfig'), \
            mock.patch(
                'google.ads.google_ads.client._parse_to_json') as mock_parser:
            mock_response = mock.Mock()
            mock_exception = self._get_mock_transport_exception()
            interceptor = self._create_test_interceptor()
            interceptor._parse_response_to_json(mock_response, mock_exception)
            mock_parser.assert_called_once_with(
                json.loads(self._MOCK_DEBUG_ERROR_STRING))

    def test_parse_response_to_json_unknown_failure(self):
        """Returns an empty JSON string if nothing can be parsed to JSON."""
        with mock.patch('logging.config.dictConfig'):
            mock_response = mock.Mock()
            mock_exception = mock.Mock()
            del mock_exception.failure
            del mock_exception.debug_error_string
            interceptor = self._create_test_interceptor()
            result = interceptor._parse_response_to_json(
                mock_response, mock_exception)
            self.assertEqual(result, '{}')

    def test_get_trailing_metadata(self):
        """Retrieves metadata from a response object."""
        with mock.patch('logging.config.dictConfig'):
            mock_response = self._get_mock_response()
            mock_exception = mock_response.exception()
            interceptor = self._create_test_interceptor()
            result = interceptor._get_trailing_metadata(
                mock_response, mock_exception)
            self.assertEqual(result, self._MOCK_TRAILING_METADATA)

    def test_get_trailing_metadata_google_ads_failure(self):
        """Retrieves metadata from a failed response."""
        with mock.patch('logging.config.dictConfig'):
            mock_response = self._get_mock_response(failed=True)
            mock_exception = mock_response.exception()
            interceptor = self._create_test_interceptor()
            result = interceptor._get_trailing_metadata(
                mock_response, mock_exception)
            self.assertEqual(result, self._MOCK_TRAILING_METADATA)

    def test_get_trailing_metadata_transport_failure(self):
        """Retrieves metadata from a transport error."""
        with mock.patch('logging.config.dictConfig'):
            mock_response = mock.Mock()
            mock_exception = self._get_mock_transport_exception()
            interceptor = self._create_test_interceptor()
            result = interceptor._get_trailing_metadata(
                mock_response, mock_exception)
            self.assertEqual(result, self._MOCK_TRAILING_METADATA)

    def test_get_trailing_metadata_unknown_failure(self):
        """Returns an empty tuple if metadata cannot be found."""
        with mock.patch('logging.config.dictConfig'):
            mock_response = {}
            mock_exception = self._get_mock_transport_exception()
            del mock_exception.trailing_metadata
            interceptor = self._create_test_interceptor()
            result = interceptor._get_trailing_metadata(
                mock_response, mock_exception)
            self.assertEqual(result, tuple())

    def test_get_fault_message(self):
        """Returns None if an error message cannot be found."""
        with mock.patch('logging.config.dictConfig'):
            mock_exception = None
            interceptor = self._create_test_interceptor()
            result = interceptor._get_fault_message(mock_exception)
            self.assertEqual(result, None)

    def test_get_fault_message_google_ads_failure(self):
        """Retrieves an error message from a GoogleAdsException."""
        with mock.patch('logging.config.dictConfig'):
            mock_exception = self._get_mock_exception()
            interceptor = self._create_test_interceptor()
            result = interceptor._get_fault_message(mock_exception)
            self.assertEqual(result, self._MOCK_ERROR_MESSAGE)

    def test_get_fault_message_transport_failure(self):
        """Retrieves an error message from a transport error object."""
        with mock.patch('logging.config.dictConfig'):
            mock_exception = self._get_mock_transport_exception()
            interceptor = self._create_test_interceptor()
            result = interceptor._get_fault_message(mock_exception)
            self.assertEqual(result, self._MOCK_TRANSPORT_ERROR_MESSAGE)

class ExceptionInterceptorTest(TestCase):
    """Tests for the google.ads.googleads.client.ExceptionInterceptor class."""

    _MOCK_FAILURE_VALUE = b"\n \n\x02\x08\x10\x12\x1aInvalid customer ID '123'."

    def _create_test_interceptor(self):
        """Creates and returns an ExceptionInterceptor instance

        Returns:
            An ExceptionInterceptor instance.
        """
        return google.ads.google_ads.client.ExceptionInterceptor()

    def test_init_(self):
        """Tests that the interceptor initializes properly"""
        interceptor = self._create_test_interceptor()
        self.assertEqual(interceptor._RETRY_STATUS_CODES,
                         (grpc.StatusCode.INTERNAL,
                          grpc.StatusCode.RESOURCE_EXHAUSTED))

    def test_get_request_id(self):
        """_get_request_id obtains a request ID from a metadata tuple"""
        mock_metadata = (('request-id', '123456'),)
        interceptor = self._create_test_interceptor()
        result = interceptor._get_request_id(mock_metadata)
        self.assertEqual(result, '123456')

    def test_get_request_id_no_id(self):
        """Returns None if the given metadata does not contain a request ID."""
        mock_metadata = (('another-key', 'another-val'),)
        interceptor = self._create_test_interceptor()
        result = interceptor._get_request_id(mock_metadata)
        self.assertEqual(result, None)

    def test_get_google_ads_failure(self):
        """Obtains the content of a google ads failure from metadata."""
        interceptor = self._create_test_interceptor()
        mock_metadata = ((interceptor._failure_key, self._MOCK_FAILURE_VALUE),)
        result = interceptor._get_google_ads_failure(mock_metadata)
        self.assertIsInstance(result, error_protos.GoogleAdsFailure)

    def test_get_google_ads_failure_decode_error(self):
        """Returns none if the google ads failure cannot be decoded."""
        interceptor = self._create_test_interceptor()
        mock_failure_value = self._MOCK_FAILURE_VALUE + b'1234'
        mock_metadata = ((interceptor._failure_key, mock_failure_value),)
        result = interceptor._get_google_ads_failure(mock_metadata)
        self.assertEqual(result, None)

    def test_get_google_ads_failure_no_failure_key(self):
        """Returns None if an error cannot be found in metadata."""
        mock_metadata = (('another-key', 'another-val'),)
        interceptor = self._create_test_interceptor()
        result = interceptor._get_google_ads_failure(mock_metadata)
        self.assertEqual(result, None)

    def test_get_google_ads_failure_with_None(self):
        """Returns None if None is passed."""
        interceptor = self._create_test_interceptor()
        result = interceptor._get_google_ads_failure(None)
        self.assertEqual(result, None)

    def test_handle_grpc_failure(self):
        """Raises non-retryable GoogleAdsFailures as GoogleAdsExceptions."""
        mock_error_message = self._MOCK_FAILURE_VALUE

        class MockRpcErrorResponse(grpc.RpcError):
            def code(self):
                return grpc.StatusCode.INVALID_ARGUMENT

            def trailing_metadata(self):
                return ((interceptor._failure_key, mock_error_message),)

            def exception(self):
                return self

        interceptor = self._create_test_interceptor()

        self.assertRaises(GoogleAdsException,
                          interceptor._handle_grpc_failure,
                          MockRpcErrorResponse())

    def test_handle_grpc_failure_retryable(self):
        """Raises retryable exceptions as-is."""
        class MockRpcErrorResponse(grpc.RpcError):
            def code(self):
                return grpc.StatusCode.INTERNAL

            def exception(self):
                return self

        interceptor = self._create_test_interceptor()

        self.assertRaises(MockRpcErrorResponse,
                          interceptor._handle_grpc_failure,
                          MockRpcErrorResponse())

    def test_handle_grpc_failure_not_google_ads_failure(self):
        """Raises as-is non-retryable non-GoogleAdsFailure exceptions."""
        class MockRpcErrorResponse(grpc.RpcError):
            def code(self):
                return grpc.StatusCode.INVALID_ARGUMENT

            def trailing_metadata(self):
                return (('bad-failure-key', 'arbitrary-value'),)

            def exception(self):
                return self

        interceptor = self._create_test_interceptor()

        self.assertRaises(MockRpcErrorResponse,
                          interceptor._handle_grpc_failure,
                          MockRpcErrorResponse())

    def test_intercept_unary_unary_response_is_exception(self):
        """If response.exception() is not None exception is handled."""
        mock_exception = grpc.RpcError()

        class MockResponse():
            def exception(self):
                return mock_exception

        mock_request = mock.Mock()
        mock_client_call_details = mock.Mock()
        mock_response = MockResponse()

        def mock_continuation(client_call_details, request):
            del client_call_details
            del request
            return mock_response

        interceptor = self._create_test_interceptor()

        with mock.patch.object(interceptor, '_handle_grpc_failure'):
            interceptor.intercept_unary_unary(
                mock_continuation, mock_client_call_details, mock_request)

            interceptor._handle_grpc_failure.assert_called_once_with(
                mock_response)

    def test_intercept_unary_unary_response_is_successful(self):
        """If response.exception() is None response is returned."""
        class MockResponse():
            def exception(self):
                return None

        mock_request = mock.Mock()
        mock_client_call_details = mock.Mock()
        mock_response = MockResponse()

        def mock_continuation(client_call_details, request):
            del client_call_details
            del request
            return mock_response

        interceptor = self._create_test_interceptor()

        result = interceptor.intercept_unary_unary(
            mock_continuation, mock_client_call_details, mock_request)

        self.assertEqual(result, mock_response)


# Below is my solution for practice problem: https://leetcode.com/explore/learn/card/fun-with-arrays/521/introduction/3238/

# This solution has :
# space complexity :: O(1)
# Time Complexity :: O(n)

class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int: ## this is how we defined a function
        final = 0  ## created this variable to store the final count value of 1's that is maximum
        c = 0   ## created this variable to store the value of count of 1's as we go through the for loop
        for _ in nums:  ## loop is used to read each value of array one by one
            if _ == 0: ## checking the value of array as "0" to reset the counter
                c = 0
            else:
                c += 1 ## increment the counter value for all consecutive one's
            final = max(c,final) ## assigning max value to final variable in each iteration
        return final


import json
import boto3
from boto3.dynamodb.conditions import Key, Attr
from decimal import Decimal

dynamo_client = boto3.resource('dynamodb')
broker_table = dynamo_client.Table('broker_users')
carrier_table = dynamo_client.Table('carrier_users')

response = carrier_table.scan()
carrier_emails = []
for i in response['Items']:
    carrier_emails.append(i['email'])

def lambda_handler(event, context):
    userEmail = event["userEmail"]
    broker = broker_table.get_item(
        Key={
            "email": userEmail
        }
    )
    contact_email_list = broker.get('Item', {}).get('contacts', [])
    new_contact_list = []
    new_user_list = []
    for contact in event.get('contacts', []):
        if contact['Email'] not in carrier_emails:
            newCarrier = {}
            newCarrier['email'] = contact['Email']
            newCarrier['companyName'] = contact.get('Company Name', '')
            newCarrier['carrierName'] = contact.get('First Name', '') + ' ' + contact.get('Last Name', '')
            newCarrier['contacts'] = [userEmail]
            newCarrier['temp'] = True
            carrier_table.put_item(
                Item=newCarrier
            )
            new_contact_list.append(contact)
            new_user_list.append(contact)

        if contact['Email'] not in contact_email_list:
            contact_email_list.append(contact['Email'])
    try:
        broker_table.update_item(
            Key={'email': userEmail},
            UpdateExpression='SET #attr1 = :val1',
            ConditionExpression=(
                'email = :email'
            ),
            ExpressionAttributeNames={'#attr1': 'contacts'},
            ExpressionAttributeValues={':email': userEmail, ':val1': contact_email_list},
            ReturnValues='UPDATED_NEW'
        )
        return {
            'statusCode': 200,
            'newContacts': new_user_list
        }
    except Exception as e:
        return {
            "statusCode": 500,
            "message": e
        }


import argparse, os
from reader import Reader

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Reader of MongoDB documents.')

    parser.add_argument('--start', action='store', type=int, default=0,
                    help='The document number to start with (default 0)')
    parser.add_argument('--end', action='store', type=int,
                    help='The document number to end with (default last)')
    parser.add_argument('--size', action='store', type=int, default=10,
                    help='The document count to handle (default 10)')
    parser.add_argument('--config', action='store', type=str,
                    help='The configuration file to use.')
    args = parser.parse_args()
    filename = os.path.dirname(os.path.realpath(__file__)) + args.config
    print("filename", filename)
    reader = Reader(args.start, args.end, args.size, filename)
    reader.run()