#!/usr/bin/env python3 import sys sys.path.insert(1, 'lib') import argparse import csv from datetime import datetime from geopy.distance import distance import io import itertools import lmdk_lib import numpy as np import os import matplotlib.pyplot as plt import time import zipfile # https://cloud.delkappa.com/s/ACMsDr2jnW3b6Np # Copenhagen data format # Header size hdr = 1 # Timestamp tim = 0 # User ID A uid_a = 1 # User ID B uid_b = 2 # Received Signal Strength Indicator (RSSI) rssi = 3 def main(args): # Get contacts from previous parsing cont_data = lmdk_lib.load_data(args, 'cont') if cont_data.size == 0: # Contacts [tim, uid_a, uid_b, rssi] cont = [] try: print('Extracting %s... ' %(os.path.abspath(args.arc)), end='', flush=True) with zipfile.ZipFile(args.arc, 'r') as arc: print('[OK]') with io.TextIOWrapper(arc.open(args.cont), newline='\n') as dat: try: print('Finding contacts... ', end='', flush=True) # Get the contacts by skipping the header cont_l = list(csv.reader(dat, delimiter=','))[hdr:] # Check each contact for c in cont_l: if c[uid_b] != '-1' and c[rssi] != '0' and c[uid_b] != '-2' and c[uid_a] != c[uid_b]: # Add valid contact cont.append([c[tim], c[uid_a], c[uid_b], c[rssi]]) print('[OK]') except Exception as e: print('[Error: %s]' %(e)) except Exception as e: print('[Error: %s]' %(e)) # Save to results lmdk_lib.save_data(args, np.array(cont, np.float32), 'cont') # Get all users usrs = np.unique(np.concatenate((cont_data[:, uid_a], cont_data[:, uid_b]), 0)) # Check each user goal = [.2, .4, .6, .8, 1] # Users suitable for experiments usrs_expt = [] for usr_i, usr in enumerate(usrs): print('Checking %d (%d%%: %d/%d)... ' %(usr, (usr_i + 1)*100/len(usrs), usr_i + 1, len(usrs)), end='', flush=True) # User's contacts usr_cont = cont_data[(cont_data[:, uid_a] == usr) | (cont_data[:, uid_b] == usr)] # For each goal for_expt = True for g in goal: if for_expt: # Possible contacts pos_cont = [] usrs_cur = list(usrs) # Remove user usrs_cur.remove(usr) # Check for every possible contact for u in usrs_cur: # Add possible contacts gradually pos_cont.append(u) # Remove from user contacts usr_cont_cur = np.copy(usr_cont) for pos_c in pos_cont: usr_cont_cur = usr_cont_cur[(usr_cont_cur[:, uid_a] != pos_c) & (usr_cont_cur[:, uid_b] != pos_c)] # Compare the difference diff = (len(usr_cont) - len(usr_cont_cur))/len(usr_cont) # Check if it's close enough to what we need if abs(diff - g)/g < .025: usrs_expt.append([usr, g, pos_cont]) if g == 1: # That's a keeper print('[OK]') break elif diff > g: print('[NOK]') for_expt = False break # Save to results lmdk_lib.save_data(args, np.array(usrs_expt, str), 'usrs_expt') ''' Parse arguments. Optional: arc - The data archive file. cont - The contacts data file. res - The results archive file. ''' def parse_args(): # Create argument parser. parser = argparse.ArgumentParser() # Mandatory arguments. # Optional arguments. parser.add_argument('-a', '--arc', help='The data archive file.', type=str, default='/home/manos/Cloud/Data/Copenhagen/Data.zip') parser.add_argument('-c', '--cont', help='The contacts data file.', type=str, default='bt_symmetric.csv') parser.add_argument('-r', '--res', help='The results archive file.', type=str, default='/home/manos/Cloud/Data/Copenhagen/Results.zip') # Parse arguments. args = parser.parse_args() return args if __name__ == '__main__': try: start_time = time.time() main(parse_args()) end_time = time.time() print('##############################') print('Time : %.4fs' % (end_time - start_time)) print('##############################') except KeyboardInterrupt: print('Interrupted by user.') exit()