# -*- coding: utf-8 -*-

import math
import random
import hashlib
import numpy 

def OUEParams(epsilon):
    """计算OUE法扰动概率"""
    # epsilon 隐私预算
    
    temp_data=math.pow(math.e,epsilon)
    prob_p1 =0.5
    prob_q1 =0.5
    prob_p2 = float(temp_data)/(temp_data+1)
    prob_q2 = 1.0/(temp_data+1)
    
    return [prob_p1,prob_q1,prob_p2,prob_q2]

def NIndexJudgeLocation(single_user_data,x_coordinate,y_coordinate):
    """不使用索引情况下，判断用户数据的位置"""
    # single_user_data 单个用户数据，形式为['x','y']
    # x_coordinate x轴区间范围，形式为[[a,b],[c,d],[]]
    # y_coordinate y轴区间范围，形式为[[a,b],[c,d],[]]
    
    for i in xrange(len(x_coordinate)):
        temp1=x_coordinate[i][0]
        temp2=x_coordinate[i][1]
        if temp1<=float(single_user_data[0])<temp2:
            x_index=i
            break
    for j in xrange(len(y_coordinate)):
        temp3=y_coordinate[j][0]
        temp4=y_coordinate[j][1]
        if temp3<=float(single_user_data[1])<temp4:
            y_index=j
            break
    single_user_data_index=x_index*len(y_coordinate)+y_index # 计算用户数据在所有数据中的位置
    
    return single_user_data_index

def NIndexDisturbSingleData(single_user_data_index,oue_params,grid_number):
    """扰动单个用户数据"""
    # single_user_data_index 单个用户数据索引
    # oue_params OUE法扰动概率
    # grid_number 网格个数
    
    prob_p1=oue_params[0]
    prob_p2=oue_params[2]
    noise_single_user_data=[0 for _ in xrange(grid_number)]
    
    for i in xrange(grid_number):
        temp_number=random.random()
        if temp_number < prob_p2: 
            noise_single_user_data[i]=0
        else:
            noise_single_user_data[i]=1
    
    temp_number=random.random()
    if temp_number < prob_p1: 
        noise_single_user_data[single_user_data_index]=1
    else:
        noise_single_user_data[single_user_data_index]=0
    
    return noise_single_user_data
    
def SUMlist(list1,list2):
    """将两个等长的数值list对应位置做加和""" 
    # list1 列表1
    # list2 列表2
    
    temp1=numpy.array(list1)
    temp2=numpy.array(list2)
    temp3=list(temp1+temp2)
    
    return temp3
    
def NIndexOUEDAAllData(all_user_data,x_coordinate,y_coordinate,oue_params,grid_number):
    """扰动所有用户数据，并求加和值"""
    # all_user_data 所有用户数据列表
    # x_coordinate x轴区间范围，形式为[[a,b],[c,d],[]]
    # y_coordinate y轴区间范围，形式为[[a,b],[c,d],[]]
    # oue_params OUE法扰动概率
    # grid_number 网格个数
    
    noise_aggregate_all_data=[0 for _ in xrange(grid_number)] # 噪声数据加和值
    
    for i in all_user_data:
        single_user_data_index=NIndexJudgeLocation(i,x_coordinate,y_coordinate)
        noise_single_user_data=NIndexDisturbSingleData(single_user_data_index,oue_params,grid_number)
        noise_aggregate_all_data=SUMlist(noise_single_user_data,noise_aggregate_all_data)
    
    return noise_aggregate_all_data


  
    
    
    
    