package com.ibm.personafusion.model;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;
public class Person implements Comparable<Person>
{
public String name;
public List<Trait> traits;
public enum Role {DEV, Manager};
public Role role;
public ResumeInfo resumeInfo;
//This will be the list of answers from the q & a of the person
//index 0 response to question 1, index 1 response to question 2 etc...
public List<String> qaResponses;
public String image_url;
public List<String> keyWords;
//one queryPerson for everyone
static Person queryPerson;
//different distances for everyone
public double distToQueryPerson;
public String group;
//one set of weights for everyone
static double weightTraits, weightResume, weightRole;
public Person(String name, List<Trait> traits, String image_url, ResumeInfo resumeInfo, Role role, List<String> keyWords)
{
this.name = name;
this.traits = traits;
this.resumeInfo = resumeInfo;
this.role = role;
//Set default weights
this.weightTraits = 1;
this.weightResume = 1;
this.weightRole = 1;
this.image_url = image_url;
this.qaResponses = new ArrayList<String>();
this.keyWords = keyWords;
}
public Person(String name, List<Trait> traits, ResumeInfo resumeInfo)
{
this.name = name;
this.traits = traits;
this.resumeInfo = resumeInfo;
this.role = role;
//Set default weights
this.weightTraits = 1;
this.weightResume = 1;
this.weightRole = 1;
this.image_url = "";
this.role = Role.DEV;
this.qaResponses = new ArrayList<String>();
this.keyWords = new ArrayList<String>();
}
public void setQueryPerson(Person p)
{
this.queryPerson = p;
}
public String toString()
{
String pString = "";
pString = traits.toString();
//pString = this.name + " , " + this.distToQueryPerson;
return pString;
}
public List<FollowUp> getFollowUp() {
return Collections.singletonList(new FollowUp(name, image_url, role));
}
public void setDistanceWeights(double weightTraits, double weightResume, double weightRole)
{
this.weightTraits = weightTraits;
this.weightResume = weightResume;
this.weightRole = weightRole;
}
/*
* Remove stop words and return N most frequent words
*/
public List<String> getKeyWords(int nMostFrequent)
{
List<String> stopWords = new ArrayList<String>();
try
{
URL url = new URL("https://dl.dropboxusercontent.com/u/27101002/personafusion/stopWords.txt");
Scanner sc = new Scanner(url.openStream());
while(sc.hasNextLine())
{
String word = sc.nextLine();
word = word.trim();
stopWords.add(word);
}
}
catch(Exception e)
{
e.printStackTrace();
}
List<String> keyWords = new ArrayList<String>();
Map<String, Integer> keyMapCount = new TreeMap<String, Integer>();
for(String tweet : this.qaResponses)
{
String[] tweetParts = tweet.split(" ");
for(String tweetWord : tweetParts)
{
if(tweetWord.length() < 2)
continue;
tweetWord = tweetWord.toLowerCase();
if(keyMapCount.containsKey(tweetWord))
{
int value = keyMapCount.get(tweetWord);
keyMapCount.put(tweetWord, value+1);
}
else
{
keyMapCount.put(tweetWord, 1);
}
}
}
List<TweetTerm> termList = new ArrayList<TweetTerm>();
List<String> stopWordsLower = new ArrayList<String>();
for(String stopWord : stopWords)
stopWordsLower.add(stopWord.toLowerCase());
for(String tweetWord : keyMapCount.keySet())
{
//tweetWord = tweetWord.toLowerCase();
//System.out.println(tweetWord);
//System.out.println(keyMapCount.get(tweetWord));
String tempTweet = tweetWord.toLowerCase();
boolean cleanTweet = true;
String alph = "abcdefghijklmnopqrstuvwxyz";
for(char c : tempTweet.toCharArray())
if(!alph.contains(c + ""))
{
cleanTweet = false;
}
//System.out.println(tempTweet);
if(!cleanTweet) continue;
if(!stopWordsLower.contains(tempTweet))
termList.add(new TweetTerm(tweetWord, keyMapCount.get(tweetWord)));
}
Collections.sort(termList);
for(int i=0; i<nMostFrequent; i++)
{
if (i == termList.size()) break;
keyWords.add(termList.get(i).word);
}
return keyWords;
}
class TweetTerm implements Comparable<TweetTerm>
{
String word;
int wordCount;
TweetTerm(String word, int wordCount)
{
this.word = word;
this.wordCount = wordCount;
}
public int compareTo(TweetTerm other)
{
return other.wordCount - this.wordCount;
}
}
double getDistanceToQueryPerson()
{
double distance = 0, distanceTraits = 0, distanceResume = 0, distanceRole = 0;
for(int i=0; i<this.queryPerson.traits.size(); i++)
{
String queryTraitName = this.queryPerson.traits.get(i).traitName;
double queryTraitPercent = this.queryPerson.traits.get(i).percent;
distanceTraits += this.getTraitDistance(queryTraitName, queryTraitPercent);
}
double distanceTechSkills = 0, distancePastEmployers = 0;
for(int i=0; i<this.queryPerson.resumeInfo.techSkills.size(); i++)
{
//if all query tech skills exist in this person distance is 0
//distance grows as skills dont match
String techSkill = this.queryPerson.resumeInfo.techSkills.get(i);
if(!this.resumeInfo.techSkills.contains(techSkill))
distanceTechSkills++;
}
for(int i=0; i<this.queryPerson.resumeInfo.pastEmployers.size(); i++)
{
String pastEmployer = this.queryPerson.resumeInfo.pastEmployers.get(i);
if(!this.resumeInfo.techSkills.contains(pastEmployer))
distancePastEmployers++;
}
distanceResume = (.75 * distancePastEmployers) + (.25 * distanceTechSkills);
if(!this.queryPerson.role.equals(this.role))
distanceRole = 1;
distance = (weightTraits * distanceTraits) + (weightResume * distanceResume) + (weightRole * distanceRole);
this.distToQueryPerson = distance;
return distance;
}
double getTraitDistance(String queryTrait, double queryScore)
{
double distance = 1;//worst case if the trait does not exist return max value 1
for(int i=0; i<this.traits.size(); i++)
{
if(queryTrait.equals(this.traits.get(i).traitName))
{
double tempDist = (queryScore/100.0) - (this.traits.get(i).percent/100.0);
distance = Math.pow(tempDist, 2);
break;//found trait distance break loop
}
}
return distance;
}
public int compareTo(Person other)
{
//sort bases off min distance from query perosn
//weight different distances between resume skills, traits, and role
double thisDistance = this.getDistanceToQueryPerson();
double otherDistance = other.getDistanceToQueryPerson();
if(thisDistance < otherDistance)
return -1;
if(thisDistance > otherDistance)
return 1;
else
return 0;
}
}