Infectious Disease Program Page

From CSclasswiki
Jump to: navigation, search

Go back to: Visualizing the Transit Map of the Spread of an Infectious Disease


Basic Structures (Infectious Disease Project)

--Kyra Gan 02:28, 17 March 2016 (EDT)

Constants.java


import java.util.Hashtable;

/**
*@author Kyra Gan
*@version 4/20/2016
* This class controls all the exogenous variables that can be modified for the purpose of 
* each individual simulation.
* Those variables includes: iterationPeriod, incubationLimit, contagiousLimit, setLog (boolean)(for debug),
* infectionProbability, edgeDiscountFactor, the whole campus data csv file name, the output csv file name,
* deterministic (boolean), stochastic volatility (sigma), vaccination (boolean), vaccipercentage, 
* vaccineContagiousProbability (the probability of a vaccinated student being a virus carrier), 
* setFirstInKey (boolean), firstInKey, quarantine (boolean), quarantineSize, quarantineHouse (boolean), 
* nodesSize.
*/
public class Constants {
	static int iterationPeriod=60;
	static int incubationLimit=6;
	static int contagiousLimit=8;
	
	public static boolean setLog=false;
	
	static float infectionProbability= (float)(0.01);
	
	/**
	 * Def: edgeDiscountFactor=(actual time length)/target time length
	 * i.e. we do not differentiate within the edgeDicountFactor unit of days
	 */
	static float edgeDiscountFactor=incubationLimit/2; //1;
	
	public static String file="TestData5.csv";
	public static String saveFileAs="remissionHT";
	
	
	public static boolean deterministic=true;
	static float sigma=(float) 1; //amplitude of the stochastic noise term
	
	/**
	 * vaccination controls whether we distribute vaccines in the population
	 * the default percentage of population receive vaccines is 0.1
	 * the default probability of a vaccinated person being a carrier of the virus
	 * is 0.005, and she has the same probability of infecting other people as a 
	 * infected person
	 * vaccineID keep tracks of all the students that are vaccinated
	 * we use hashtable for vaccineID because containskey will be called very often; the Integer is 
	 * preserve for the probability of infecting other people or probability become 
	 * contagious (for now, it does not mean anything)
	 */
	public static boolean vaccination=false;
	static float vaccipercentage=(float) 0.5;
	static float vaccineContagiuosProbability=(float) 0.001;
	static Hashtable<String,Integer> vaccineID=new Hashtable<String,Integer>();

	
	/**
	 * in order to run comparison, we want to have the fisrtInKey to be the same for
	 * a series of graphs. Then we can call the following variable;
	 */
	public static boolean setFirstInKey=true;
	static String firstInKey="82";
	
	
	/**
	 * quarantine controls whether we stop a class that contains more than 40 students
	 * note, we are not going to eliminate the contacts between students in the house
	 */
	public static boolean quarantine=false;
	static int quarantineSize=30;
	public static boolean quarantineHouse=true;
	
	/**
	 * nodeSize is used when we are generating the dot file in ToDot class
	 */
	static double nodeSize=0.6;
	

}


Time.java


/**
 * @author kyragan
 * @version:4/20/2016
 * This class is stores all the necessary information about time when an event happens;
 * it contains four fields: date (when the event happens), startT (of the event),
 * endT (of the event), and daycount(the duration of the event). Date takes seven values, 
 * Mon - Su. 
 * The class has two constructors. 
 * The main methods in the class are 
 * increaseDaycount(), timeOrder() (which allows one to sort time from Mon-Su in a week),
 * dayOfTheWeek() (returns the index of the date +1), equals(Time time2) (compares two time unit),
 * toString(), and toCSV()
 */
import java.util.Arrays;
import java.util.List;

public class Time {
	final String date; // Mon,Tu,Wed,Th,Fri,Sa,Su
	final int startT; // want them to be integer so we can take the difference later
	int endT=-1; // we set -1 to be the null case (it is going to be 0 in some case in
				// some status related classes)
	int daycount=0; //this variable is going to be used in the status hash table ONLY
					//for the purpose of clarity, we will only use day count the 
					//length between startT and endT
					//the null is 0
	List<String> DDate=Arrays.asList("Mon","Tu","Wed","Th","Fri","Sa","Su");

	public Time(String date,int startT, int endT){
		this.date=date;
		this.startT=startT;
		this.endT=endT;
	}
	
	//for the student status hash table ONLY
	public Time(String date, int startT){
		this.date=date;
		this.startT=startT;
	}
	
	public String getDate(){
		return date;
	}
	
	public int getStartT(){
		return startT;
	}
	
	public int getEndT(){
		return endT;
	}
	
	public int getDaycount(){
		return daycount;
	}
	
	//We are going to use the following 3 methods when simulating the virus spread
	
	public void setEndT(int endT){
		this.endT=endT;
	}
	
	public void setDaycount(int daycount){
		this.daycount=daycount;
	}
	
	public void increaseDaycount(){
		daycount+=1;
	}
	
	//since when adding an entry in PlaceValue and StudentValue
	//we want them to be time ordered, thus we have a timeOrder calculator here
	//timeOrder= a five digit number, where the highest digit=dateIndex,
	//the next four digit is the startT. 
	public int timeOrder(){
		return DDate.indexOf(date)*10000+startT;
	}
	
	public int dayOfTheWeek(){
		return DDate.indexOf(date)+1;
	}
	public String nextDate(){
		return DDate.get((DDate.indexOf(date)+1)%7);
	}
	
	public String toString(){
		return String.format("date=%s,startT=%d,endT=%d,daycount=%d", date,startT,endT,daycount);
	}
	
	public boolean equals(Time t2){
		if(date.equals(t2.getDate())){
			if(startT==t2.getStartT()){
				if(endT==t2.getEndT()){
					if(daycount==t2.daycount){
						return true;
					}
				}
			}
		}
		return false;
	}
	
	public String toCSV(){
		return date+","+startT+","+endT+","+daycount+",";
		
	}
}


StudentTimeEntry.java


/**
 * @author Kyra Gan
 * @version 4/20/2016
 * This class is used in StudentValue class to define the type of ArrayList STE. 
 * It stores Time and place (String), and has one constructor.
 */
public class StudentTimeEntry {
	
	Time time;
	String place;
	public StudentTimeEntry(Time time,String place){
		this.time=time;
		this.place=place;
	}
	
	public Time getTime(){
		return time;
	}
	
	public String getPlace(){
		return place;
	}
	
	String newline = System.getProperty("line.separator");
	public String toString(){
		String myste="";
		myste+=String.format("place=%s,", place);
		myste+="Time: "+ time.toString()+newline;
		return myste;
	}
	
}


StudentValue.java


/**
 * @author Kyra Gan
 * @version 4/20/2016
 * this class generates the value of student schedule hash table (STH); it stores
 * 2 variables: STE (ArrayList<StudentTimeEntry) and houseCode (String), which 
 * represent a student's weekly schedule. 
 * There are two constructors. 
 * addSTE(StudentTimeEntry Ety) is called when generating a student's hash value 
 * It also has the method toString()
 */
import java.util.ArrayList;

public class StudentValue {
	ArrayList<StudentTimeEntry> STE=new ArrayList<StudentTimeEntry>();
	String houseCode;
	
	public StudentValue(String houseCode){
		this.houseCode=houseCode;
	}
	public StudentValue(String houseCode, StudentTimeEntry Ety){
		this.houseCode=houseCode;
		STE.add(Ety);
	}

	//when adding another time entry we want things to be ordered
	//we also want the function to return false if there is time overlap 
	public boolean addSTE(StudentTimeEntry Ety){
		for(int i=0;i<STE.size();i++){
			//first we check whether the dates are the same
			if(STE.get(i).time.date.equals(Ety.time.date)){
				if(STE.get(i).time.startT<Ety.time.startT & Ety.time.startT<STE.get(i).time.endT){
					return false;
				}
				if(STE.get(i).time.startT<Ety.time.endT & Ety.time.startT<STE.get(i).time.endT){
					return false;
				}
			}
			//we want the order to be from the smallest to the biggest
			if (Ety.time.timeOrder()<STE.get(i).time.timeOrder()){
				STE.add(i,Ety);
				return true;
			}
		}
		STE.add(Ety);
		return true;
	}
	
	public String getHouseCode(){
		return houseCode;
	}
	
	public ArrayList<StudentTimeEntry> getSTE(){
		return STE;
	}
	String newline = System.getProperty("line.separator");
	public String toString(){
		String sv="";
		sv+=String.format("house code=%s", houseCode)+newline;
		for(int i=0;i<STE.size();i++){
			sv+=STE.get(i).toString();
		}
		return sv;
	}
}


PlaceTimeEntry.java


/**
 * @author Kyra Gan
 * @version 4/20/2016
 * This is a basic structure of PlaceValue class; it stores time, studentID (ArrayList<String>)
 *contagiousID (ArrayList<String>), healthyID (ArrayList<String>, hvaccineID(ArrayList<String>)
 * 
 * studentID record all the students in the room at Time time
 * contagiousID keeps track of contagious students during the simulation
 * healthyID keeps track of healthy students during the simulation
 * hvaccineID keeps track of all healthy vaccinated students in the room: 
 * studentID are partitioned into healthyID and hvaccineID before virus spread simulation
 * 
 * There are two constructors and several methods to modify all the ID ArrayLists.
 * However, addConID and removeConID are not used in the simulation because a more concise method
 * is implemented in WrapperStatusV5 to modify contagiousID list.
 * It also has the method toString()
 * 
 * Note: notice (!studentID.contains(ID)) is order n (under our assumption,
 * E[n]=30). Since the program is not running slow, we will not change the data structure to hash table
 * at this point
 */
import java.util.ArrayList;

public class PlaceTimeEntry {
	Time time;
	ArrayList<String> studentID=new ArrayList<String>();
	ArrayList<String> contagiousID=new ArrayList<String>();
	ArrayList<String> healthyID=new ArrayList<String>();
	ArrayList<String> hvaccineID=new ArrayList<String>();

	public PlaceTimeEntry(Time time){
		this.time=time;
	}

	public PlaceTimeEntry(Time time, String sID){
		this.time=time;
		studentID.add(sID);
		if(Constants.vaccineID.containsKey(sID)){
			hvaccineID.add(sID);
		}else{
			healthyID.add(sID);
		}
	}

	//since when only add student at the before simulation, 
	//we assume all the students are healthy, and initialize the healthy ID
	public void addSID(String ID){
		if(!studentID.contains(ID)){
			studentID.add(ID);
			if(Constants.vaccineID.containsKey(ID)){
				hvaccineID.add(ID);
			}else{
				healthyID.add(ID);
			}
		}else{
			System.out.println("PlaceTimeEntry.addSID(String): ID exist, let's debug");
		}
	}
	//assume this list has only one ID (this is the only case we are going to use this function)
	public void addSID(ArrayList<String> ID){
		String id=ID.get(0);
		if(!studentID.contains(id)){
			studentID.add(id);
			if(Constants.vaccineID.containsKey(id)){
				hvaccineID.add(id);
			}else{
				healthyID.add(id);
			}
		}else{
			System.out.println("PlaceTimeEntry.addSID(A<S>): ID: "+ID.get(0)+" exist, let's debug");
		}
	}

	//we also need to keep track of people who in the room are contagious
	public boolean addConID(String ID){
		if(!contagiousID.contains(ID)){
			if(studentID.contains(ID)){
				contagiousID.add(ID);
				if(healthyID.contains(ID)){
					healthyID.remove(ID);
				}else if(hvaccineID.contains(ID)){
					hvaccineID.remove(ID);
				}
				return true;
			}
			return false;
		}else{
			return false;
		}
	}

	public boolean removeConID(String ID){
		if(contagiousID.contains(ID)){
			contagiousID.remove(ID);
			return true;
		}else{
			Log.log(String.format("PlaceTimeEntry.removeConID(%s)",ID));
			System.out.println("PlaceTimeEntry.removeConID: ID doesn't exist");
			return false;
		}
	}

	//this function removes the ID from healthy once the student is infected
	public boolean removeHID(String ID){
		if(healthyID.contains(ID)){
			healthyID.remove(ID);
			return true;
		}
		else{
			//mainly for debug
			//Log.log(String.format("PlaceTimeEntry.removeHID(%s)",ID));
			//Log.log("StudentID= "+PrintArrayList(studentID)+"ContagiousID= "+PrintArrayList(contagiousID)+
			//		"HealthyID= "+PrintArrayList(healthyID));
			System.out.println("PlaceTimeEntry.removeHID: ID doesn't exist");
			return false;
		}
	}
	//methods that might be useful when we are simulating later on	
	public int stdNum(){
		return studentID.size();
	}

	public int conNum(){
		return contagiousID.size();
	}

	public int hlyNum(){
		return healthyID.size();
	}

	public Time getTime(){
		return time;
	}

	public ArrayList<String> getStudentID(){
		return studentID;
	}

	public ArrayList<String> getContagiousID(){
		return contagiousID;
	}

	public ArrayList<String> getHealthyID(){
		return healthyID;
	}

	public ArrayList<String> getHvaccineID(){
		return hvaccineID;
	}
	
	public String toStringArrayList(ArrayList<String> as){
		String myarr="";
		for(int i=0;i<as.size();i++){
			myarr+=as.get(i)+"|";
		}
		return myarr;
	}
	String newline = System.getProperty("line.separator");
	public String toString(){
		String pte="";
		pte+=time.toString()+"|"+newline+"studentID:"+toStringArrayList(studentID)+"|"+newline
				+"contagiousID:"+toStringArrayList(contagiousID)+"|"+newline
				+"healthyID:"+toStringArrayList(healthyID)+"|"+newline+
				"vaccineID:"+toStringArrayList(hvaccineID)+"|";
		return pte;
	}
}


PlaceValue.java


/**
 * @author Kyra Gan
 * @version: 4/20/2016
 * this generates the place hash value of the place hash table;
 * it contains a ArrayList<PlaceTimeEntry> that stores all events at one place in one week
 * it also contains a integer array that records the number of events in each date
 * addEntry(PlaceTimeEntry timeEntry) is called when initializing the place hash table, it 
 * adds a new PlaceTimeEntry according to time order.
 * getFirstIndexOfDates(String date) and getLastIndexOfDates(String date) allow one to jump
 * directly to the target dates in the placeEntry ArrayList.
 * it also contains the toString() method.
 * 
 */
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class PlaceValue {
	
	ArrayList<PlaceTimeEntry> placeEntry=new ArrayList<PlaceTimeEntry>();
	
	List<String> DDate=Arrays.asList("Mon","Tu","Wed","Th","Fri","Sa","Su"); 
	int[] NumberOfDates=new int[7];
	
	public PlaceValue(){
	}
	public PlaceValue(PlaceTimeEntry ety){
		placeEntry.add(ety);
		NumberOfDates[DDate.indexOf(ety.getTime().getDate())]+=1;
	}
	
	//used for updating the placeValue in the simulation part
	public PlaceValue(ArrayList<PlaceTimeEntry> placeEntry){
		this.placeEntry=placeEntry;
		for(int i=0;i<placeEntry.size();i++){
			NumberOfDates[DDate.indexOf(placeEntry.get(i).getTime().getDate())]+=1;
		}
	}

	//when adding timeEntry, we are not worried about the place hash key doesn't match
	//since the logic this program will not allow that
	//thing we care about: two time Entry with the same Time but different student ID
	//since we are going to process the csv file line by line, in the target timeEntry
	//there will be a student ID ArrayList that contains only one student ID
	
	public boolean addEntry(PlaceTimeEntry timeEntry){
		if(!placeEntry.contains(timeEntry)){
			//loop through the list to see whether we have the same time block under 
			//this place
			for(int i=0;i<placeEntry.size();i++){
				if(timeEntry.getTime().equals(placeEntry.get(i).getTime())){
					placeEntry.get(i).addSID(timeEntry.getStudentID());
					return true;
				}
			}
			//we also want the time entry to be ordered as in studentValue
			for(int i=0;i<placeEntry.size();i++){
				//we order from closest time to farthest 
				if (timeEntry.getTime().timeOrder()<placeEntry.get(i).getTime().timeOrder()){
					NumberOfDates[DDate.indexOf(timeEntry.getTime().getDate())]+=1;
					placeEntry.add(i,timeEntry);
					return true;
				}
			}
			NumberOfDates[DDate.indexOf(timeEntry.getTime().getDate())]+=1;
			placeEntry.add(timeEntry);
			return true;
		}else{
			//for debug
			System.out.println("PlaceValue.addEntry(): this time Entry exist");
			return false;
		}
	}
	
	public ArrayList<PlaceTimeEntry> getPlaceEntry(){
		return placeEntry;
	}

	public int getNumberOfDates(String date){
		return NumberOfDates[DDate.indexOf(date)];
	}
	
	public int getFirstIndexOfDates(String date){
		//monday is a special case
		if(date.equals("Mon")){
			return firstIndexOfMonday();
		}
		//Tuesday to sunday case
		int number=0;
		if(getNumberOfDates(date)!=0){
			for(int i=0;i<DDate.indexOf(date);i++){
				number+=NumberOfDates[i];
			}
			return number;
		}else{
			return -1;
		}
	}
	
	public int getLastIndexOfDates(String date){
		//monday is a special case
		if(date.equals("Mon")){
			return lastIndexOfMonday();
		}
		if(getNumberOfDates(date)!=0){
			return getFirstIndexOfDates(date)+getNumberOfDates(date)-1;
		}else{
			//System.out.println("PlaceValue: "+date+ " entry is not initialized, debug");
			return -1;
		}
	}
	public int firstIndexOfMonday(){
		if(NumberOfDates[0]!=0){
			return 0;
		}else{
			//System.out.println("PlaceValue: Monday entry is not initialized, debug");
			return -1;
		}
	}
	public int lastIndexOfMonday(){
		return NumberOfDates[0]-1;
	}
	public String toStringFirstLastIndexOfDays(){
		String s="";
		for(int i=0;i<7;i++){
			String date=DDate.get(i);
			s+="the first index of "+date+" is: "+ getFirstIndexOfDates(date)+"; the last index of "
			+date+" is: "+ getLastIndexOfDates(date)+" ";
		}
		return s;
	}
	
	public String toString(){
		String mypv="";
		for (int i=0;i<placeEntry.size();i++){
			PlaceTimeEntry mypte=placeEntry.get(i);
			mypv+=mypte.toString();
		}
		return mypv;
	}

}


Recipient.java


/**
 * @author kyragan
 * This is a basic unit structure of StatusValue
 * Recipient will only keep track of the direct recipients
 * e.g if student A affect B and B affect C, only B will appear in A's recipient
 * Each Recipient will record the students are infected by our hashkey value 
 * student at Time. 
 * Time will have the format (date.input,startT.input, endT=0,
 * daycount=0) (since we are only using daycount for length bw startT and endT)
 * @version 3/19/2016
 */
import java.util.ArrayList;

public class Recipient {
	int week; //keep track of the week.
	//notice here for time, all endT are null=-1!
	Time time;
	ArrayList<String> ID=new ArrayList<String>();
	String place;
	
	//we only want to initialize week and time here.
	public Recipient(String place, int week, Time time){
		this.time=time;
		this.week=week;
		this.place=place;
	}
	
	public Recipient(String place, int week, Time time, ArrayList<String> ID){
		this.time=time;
		this.week=week;
		this.ID=ID;
		this.place=place;
	}
	
	//allow us to add the id s separately
	public boolean addID(ArrayList<String> id){
		for(int i=0;i<id.size();i++){
			if(ID.contains(id.get(i))){
				System.out.println("Recipient.addID(A<s>):let's debug");
				return false;
			}
		}
		ID.addAll(id);
		return true;
	}
	
	public int getWeek(){
		return week;
	}
	
	public Time getTime(){
		return time;
	}
	
	public ArrayList<String> getID(){
		return ID;
	}
	
	public String getPlace(){
		return place;
	}
	
	public String toStringArrayList(ArrayList<String> as){
		String myarr="";
		for(int i=0;i<as.size();i++){
			myarr+=as.get(i)+"|";
		}
		return myarr;
	}
	String newline = System.getProperty("line.separator");
	
	public String toString(){
		String re="";
		re+=String.format("place=%s,week=%d,",place,week);
		re+=time.toString()+"|";
		re+=toStringArrayList(ID)+newline;
		return re;
	}
	
	public String toCSVArrayList(ArrayList<String> as){
		String a="";
		for (int i=0;i<as.size();i++){
			a+=as.get(i)+",";
		}
		return a;
	}
	
	public String toCSV(){
		return place+","+week+","+time.toCSV()+toCSVArrayList(ID);
	}
	public String toStringV2(){
		String re="";
		int day=week*7+time.dayOfTheWeek();
		re+=String.format("place=%s,day=%d,startT=%d,",place,day,time.getStartT());
		re+=toStringArrayList(ID)+newline;
		return re;
	}
	public String toCSVV2(){
		int day=week*7+time.dayOfTheWeek();
		return place+","+day+","+time.getStartT()+","+toCSVArrayList(ID);
	}
}


Status.java


import java.util.Arrays;
import java.util.List;

/**
 * @version 3/17/2016
 * @author kyragan
 * This is a basic structure for the StatusValue class
 * 
 * Main Methods: IncreaseIncubationDaycount(),IncreaseContagiousDaycount(),
 * getCurrentDate()
 * 
 * this class keeps track of the hashkey value student's health status
 * incubation form (date.input, startT.input, endT.input, daycount.input)
 * Infectious form (date=(incubation.date+incubation.daycount)%7, 
 * startT=incubation.endT, endT.input, daycount.input)
 * once student is in the remission phase, we going to move her out of the
 * hash table and into another hash table, thus we are not going to record 
 * remission phase here
 */
public class Status {
	int week; // we need to track when the student first get infected
				// after that, we can use the daycount variable in our Time class
	
	//default setting of incubation and contagious stage length setting
	int incubationLimit=Constants.incubationLimit;
	int contagiousLimit=Constants.contagiousLimit;
	
	Time incubation;
	Time NullTime=new Time("a",-1,-1);
	Time contagious=NullTime;
	
	List<String> DDate=Arrays.asList("Mon","Tu","Wed","Th","Fri","Sa","Su");

	public Status(Time incubation,Time contagious, int week){
		this.incubation=incubation;
		this.contagious=contagious;
		this.week=week;
	}
	
	public Status(Time incubation, int week){
		this.incubation=incubation;
		this.week=week;
	}
	
	public Time getIncubation(){
		return incubation;
	}
	
	public Time getContagious(){
		return contagious;
	}
	
	public int getWeek(){
		return week;
	}
	
	public int getIncubationLimit(){
		return incubationLimit;
	}
	
	public int getContagiousLimit(){
		return contagiousLimit;
	}

	public boolean setIncubationEndTime(int endT, int daycount){
		if (incubation.getEndT()!=-1){
			return false;
		}
		incubation.setEndT(endT);
		incubation.setDaycount(daycount);
		return true;
	}
	
	
	public boolean IncreaseIncubationDaycount(){
		if(IEndTimeExist()){
			return false;
		}
		if(incubation.getDaycount()<(incubationLimit-1)){
			incubation.increaseDaycount();
			return true;
		}
		if(incubation.getDaycount()==(incubationLimit-1)){
			int startT=incubation.getStartT();
			//set the incubation end time and initialize the contagious
			setIncubationEndTime(startT,incubationLimit);
			Time mycontagious=new Time(DDate.get((DDate.indexOf(incubation.getDate())
					+incubationLimit)%7),startT);
			setContagious(mycontagious);
			return true;
		}
		return false;
	}
	
	public boolean setContagious(Time contagious){
		//if contagious is already initialized
		if(checkContagious()){
			return false;
		}
		this.contagious=contagious;
		return true;
	}
	

	public boolean IncreaseContagiousDaycount(){
		if(!checkContagious()){
			return false;
		}
		if(CEndTimeExist()){
			return false;
		}
		if(contagious.getDaycount()<(contagiousLimit-1)){
			contagious.increaseDaycount();
			return true;
		}else{
			setContagiousEndTime(contagious.getStartT(),contagiousLimit);
			return true;
		}
	}
	
	public boolean setContagiousEndTime(int endT, int daycount){
		if(!checkContagious()){
			return false;
		}
		if(CEndTimeExist()){
			return false;
		}
		contagious.setEndT(endT);
		contagious.setDaycount(daycount);
		return true;
	}
	
	public boolean CEndTimeExist(){
		if(contagious.getEndT()==-1){
			return false;
		}
		return true;
	}
	
	public boolean IEndTimeExist(){
		if(incubation.getEndT()==-1){
			return false;
		}
		return true;
	}
	
	//if contagious is nulltime, return false
	public boolean checkContagious(){
		return !contagious.equals(NullTime);
	}
	
	//return the current date in this status according to values stored in this status
	public String getCurrentDate(){
		if(!IEndTimeExist()){
			return DDate.get((DDate.indexOf(incubation.getDate())
					+incubation.getDaycount())%7);
		}
		if(!CEndTimeExist()){
			return DDate.get((DDate.indexOf(contagious.getDate())
					+contagious.getDaycount())%7);
		}
		String date=DDate.get((DDate.indexOf(contagious.getDate())
				+contagiousLimit)%7);
		return "date exit contagious: "+date+" under Remission";
	}
	
	String newline = System.getProperty("line.separator");
	public String toString(){
		String mystatus="";
		mystatus+=String.format("week=%d,", week)+newline;
		mystatus+="incubation time:"+incubation.toString()+newline;
		mystatus+="contagious time:"+contagious.toString();
		return mystatus;
	}
	
	public String toCSV(){
		return week+","+incubation.toCSV()+contagious.toCSV();
	}
}


StatusValue.java


/**
 * @author kyragan
 * @version 4/20/2016
 * This generates the status value for the status hashtable
 * it stores the status of the student, student's infection source, student's recipientIDs,
 * and student's recipients stamped by time (ArrayList<Recipient>)
 * it has two constructors; addrecp is called during the simulation; it contains
 * multiple versions of toString() and toCSV()
 */
import java.util.ArrayList;

public class StatusValue {
	Status st;
	String source;
	ArrayList<Recipient> stRecpt=new ArrayList<Recipient>();
	ArrayList<String> RecipientID=new ArrayList<String>();

	public StatusValue(String source,Status st){
		this.st=st;
		this.source=source;
	}

	public StatusValue(String source,Status st, ArrayList<Recipient> stRecpt){
		this.st=st;
		this.source=source;
		this.stRecpt=stRecpt;
		for(int i=0;i<stRecpt.size();i++){
			ArrayList<String> myID=stRecpt.get(i).ID;
			for(int j=0;j<myID.size();j++){
				RecipientID.add(myID.get(j));
			}
		}
	}

	//objective: do not add the same recipient twice under different time
	//addrecp only apply when (st.getCurrentDate()).equals(r.getTime().getDate())
	public boolean addrecp(Recipient r){
		if(!st.checkContagious()){
			return false;
		}
		if(st.CEndTimeExist()){
			return false;
		}

		if(!r.getTime().getDate().equals(st.getCurrentDate())){
			return false;
		}


		//find out whether we have overlaps 		
		for(int i=0;i<RecipientID.size();i++){
			if(r.getID().contains(RecipientID.get(i))){
				return false;
			}
		}

		//iterate through the list to see whether there is same starting time
		for(int i=0;i<stRecpt.size();i++){
			Recipient myr=stRecpt.get(i);
			if(myr.getWeek()==r.getWeek()){
				if(myr.getTime().timeOrder()==(r.getTime().timeOrder())){
					myr.addID(r.getID());

					RecipientID.addAll(r.getID());

					return true;
				}
				//want recipient also to be time ordered
				if(r.getTime().timeOrder()<myr.getTime().timeOrder()){
					stRecpt.add(i,r);

					RecipientID.addAll(r.getID());

					return true;
				}
			}
		}
		//let's see whether we will use the above part later
		stRecpt.add(r);
		RecipientID.addAll(r.getID());
		return true;
	}

	public Status getSt(){
		return st;
	}
	public String getSource(){
		return source;
	}

	public ArrayList<Recipient> getStRecpt(){
		return stRecpt;
	}

	public ArrayList<String> getRecipientID(){
		return RecipientID;
	}

	String newline = System.getProperty("line.separator");
	public String toString(){
		String mystatusvalue="";
		mystatusvalue+=String.format("source=%s,", source)+newline;
		mystatusvalue+="status: "+st.toString()+newline;
		mystatusvalue+="recepient:"+newline;
		for(int i=0;i<stRecpt.size();i++){
			mystatusvalue+=stRecpt.get(i).toString();
		}
		return mystatusvalue;
	}
	public String toStringV2(){
		String mystatusvalue="";
		mystatusvalue+=String.format("source=%s,", source)+newline;
		mystatusvalue+="status: "+st.toString()+newline;
		mystatusvalue+="recepient:"+newline;
		for(int i=0;i<stRecpt.size();i++){
			mystatusvalue+=stRecpt.get(i).toStringV2();
		}
		return mystatusvalue;
	}
	public String toCSV(){
		String csv= source+","+RecipientID.size()+","+st.toCSV();
		for(int i=0;i<stRecpt.size();i++){
			csv+=stRecpt.get(i).toCSV();
		}
		return csv;
	}
	public String toCSVV2(){
		String csv= source+","+st.toCSV();
		for(int i=0;i<stRecpt.size();i++){
			csv+=stRecpt.get(i).toCSVV2();
		}
		return csv;
	}
	public String toCSVV3(){
		return source+","+RecipientID.size()+","+st.getinfectionDay()+",";
	}
}


Probability.java


import java.util.ArrayList;
import java.util.Random;

/**
 * @version 4/17/2016
 * @author kyraga
 * This class calculates the following: the infectionProbability, number of people infected in a 
 * given space, and recipients assignment.
 * This class also generates the vaccineID before we run WrapperSP parse;
 * Deterministic part:
 * infectionProbability: proportional to number of contagious people and individual infection 
 * probability (assume it the same for everyone at this stage)
 * numberOfInfected: use round method to get the nearest integer
 * assignRecipients: generated students to be infected randomly but assign them to the source 
 * systematically (round by round) 
 * Stochastic part:
 * KG implemented this part in function numberOfInfected: we add a noise term to the deterministic 
 * part: use random Gaussian to generate a number from normal random distribution, multiply by the
 * amplitude Constants.sigma, and finally restrict number of infected to be positive
 */

public class Probability {
	Random randomGenerator = new Random();

	public Probability(){

	}

	//create an integer random number generator
	public int myRandn(int startRange, int EndRange){
		if(startRange!=EndRange){
			return startRange+randomGenerator.nextInt(EndRange-startRange);
		}else{
			return startRange;
		}
	}

	//this is the deterministic probability of a healthy student in a given place getting 
	//infected
	public float infectionProbability(int contagiousN){
		if(Constants.infectionProbability>1){
			System.out.println("Constants.infectionProbability: probability cannot be"
					+ "greater than 1");
			System.exit(0);
		}
		float p=Constants.infectionProbability*contagiousN;
		return Math.min(1, p);
	}

	//this is the deterministic probability of a vaccinated student in a given place getting 
	//infected
	public float vaccineContagiousProbability(int contagiousN){
		if(!Constants.vaccination){
			if(Constants.vaccineContagiuosProbability>1){
				System.out.println("Constants.vaccineContagiuosProbability: probability cannot be"
						+ "greater than 1");
				System.exit(0);
			}
			float p=Constants.vaccineContagiuosProbability*contagiousN;
			return Math.min(1, p);
		}else{
			return 0;
		}
	}

	//this is the deterministic/stochastic number of healthy students getting infected in a
	// given place we use round method here
	public int numberOfInfected(int contagiousN,int healthyN){
		if(!Constants.deterministic){
			float p=infectionProbability(contagiousN)*healthyN;
			p+=randomGenerator.nextGaussian()*Constants.sigma;
			return Math.min(Math.max(0, Math.round(p)), healthyN);
		}
		return Math.round(infectionProbability(contagiousN)*healthyN);
	}

	//this is the deterministic/stochastic number of not contagious vaccinated students 
	//getting infected in a given place we use round method here
	public int numberOfVaccineContagious(int contagiousN,int hvaccineN){
		if(!Constants.deterministic){
			float p=vaccineContagiousProbability(contagiousN)*hvaccineN;
			p+=randomGenerator.nextGaussian()*Constants.sigma;
			return Math.min(Math.max(0, Math.round(p)), hvaccineN);
		}
		return Math.round(vaccineContagiousProbability(contagiousN)*hvaccineN) ;
	}

	/**
	 * @version 1: everyone has the same probability of affecting other people
	 * we divide the number of recipients evenly(as possible) among them
	 * I do not want to remove the student from healthy once I generate her to be infected
	 * because that will mass up with the rest of update part in WrapperStatus, thus I created a
	 * new array list called myHealthy(a deep copy) to handle to problem for now
	 * Further: we use randn function to generate the student to be infected and assign recipients
	 * to already contagious by rounds
	 */
	public ArrayList<ArrayList<String>> assignRecipients(ArrayList<String> healthy,
			ArrayList<String> hvaccineID,ArrayList<String> myConID){
		int infected=numberOfInfected(myConID.size(),healthy.size());
		int infected2=numberOfVaccineContagious(myConID.size(),hvaccineID.size());
		if(infected2!=0){
			System.out.println(vaccineContagiousProbability(myConID.size())*healthy.size());
			System.out.println(Math.round(vaccineContagiousProbability(myConID.size())*healthy.size()));
		}
		ArrayList<String> myNew=new ArrayList<String>(healthy);
		ArrayList<String> myNewhv=new ArrayList<String>(hvaccineID);
		ArrayList<ArrayList<String>> result=new ArrayList<ArrayList<String>>();
		if(healthy.isEmpty()){
			return result;
		}
		/**
		if(Constants.infectionProbability==1){
			myNew.add(myConID.get(0)); //the last index of healthy will be the source
			result.add(myNew);
			return result;
		}
		 */
		if(infected==0){
			if(infected2==0){
				return result;
			}
		}
		if(infected!=0){
			for(int i=0;i<infected;i++){
				if(i<myConID.size()){// when infected<=myConID.size()
					//generated the student to be infected
					ArrayList<String> student=new ArrayList<String>();
					//System.out.println(myNew.size()+"infected"+infected);
					student.add(myNew.remove(myRandn(0,myNew.size()-1)));
					//for source myConID.get(i)
					student.add(myConID.get(i));
					result.add(student);
				}else{
					ArrayList<String> student=result.get(i%myConID.size());
					student.add(student.size()-2,myNew.remove(myRandn(0,myNew.size())));
				}
			}
		}
		if(infected2==0){
			return result;
		}
		for(int i=0;i<infected2;i++){
			if(result.size()<myConID.size()){
				ArrayList<String> student=new ArrayList<String>();
				//System.out.println(myNewhv.size()+"infected2"+infected2);
				student.add(myNewhv.remove(myRandn(0,myNewhv.size()-1)));
				//System.out.println(result.size());
				//System.out.println(i);
				student.add(myConID.get(result.size()));
				result.add(student);
			}else{
				ArrayList<String> student=result.get((i+result.size())%myConID.size());
				student.add(student.size()-2,myNewhv.remove(myRandn(0,myNewhv.size())));
			}
		}
		return result;
	}

	public boolean generateVaccineID(){
		if(!Constants.file.equals("TestData5.csv")){
			return false;
		}
		//we know the last student's ID is 2624
		int number=Math.round(2624*Constants.vaccipercentage);
		ArrayList<String> ID=new ArrayList<String>();
		for(int i=0;i<2624;i++){
			ID.add(Integer.toString(i));
		}
		for(int i=0;i<number;i++){
			int myIndex=myRandn(1,ID.size());
			Constants.vaccineID.put(ID.get(myIndex), 0);
			ID.remove(myIndex);
		}
		return true;
	}
}



StatusV2.java


package mostRecent;


import java.util.Arrays;
import java.util.List;

/**
 * @version 3/27/2016
 * @author kyragan
 * StatusV2.java and Status.java are not supposed to run at the same time
 * This is the version of Status.java without the Recipient structure
 * 
 * Main Methods: IncreaseIncubationDaycount(),IncreaseContagiousDaycount(),
 * getCurrentDate()
 * 
 * this class keeps track of the hashkey value student's health status
 * incubation form (date.input, startT.input, endT.input, daycount.input)
 * Infectious form (date=(incubation.date+incubation.daycount)%7, 
 * startT=incubation.endT, endT.input, daycount.input)
 * once student is in the remission phase, we going to move her out of the
 * hash table and into another hash table, thus we are not going to record 
 * remission phase here
 */
public class StatusV2 {
	/**
	 * stamp the day of the semester when student got infected and the place where she 
	 * first got infected
	 * default setting of incubation and contagious stage length setting
	 */
	String place;
	int day;
	int incubationLimit=Constants.incubationLimit;
	int contagiousLimit=Constants.contagiousLimit;
	
	Time incubation;
	Time NullTime=new Time("a",-1,-1);
	Time contagious=NullTime;
	
	List<String> DDate=Arrays.asList("Mon","Tu","Wed","Th","Fri","Sa","Su");

	public StatusV2(Time incubation,Time contagious, int day, String place){
		this.incubation=incubation;
		this.contagious=contagious;
		this.day=day;
		this.place=place;
	}
	
	public StatusV2(Time incubation, int day,String place){
		this.incubation=incubation;
		this.day=day;
		this.place=place;
	}
	
	public Time getIncubation(){
		return incubation;
	}
	
	public Time getContagious(){
		return contagious;
	}
	
	public int getDay(){
		return day;
	}
	public String getPlace(){
		return place;
	}
	
	public int getIncubationLimit(){
		return incubationLimit;
	}
	
	public int getContagiousLimit(){
		return contagiousLimit;
	}

	public boolean setIncubationEndTime(int endT, int daycount){
		if (incubation.getEndT()!=-1){
			return false;
		}
		incubation.setEndT(endT);
		incubation.setDaycount(daycount);
		return true;
	}
	
	
	public boolean IncreaseIncubationDaycount(){
		if(IEndTimeExist()){
			return false;
		}
		if(incubation.getDaycount()<(incubationLimit-1)){
			incubation.increaseDaycount();
			return true;
		}
		if(incubation.getDaycount()==(incubationLimit-1)){
			int startT=incubation.getStartT();
			//set the incubation end time and initialize the contagious
			setIncubationEndTime(startT,incubationLimit);
			Time mycontagious=new Time(DDate.get((DDate.indexOf(incubation.getDate())
					+incubationLimit)%7),startT);
			setContagious(mycontagious);
			return true;
		}
		return false;
	}
	
	public boolean setContagious(Time contagious){
		//if contagious is already initialized
		if(checkContagious()){
			return false;
		}
		this.contagious=contagious;
		return true;
	}
	

	public boolean IncreaseContagiousDaycount(){
		if(!checkContagious()){
			return false;
		}
		if(CEndTimeExist()){
			return false;
		}
		if(contagious.getDaycount()<(contagiousLimit-1)){
			contagious.increaseDaycount();
			return true;
		}else{
			setContagiousEndTime(contagious.getStartT(),contagiousLimit);
			return true;
		}
	}
	
	public boolean setContagiousEndTime(int endT, int daycount){
		if(!checkContagious()){
			return false;
		}
		if(CEndTimeExist()){
			return false;
		}
		contagious.setEndT(endT);
		contagious.setDaycount(daycount);
		return true;
	}
	
	public boolean CEndTimeExist(){
		if(contagious.getEndT()==-1){
			return false;
		}
		return true;
	}
	
	public boolean IEndTimeExist(){
		if(incubation.getEndT()==-1){
			return false;
		}
		return true;
	}
	
	//if contagious is nulltime, return false
	public boolean checkContagious(){
		return !contagious.equals(NullTime);
	}
	
	//return the current date in this status according to values stored in this status
	public String getCurrentDate(){
		if(!IEndTimeExist()){
			return DDate.get((DDate.indexOf(incubation.getDate())
					+incubation.getDaycount())%7);
		}
		if(!CEndTimeExist()){
			return DDate.get((DDate.indexOf(contagious.getDate())
					+contagious.getDaycount())%7);
		}
		String date=DDate.get((DDate.indexOf(contagious.getDate())
				+contagiousLimit)%7);
		return "date exit contagious: "+date+" under Remission";
	}
	
	String newline = System.getProperty("line.separator");
	public String toString(){
		String mystatus="";
		mystatus+=String.format("day=%d,place=%s,", day,place)+newline;
		mystatus+="incubation time:"+incubation.toString()+newline;
		mystatus+="contagious time:"+contagious.toString();
		return mystatus;
	}
	
	public String toCSV(){
		return day+","+place+","+incubation.toCSV()+contagious.toCSV();
	}
}


StatusValueV2.java


package mostRecent;
/**
 * @author kyragan
 * @version 3/27/2016
 * This is the version of StatusValue.java without Recipient structure 
 * This generates the status value for the status hashtable
 */
import java.util.ArrayList;

public class StatusValueV2 {
	StatusV2 st;
	String source;
	

	public StatusValueV2(String source,StatusV2 st){
		this.st=st;
		this.source=source;
	}

	public StatusV2 getSt(){
		return st;
	}
	public String getSource(){
		return source;
	}

	String newline = System.getProperty("line.separator");
	public String toString(){
		String mystatusvalue="";
		mystatusvalue+=String.format("source=%s,", source)+newline;
		mystatusvalue+="status: "+st.toString()+newline;
		return mystatusvalue;
	}

	public String toCSV(){
		String csv= source+","+st.toCSV();
		return csv;
	}
}


ToDot.java

/**
 * @author kyragan
 * @version 4/19/2016
 * this class reads in the toCSVV3 in WrapperStatus and generates the dot file 
 * according to the data.
 * In order to save the time of iteration, we are going to store all the values in a 
 * hash table in the first iteration.
 * the key value of status is a ArrayList<String> of size 3, the first element is the
 * source, the second element is the day of the semester when infected, the third 
 * element is the size of the recipients.
 * in this version of toDot(), the size of the nodes (area) are proportional to their 
 * number of recipients
 */

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Map.Entry;
import java.util.NoSuchElementException;

public class ToDot {
	boolean radiusRatio=true;
	boolean radiusLog=false;
	Hashtable<String,ArrayList<String>> status;
	String newline = System.getProperty("line.separator");
	static String dot=null;
	String firstInKey=null;
	int maxdays=0;
	int maxsteps;
	float percentageStudentInfected;

	public ToDot(String file){
		//initialize the hash table 
		status=new Hashtable<String,ArrayList<String>>();
		try {
			parse(file);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("ToDot.ToDot:"+ file+" not found");
		}
	}

	public void setRadiusRatio(boolean ratio){
		radiusRatio=ratio;
	}

	public void setRadiusLog(boolean log){
		if(log){
			if(!radiusRatio){
				System.out.println("warning: radiusRatio false: cannot use log");
			}
		}
		radiusLog=log;
	}
	
	public void parse(String filename) throws FileNotFoundException {
		Scanner scanner = new Scanner(new File(filename));
		try{
			percentageStudentInfected=Float.valueOf(scanner.next().split(",")[0]);
		}catch(NoSuchElementException e){
			
		}
		while(scanner.hasNextLine()){

			String[] a;
			try{
				a=scanner.next().split(",");
				ArrayList<String> myvalue=new ArrayList<String>();
				myvalue.add(a[1]);//add the source index 0
				myvalue.add(a[3]);//add the day of the semester of the infection index 1
				myvalue.add(a[2]);//add the size of the direct recipients index 2
				myvalue.add(a[4]);//add the indication of vaccination index 3
				status.put(a[0], myvalue);
				if(Integer.parseInt(a[3])>maxdays){
					maxdays=Integer.parseInt(a[3]);
				}
			}catch(NoSuchElementException e){

			}
		}
		scanner.close();
	}

	public void generateDot(){
		ArrayList<String> source=new ArrayList<String>();
		ArrayList<String> invisibleNodes=new ArrayList<String>();
		//initialize invisible nodes list
		for(Entry<String,ArrayList<String>> entry: status.entrySet()){
			if(!entry.getValue().get(0).equals("0")){
				int currentday=Integer.parseInt(entry.getValue().get(1));
				int sourceday=Integer.parseInt(status.get(entry.getValue().get(0)).get(1));
				if(currentday-sourceday>1){
					int steps=(int) ((currentday-sourceday-1)/Constants.edgeDiscountFactor);
					for(int i=0;i<steps;i++){
						invisibleNodes.add("m"+invisibleNodes.size());	
					}
				}
			}else{
				firstInKey=entry.getKey();
			}
		}

		dot="digraph spread {"+newline+"graph [label=\""+percentageStudentInfected*100+
				"% student infected \", labelloc=bottom, fontsize=150];"
				+newline+"rankdir=LR;"+newline+"root="+firstInKey+";"
				+newline+"ranksep=3.0;"
				+newline+"nodesep=2.0;"+newline+
				firstInKey+newline;
		//first iterate through the sources
		//the size of the node reflect the number of recipient: sqrt(#of recipient)*Constants.nodeSize
		for(Entry<String,ArrayList<String>> entry: status.entrySet()){
			String mysource=entry.getValue().get(0);
			if(!source.contains(mysource)){
				if(mysource.equals("0")){
					dot+=entry.getKey()+" [fillcolor=";
					if(entry.getValue().get(3).equals("0")){
						dot+="coral1";
					}else{
						dot+="limegreen";
					}
					dot+= ",shape=doublecircle,"+"width=";
					if(radiusRatio){
						if(!radiusLog){
							dot+=Integer.parseInt(entry.getValue().get(2))*Constants.nodeSize;
						}else{
							dot+=Math.log(1+Integer.parseInt(entry.getValue().get(2))*Constants.nodeSize);
						}
					}else{
						dot+=Math.sqrt(Integer.parseInt(entry.getValue().get(2)))*Constants.nodeSize;
					}
					dot+=",style=filled,"+ "fontsize=12];"+newline;
					source.add(entry.getKey());
				}
				else{
					int size=Integer.parseInt(status.get(mysource).get(2));
					dot+=mysource+" [fillcolor=\"";
					if(!Constants.vaccination){
						if(!radiusRatio){
							if(size<=5){
								dot+="lightyellow1\"";
							}else if(size<=10){
								dot+="yellow1\"";
							}else if(size>10){
								dot+="goldenrod1\"";
							}
						}else{
							dot+="goldenrod1\"";
						}
					}else{
						if(status.get(mysource).get(3).equals("1")){
							dot+="limegreen\"";
						}else{
							dot+="goldenrod1\"";
						}
					}
					dot+=",shape=circle,"+"width=";
					if(radiusRatio){
						if(!radiusLog){
							dot+=Integer.parseInt(status.get(mysource).get(2))*Constants.nodeSize;
						}else{
							dot+=Math.log(1+Integer.parseInt(status.get(mysource).get(2))*Constants.nodeSize);
						}
					}else{
						dot+=Math.sqrt(size)*Constants.nodeSize;
					}
					dot+=",style=filled,"+ "fontsize=12];"+newline;
					source.add(mysource);
				}
			}
		}
		//Initialize the day scaler nodes
		maxsteps=(int)(maxdays/Constants.edgeDiscountFactor);
		dot+="{node[shape=plaintext, fontsize=16]";
		for(int i=1;i<=maxsteps;i++){
			dot+=" day"+(int)(i*Constants.edgeDiscountFactor);
		}
		dot+="}"+newline;
		//initialize invisible nodes
		dot+="{node[shape=point,style=invis] ";
		for(int i=0;i<invisibleNodes.size();i++){
			dot+=invisibleNodes.get(i)+" ";
		}
		dot+="}"+newline;

		//then we iterate through the keys and add edges
		for(Entry<String,ArrayList<String>> entry: status.entrySet()){
			String mykey=entry.getKey();
			if(!source.contains(mykey)){
				dot+=mykey+" [shape=point,fillcolor=\"";
				if(status.get(mykey).get(3).equals("1")){
					dot+="limegreen";
				}else{
					dot+="blueviolet";
				}
				dot+="\",width="+Constants.nodeSize+",style=filled,fontsize=12];"+newline;
			}
		}
		Iterator<String> it=invisibleNodes.iterator();
		for(Entry<String,ArrayList<String>> entry: status.entrySet()){
			String mykey=entry.getKey();
			String mysource=entry.getValue().get(0);
			if(!mysource.equals("0")){
				dot+=mysource;
				int currentday=Integer.parseInt(entry.getValue().get(1));
				int sourceday=Integer.parseInt(status.get(entry.getValue().get(0)).get(1));
				int steps=(int) (currentday/Constants.edgeDiscountFactor)
						-(int) (sourceday/Constants.edgeDiscountFactor)-1;
				for(int i=0;i<steps;i++){
					dot+="->"+it.next();
				}
				dot+="->"+mykey+"[arrowsize=0.4, penwidth=1.2,color="
						+ "\"dimgray\"]"+";"+newline;
			}
		}

		dot+=firstInKey+"->day"+(int)Constants.edgeDiscountFactor+"[style=bold,color=maroon3,penwidth=8]"+newline;
		for(int i=2;i<=maxsteps;i++){
			dot+="day"+(int)((i-1)*Constants.edgeDiscountFactor)+"->day"
					+(int)(i*Constants.edgeDiscountFactor)+"[style=bold,color=maroon3,penwidth=8]"+newline;
		}

		dot+="}";
	}

	public Hashtable<String,ArrayList<String>> getStatusHashtable(){
		return status;
	}
	public static void main(String[] args){
		ToDot mydot=new ToDot("firstInKey82AreaProb0.01DEQ.csv");//Constants.saveFileAs+"V3.csv");
		mydot.setRadiusRatio(false);
		mydot.setRadiusLog(false);
		mydot.generateDot();
		try (PrintWriter out =new PrintWriter("firstInKey82AreaProb0.01DEQ.dot")){//Constants.saveFileAs+"V2.dot")){
			out.println(dot);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

Basic Structures testing


ProbabilityTest.java


/**
 * @author kyragan
 * @version 4/3/2016
 * this is the Junit file for probability
 */
import static org.junit.Assert.*;

import java.util.ArrayList;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class ProbabilityTest {

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testassignrecipients1() {
		Probability p=new Probability();
		ArrayList<String> healthy1=new ArrayList<String>();
		//create 200 healthy ID
		for (int i=0;i<200;i++){
			healthy1.add(Integer.toString(i));
		}
		// create 4 contagious ID
		ArrayList<String> contagious1=new ArrayList<String>();
		for (int i=0;i<4;i++){
			contagious1.add(Integer.toString(i+1000));
		}
		ArrayList<ArrayList<String>> result=p.assignRecipients(healthy1, contagious1);
		assertTrue(result.size()==4);
		assertTrue(result.get(0).size()==3);
		assertTrue(result.get(1).size()==3);
		assertTrue(result.get(2).size()==3);
		assertTrue(result.get(3).size()==3);
		System.out.println(result.get(0).get(2)+":"+result.get(0).get(0)+","+result.get(0).get(1));
		System.out.println(result.get(1).get(2)+":"+result.get(1).get(0)+","+result.get(1).get(1));
		System.out.println(result.get(2).get(2)+":"+result.get(2).get(0)+","+result.get(2).get(1));
		System.out.println(result.get(3).get(2)+":"+result.get(3).get(0)+","+result.get(3).get(1));
	}
	@Test
	public void testassignrecipients2() {
		Probability p=new Probability();
		ArrayList<String> healthy1=new ArrayList<String>();
		//create 155 healthy ID
		for (int i=0;i<155;i++){
			healthy1.add(Integer.toString(i));
		}
		// create 3 contagious ID
		ArrayList<String> contagious1=new ArrayList<String>();
		for (int i=0;i<3;i++){
			contagious1.add(Integer.toString(i+1000));
		}
		ArrayList<ArrayList<String>> result=p.assignRecipients(healthy1, contagious1);
		assertTrue(result.size()==3);
		assertTrue(result.get(0).size()==3);
		assertTrue(result.get(1).size()==3);
		assertTrue(result.get(2).size()==2);
		System.out.println(result.get(0).get(2)+":"+result.get(0).get(0)+","+result.get(0).get(1));
		System.out.println(result.get(1).get(2)+":"+result.get(1).get(0)+","+result.get(1).get(1));
		System.out.println(result.get(2).get(1)+":"+result.get(2).get(0));
	}

}



TimeTest.java


/**
 * @author kyragan
 * @version 3/17/2016
 * This is the JUnit file for time
 */
import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TimeTest {

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testGetDateReturnCorrectAnswer() {
		Time time=new Time("Mon",800,850);
		assertTrue(time.getDate().equals("Mon"));
	}
	@Test
	public void testGetStartTReturnCorrectAnswer(){
		Time time=new Time("Mon",800,850);
		assertTrue(time.getStartT()==800);
	}
	@Test
	public void testTimeOrderReturnCorrectAnswer(){
		Time time=new Time("Mon",800,850);
		Time time2=new Time("Sa",100,200);
		Time time3=new Time("Wed",300,450);
		Time time4=new Time("Fri",600,700);
		assertTrue(time.timeOrder()<time2.timeOrder());
		assertTrue(time3.timeOrder()<time4.timeOrder());
		assertTrue(time3.timeOrder()>time.timeOrder());
	}
	@Test
	public void testSetEndT(){
		Time time=new Time("Mon",0000);
		assertTrue(time.getEndT()==-1);
		time.setEndT(2000);
		assertTrue(time.getEndT()==2000);
	}
	@Test public void testNextDate(){
		Time time=new Time("Mon",0000);
		assertTrue(time.nextDate().equals("Tu"));
		Time time2=new Time("Su",0000);
		assertTrue(time2.nextDate().equals("Mon"));
		System.out.println(time.toString());
		System.out.println(time.toCSV());
	}
}


StudentValueTest.java


/**
 * @author kyragan
 * This is the JUnit file for StudentValue class
 * @version 3/16/2016
 */
import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class StudentValueTest {

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testaddSTE() {
		Time time1=new Time("Mon",800,900);
		StudentTimeEntry ste1=new StudentTimeEntry(time1,"abd");
		StudentValue sv=new StudentValue("1",ste1);
		Time time2=new Time("Tu",800,900);
		StudentTimeEntry ste2=new StudentTimeEntry(time2,"csf");
		assertTrue(sv.addSTE(ste2));
		System.out.println(sv.toString());
	}

}



PlaceTimeEntryTest.java.txt


/**
 * @author kyragan
 * @version: 3/16/2016
 * the testing file for PlaceTimeEntry.java
 */
import static org.junit.Assert.*;

import java.util.ArrayList;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class PlaceTimeEntryTest {

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testPlaceTimeEntryAddStudentID1() {
		Time mytime1=new Time("Mon",800,900);
		PlaceTimeEntry myplace=new PlaceTimeEntry(mytime1,"23"); //23 is the student ID
		myplace.addSID("25");
		assertTrue(myplace.getStudentID().size()==2);
		assertTrue(myplace.getHealthyID().size()==2);
	}
	
	@Test
	public void testPlaceTimeEntryAddStudentID2() {
		Time mytime1=new Time("Mon",800,900);
		PlaceTimeEntry myplace=new PlaceTimeEntry(mytime1,"23"); //23 is the student ID
		ArrayList<String> mystudent=new ArrayList<String>();
		mystudent.add("25");
		mystudent.add("27");
		myplace.addSID(mystudent);
		assertTrue(myplace.getStudentID().size()==2);
		assertTrue(myplace.getHealthyID().size()==2);
	}
	
	@Test
	public void testPlaceTimeEntryRemoveHealthyID() {
		Time mytime1=new Time("Mon",800,900);
		PlaceTimeEntry myplace=new PlaceTimeEntry(mytime1,"23"); //23 is the student ID
		myplace.addSID("25");
		myplace.removeHID("23");
		assertTrue(myplace.getStudentID().size()==2);
		assertTrue(myplace.getHealthyID().size()==1);
		assertTrue(myplace.getHealthyID().get(0).equals("25"));
	}
	
	
	
	@Test
	public void testPlaceTimeEntryaddConID() {
		Time mytime1=new Time("Mon",800,900);
		PlaceTimeEntry myplace=new PlaceTimeEntry(mytime1,"23"); //23 is the student ID
		assertFalse(myplace.addConID("25"));
		myplace.addSID("25");
		assertFalse(myplace.addConID("25"));
		myplace.removeHID("25");
		assertTrue(myplace.addConID("25"));
		myplace.removeHID("25");
		assertTrue(mytime1.timeOrder()==800);
		Time mytime2=new Time("Tu",800,900);
		assertTrue(mytime2.timeOrder()==10800);
		Time mytime3=new Time("Wed",800,900);
		assertTrue(mytime3.timeOrder()==20800);
		System.out.println(myplace.toString());
	}
}


PlaceValueTest.java


/***
 * @author Kyra Gan
 * This the JUnit file for PlaceValue
 * @version:3/16/2016
 */
import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class PlaceValueTest {

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testAddSinglePlaceTimeEntry() {
		
		Time time1=new Time("Mon",800,900);
		PlaceTimeEntry pte1=new PlaceTimeEntry(time1);
		PlaceValue pv=new PlaceValue(pte1);
		
		assertTrue(pv.getNumberOfDates("Mon")==1);
		assertFalse(pv.getNumberOfDates("Tu")==1);
		assertFalse(pv.getNumberOfDates("Mon")==2);
		assertTrue(pv.getFirstIndexOfDates("Mon")==0);
		assertTrue(pv.getLastIndexOfDates("Mon")==0);
		Time time2=new Time("Tu",800,900);
		PlaceTimeEntry pte2=new PlaceTimeEntry(time2);
		
		assertTrue(pv.addEntry(pte2));
		assertFalse(pv.addEntry(pte1));
		assertTrue(pv.getNumberOfDates("Tu")==1);
		assertTrue(pv.getFirstIndexOfDates("Tu")==1);
		assertTrue(pv.getLastIndexOfDates("Tu")==1);
		PlaceTimeEntry pte3=new PlaceTimeEntry(time1,"23");
		PlaceValue pv2=new PlaceValue(pte3);
		
		PlaceTimeEntry pte4=new PlaceTimeEntry(time1,"25");
		
		assertTrue(pv2.addEntry(pte4));
		assertTrue(pv2.getPlaceEntry().get(0).getStudentID().size()==2);
		
		Time time3=new Time("Mon",1200,1300);
		PlaceTimeEntry pte5=new PlaceTimeEntry(time3);
		
		assertTrue(pv.addEntry(pte5));
		assertTrue(pv.getNumberOfDates("Mon")==2);
		assertTrue(pv.getFirstIndexOfDates("Mon")==0);
		assertTrue(pv.getLastIndexOfDates("Mon")==1);
		assertTrue(pv.getFirstIndexOfDates("Tu")==2);
		assertTrue(pv.getLastIndexOfDates("Tu")==2);
		assertTrue(pv.getPlaceEntry().get(2).getTime().getDate().equals("Tu"));
		System.out.println(pv.toStringFirstLastIndexOfDays());
		System.out.println(pv.toString());
		System.out.println(pv2.toString());
		
	}

}



RecipientTest.java


/**
 * @author kyragan
 * @version 3/19/2016
 * this is the jUnit file for Recipient class
 */
import static org.junit.Assert.*;

import java.util.ArrayList;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class RecipientTest {

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testAddID() {
		Time time1=new Time("Mon",0000);
		Recipient myr=new Recipient("place",0,time1);
		assertTrue(myr.getID().size()==0);
		ArrayList<String> ID=new ArrayList<String>();
		ID.add("23");
		assertTrue(myr.addID(ID));
		ID.add("25");
		assertFalse(myr.addID(ID));
		ArrayList<String> ID2=new ArrayList<String>();
		ID2.add("25");
		ID2.add("27");
		assertTrue(myr.addID(ID2));
		System.out.println(myr.toString());
		System.out.println(myr.toCSV());
		System.out.println(myr.toStringV2());
		System.out.println(myr.toCSVV2());
	}

}


StatusTest.java


/**
 * @author kyragan
 * @version 3/17/2016
 * this is the JUnite File for Status Class
 */
import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class StatusTest {

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testAllSetMethodsInStatusPlusCheckContagious() {
		Time incubation=new Time("Mon",0000);
		Status mystatus=new Status(incubation,0);
		assertFalse(mystatus.checkContagious());
		assertTrue(mystatus.setIncubationEndTime(0000,2));
		assertFalse(mystatus.setIncubationEndTime(1234, 1));
		
		Time contagious=new Time("Wed",0000);
		assertTrue(mystatus.setContagious(contagious));
		assertTrue(mystatus.setContagiousEndTime(0000, 6));
		assertFalse(mystatus.setContagious(incubation));
		assertFalse(mystatus.setContagiousEndTime(1234, 4));
		assertTrue(mystatus.checkContagious());
		System.out.println(mystatus.toString());
		System.out.println(mystatus.toCSV());
	}
	@Test
	public void testAllIncreaseFunctionsInStatusPlusgetCurrentDate(){
		Time incubation=new Time("Mon",0000);

		
		//day0
		Status mystatus=new Status(incubation,0);
		assertTrue(mystatus.getIncubationLimit()==2);
		assertTrue(mystatus.getContagiousLimit()==6);

		//day1
		assertTrue(mystatus.IncreaseIncubationDaycount());
		assertFalse(mystatus.IncreaseContagiousDaycount());
		assertTrue(mystatus.getCurrentDate().equals("Tu"));

		//day2
		assertTrue(mystatus.IncreaseIncubationDaycount());
		assertTrue(mystatus.getCurrentDate().equals("Wed"));
		assertTrue(mystatus.IEndTimeExist());

		
		//day3
		assertTrue(mystatus.IncreaseContagiousDaycount());
		assertTrue(mystatus.getCurrentDate().equals("Th"));

		//day4
		assertTrue(mystatus.IncreaseContagiousDaycount());
		assertTrue(mystatus.getCurrentDate().equals("Fri"));

		//day5
		assertTrue(mystatus.IncreaseContagiousDaycount());
		assertTrue(mystatus.getCurrentDate().equals("Sa"));

		//day6
		assertTrue(mystatus.IncreaseContagiousDaycount());
		assertTrue(mystatus.getCurrentDate().equals("Su"));

		//day7
		assertTrue(mystatus.IncreaseContagiousDaycount());
		assertTrue(mystatus.getCurrentDate().equals("Mon"));
		
		//day8
		assertTrue(mystatus.IncreaseContagiousDaycount());		
		assertTrue(mystatus.getCurrentDate().equals("date exit contagious: Tu under Remission"));
		System.out.println(mystatus.toString());
		System.out.println(mystatus.toCSV());
	}
	
}


StatusValueTest.java


/**
 * @author kyragan
 * @version 3/19/2016
 * this is the JUnit file for StatusValue Class
 */
import static org.junit.Assert.*;

import java.util.ArrayList;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class StatusValueTest {

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testAddRecipient() {
		Time recp1=new Time("Mon",1234);
		Time recp2=new Time("Wed",1234);
		
		ArrayList<String> reID1=new ArrayList<String>();
		reID1.add("23");
		
		Recipient r1=new Recipient("place",0,recp1,reID1);
		Recipient r2=new Recipient("place",0,recp2,reID1);
		
		
		ArrayList<String> reID2=new ArrayList<String>();
		reID2.add("25");
		reID2.add("30");
		Recipient r4=new Recipient("place",3,recp2,reID2);
		Recipient r3=new Recipient("place",0,recp2,reID2);
		
		ArrayList<String> reID3=new ArrayList<String>();
		reID3.add("31");
		Time recp3=new Time("Wed", 830);
		Recipient r5=new Recipient("place",0,recp3,reID3);
		
		
		
		Time incubation=new Time("Mon",0000);
		Status st=new Status(incubation,0);
		st.IncreaseIncubationDaycount();
		StatusValue sv1=new StatusValue("-1",st);
		assertFalse(sv1.addrecp(r2));
		
		
		st.IncreaseIncubationDaycount();
		
		StatusValue sv2=new StatusValue("-1",st);
		assertTrue(sv2.addrecp(r2));
		assertTrue(sv2.getRecipientID().size()==1);
		assertFalse(sv2.addrecp(r4));
		assertTrue(sv2.addrecp(r3));
		assertTrue(sv2.getRecipientID().size()==3);
		assertFalse(sv2.addrecp(r3));
		assertTrue(sv2.getStRecpt().size()==1);
		assertTrue(sv2.addrecp(r5));
		assertTrue(sv2.getStRecpt().size()==2);
		assertTrue(sv2.getStRecpt().get(0).getTime().getStartT()==830);
		
		st.IncreaseContagiousDaycount();
		st.IncreaseContagiousDaycount();
		st.IncreaseContagiousDaycount();
		st.IncreaseContagiousDaycount();
		
		StatusValue sv3=new StatusValue("-1",st);
		assertFalse(sv3.addrecp(r1));
		assertFalse(sv3.addrecp(r2));
		System.out.println(sv2.toString());
		System.out.println(sv3.toString());
		System.out.println(sv1.toString());
		System.out.println(sv2.toCSV());
		System.out.println(sv3.toCSV());
		System.out.println(sv1.toCSV());
		System.out.println(sv2.toStringV2());
		System.out.println(sv3.toStringV2());
		System.out.println(sv1.toStringV2());
		System.out.println(sv2.toCSVV2());
		System.out.println(sv3.toCSVV2());
		System.out.println(sv1.toCSVV2());
	}

}


Wrappers



WrapperSP.java


/** 
 * @author Kyra Gan   
 * @version 4/21/2016   
 * WrapperSP reads csv input, generates and stores student schedule hash table 
 * and place hash table
 * It contains 3 fields: student (schedule) hash table, place hash table, and the keys 
 * of student hash table. Probability class is initialized only when Constants.vaccination
 * =true.
 * parse(String filename) is the method that generates the schedules.
 * this class also contains toStringSHT(), and toStringPHT().
 */

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Scanner;
import java.util.Map.Entry;

public class WrapperSP {
	Hashtable<String,StudentValue> SHT;
	Hashtable<String,PlaceValue> PHT;
	ArrayList<String> sID;
	Probability prob;
	String[] date={"Mon","Tu","Wed","Th","Fri","Sa","Su"}; 

	public WrapperSP(String file){
		//initialize the hash tables 
		SHT=new Hashtable<String,StudentValue>();
		//the place hash table is going to include the housing
		PHT=new Hashtable<String,PlaceValue>();
		//store all student ID so we can iterate through SHT later 
		//to find houseCode
		sID=new ArrayList<String>();
		if(Constants.vaccination){
			prob=new Probability();
			if(!prob.generateVaccineID()){
				System.out.println("WrapperStatus.Probabililty.generateVaccineID.wrong data");
				System.exit(0);
			}
		}
		try {
			parse(file);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("WrapperSP.WrapperSP:file not found");
		}
	}
	public Hashtable<String,StudentValue> getSHT() {
		return SHT;
	}

	//clone
	/**
	public Hashtable<String,StudentValue> clone(){
		Hashtable<String,StudentValue> ht=new Hashtable<String,StudentValue>();
		for(int i=0;i<sID.size();i++){
			String key=sID.get(i);
			StudentValue sv=SHT.get(SHT);
		}
	}

	 */

	public Hashtable<String,PlaceValue> getPHT() {
		return PHT;
	}
	public ArrayList<String> getSID(){
		return sID;
	}

	public void parse(String filename) throws FileNotFoundException {



		//objective: when reading each table line, we want to initialize 
		//both studentHashTable and PlaceHashTable so we don't need 
		//to waste the memory to store these values

		Scanner scanner = new Scanner(new File(filename));

		//read the file line by line

		while(scanner.hasNextLine()){

			//each row is corresponding to one student's schedule for one 
			//class (one ID, one place)

			String[] a=scanner.next().split(",");

			//since from each row, we have unique time entries, we can create 
			//Time time s

			if(a[0].equals("hashValue")){
				continue;
			}

			//index 1 is houseCode
			//if the student hashKey is already in the system we are NOT going 
			//to create a new studentValue, instead we want to modify the original
			//one and we are going to create one if hashKey is not in the table

			StudentValue sv;

			if(!SHT.containsKey(a[0])){
				sv=new StudentValue(a[1]);
			}else{
				sv=SHT.get(a[0]);
			}

			//updating the place hash table:
			//index 9, 10 are building, room
			//same logic as above
			//however, merge two PlaceTimeEntry is more complicated, we leave that 
			//function to placeValue add function

			PlaceValue pv;
			if(!PHT.containsKey(a[9]+a[10])){
				pv=new PlaceValue();
			}else{
				pv=PHT.get(a[9]+a[10]);
			}

			//initialize all the time blocks we can extract from our current row
			ArrayList<Time> tList=new ArrayList<Time>();
			//for each row, index 2-6 are Mon-Fri
			for(int i=2;i<7;i++){
				if (a[i].equals("1")){
					Time time=new Time(date[i-2],Integer.parseInt(a[7]),Integer.parseInt(a[8]));
					tList.add(time);
				}
			}

			//now we can generate StudentTimeEntry
			//based on the tList, we can also create PlaceTimeEntry
			for(int i=0;i<tList.size();i++){
				StudentTimeEntry ste=new StudentTimeEntry(tList.get(i),a[9]+a[10]);
				sv.addSTE(ste);

				PlaceTimeEntry pte=new PlaceTimeEntry(tList.get(i),a[0]);
				pv.addEntry(pte);
			}

			SHT.put(a[0], sv);
			//now we are down updating the student Hash Table

			//push the result to the place hash table
			PHT.put(a[9]+a[10], pv);

			//update sID list:
			if(!sID.contains(a[0])){
				sID.add(a[0]);
			}
		}
		scanner.close();
		//now we are down reading the file, we need to use our assumption to generate
		//breakfast, lunch, dinner, study time in the house

		//this part of the code is generate because the size and assumption of our baby program
		//we need a loop to literate through students' houseCode and etc

		//first we initialize all the time blocks we want to use
		ArrayList<Time> mealStuList=new ArrayList<Time>();
		int[] hourS={800,1220,1730,1900};
		int[] hourE={830,1250,1830,2100};
		//iterate through 7 days a week to generate all the meal and study blocks
		for(int i=0;i<7;i++){
			//iterate the target 4 blocks a day
			for(int j=0;j<4;j++){
				Time time=new Time(date[i],hourS[j],hourE[j]);
				mealStuList.add(time);
			}
		}

		//now let's update hv values in the PHT 
		//and sv-myste values in the SHT
		PlaceValue hv;
		for(int i=0;i<sID.size();i++){
			String housekey=SHT.get(sID.get(i)).getHouseCode();

			//get the existing student value
			StudentValue myste=SHT.get(sID.get(i));

			//generate StudentTimeEntry to update SHT
			for(int j=0;j<mealStuList.size();j++){
				StudentTimeEntry mealstu=new StudentTimeEntry(mealStuList.get(j),housekey);
				if(myste.addSTE(mealstu)){
					//then we also want to add this student to the PHT list
					if(!PHT.containsKey(housekey)){
						hv=new PlaceValue();
					}else{
						hv=PHT.get(housekey);
					}
					PlaceTimeEntry mealpte=new PlaceTimeEntry(mealStuList.get(j),sID.get(i));
					hv.addEntry(mealpte);
					PHT.put(housekey, hv);
				}
				SHT.put(sID.get(i),myste);
			}
		}
	}

	String newline = System.getProperty("line.separator");
	public String toStringSHT(){
		String hashstring="";
		for(Entry<String,StudentValue> entry : SHT.entrySet()){
			hashstring += entry.getKey() + "=" +newline
					+entry.getValue().toString();
		}
		return hashstring;  
	}
	public String toStringPHT(){
		String hashstring="";
		for(Entry<String,PlaceValue> entry : PHT.entrySet()){
			hashstring += entry.getKey() + "=" +newline
					+entry.getValue().toString();
		}
		return hashstring;  
	}
	public static void main(String[] args){
		WrapperSP w=new WrapperSP(Constants.file);
		System.out.println(w.toStringPHT());
	}
}


WrapperSPTest.java


/**
 * @author kyragan
 * This is a simple JUnit file for WrapperSP
 * %Latest Update: 3/16/2016
 */
import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.Hashtable;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class WrapperSPTest {
	
	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testGetSHTReturnValueHashtable() {
		WrapperSP wrapper=new WrapperSP(Constants.file);
		Hashtable<String,StudentValue> sht=wrapper.getSHT();
		ArrayList<String> key=wrapper.getSID();
		for(int i=0; i<key.size();i++){
			assertTrue(sht.containsKey(key.get(i)));
		}
		assertFalse(sht.containsKey("hashValue"));
		assertTrue(key.size()==sht.size());
	}

}


WrapperStatusV5.java


This is the main file for the simulation. Run it using the following command (after exporting the project as an executable jar):

 java -jar WrapperStatusV5

To change any of the parameters, edit the Constants.java class, and modify the parameters of interest.

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
/**
 * @version 4/20/2016
 * @author kyragan
 * After saving the rest of the files to the directory, this is the file that one
 * should run to simulate how a contagious virus spread within a closed campus. 
 * This class contains 12 fields. It first call WrapperSP to generate the campus
 * schedule, then stores the following outputs: student hash table (sht), place hash
 * table (pht), and student hash table key (sID). see the specific explanations for
 * the remaining fields inside the class.
 * updateAll(String place, String date) updates all student values at a given place 
 * on a certain date in the place hash table. It is called before at the beginning
 * of everyday and after each new recipient is created.
 * generateFirstStudent() generates a random first infected student
 * generatePlace() iterates through all the current keys inside the status value hash 
 * table, and generate a list of places to iterate through for each day
 * updatePlaceHashTableGenerateInfections() looks into the data provided by a placeEntry,
 * generates new infected students, assigns recipients, and updates all related fields.
 * incrementdaycount() is called at the end of the day.
 * Simulation () puts everything together.
 * This class also contains mutiple toString() and toCSV() methods.
 * 
 */
public class WrapperStatusV5 {
	/**
	 * call WrapperSP to generate the student schedules
	 * use get method to get the fields in WrapperSP:
	 * sht: the student schedule hash table generated in WrapperSP
	 * pht: the place hash table generated in WrapperSP
	 * sID: all the keys of sht: is used to generated the first infected student.
	 * week: keep track of the week of the semester during the simulation
	 * daycount: keep track of the day of the week during the simulation
	 * firstInKey: the ID of the first infected student
	 */
	WrapperSP wrapper=null;
	Hashtable<String,StudentValue> sht=null;
	Hashtable<String,PlaceValue> pht=null;
	ArrayList<String> sID=null; 
	String newline = System.getProperty("line.separator");
	int week=0;
	int daycount=1;
	String firstInKey=null;


	/**
	 * call probability class to get access to the methods inside
	 */
	Probability prob=null;

	/**
	 * statusKey keeps track of all students under incubation and contagious periods
	 * contagiousKey keeps track of all students under contagious period.
	 */
	ArrayList<String> statusKey=null; 
	ArrayList<String> contagiousKey=null; 

	/**
	 * SVHT: status value hash table: store all the students who are under incubation and 
	 *       contagious periods with hashvalue: StatusValue: fields: status st, 
	 *       String source, ArrayList<Recipient> stRecpt,ArrayList<String> RecipientID
	 * RemissionHT: once a student enter the remission period, we are going to remove her
	 * 		 from the SVHT and add to ReimissionHT: this is the table we are going to at 
	 * 		 the end of the day.
	 */
	Hashtable<String,StatusValue> SVHT=null;
	Hashtable<String,StatusValue> RemissionHT=null;


	List<String> DDate=Arrays.asList("Mon","Tu","Wed","Th","Fri","Sa","Su"); 

	public WrapperStatusV5(){
		prob=new Probability();
		wrapper=new WrapperSP(Constants.file);
		sht=wrapper.getSHT();
		pht=wrapper.getPHT();
		sID=wrapper.getSID();
		statusKey=new ArrayList<String>();
		contagiousKey=new ArrayList<String>();
		SVHT=new Hashtable<String,StatusValue>();
		RemissionHT=new Hashtable<String,StatusValue>();
		simulate();
	}

	public Hashtable<String,StatusValue> getSVHT(){
		return SVHT;
	}

	public int RemissionHTsize(){
		return RemissionHT.size();
	}

	// according to our data, the size of the whole population on campus is 2624
	public float percentageStudentInfected(){
		return (float)(RemissionHT.size())/2624;
	}

	public Hashtable<String,StatusValue> getRemissionHT(){
		return RemissionHT;
	}

	public Hashtable<String,StudentValue> getsht(){
		return sht;
	}

	public Hashtable<String,PlaceValue> getpht(){
		return pht;
	}

	public ArrayList<String> getContagiousKey(){
		return contagiousKey;
	}

	public void updateAll(String place, String date){
		PlaceValue mypv=pht.get(place);
		for(int i=mypv.getFirstIndexOfDates(date);i<mypv.getLastIndexOfDates(date)+1;i++){
			ArrayList<String> studentID=mypv.getPlaceEntry().get(i).getStudentID();
			ArrayList<String> contagiousID=mypv.getPlaceEntry().get(i).getContagiousID();
			ArrayList<String> healthyID=mypv.getPlaceEntry().get(i).getHealthyID();
			ArrayList<String> vaccineID=mypv.getPlaceEntry().get(i).getHvaccineID();
			for(Iterator<String> it=studentID.iterator();it.hasNext();){
				String mynext=it.next();
				if(SVHT.containsKey(mynext)){
					if(!healthyID.remove(mynext)){
						vaccineID.remove(mynext);
					}
					if(SVHT.get(mynext).getSt().checkContagious()){
						if(!contagiousID.contains(mynext)){
							contagiousID.add(mynext);
						}
					}
				}
				else if(RemissionHT.containsKey(mynext)){
					if(!healthyID.remove(mynext)){
						vaccineID.remove(mynext);
					}
					contagiousID.remove(mynext);
				}
			}
		}
	}


	//add recipient and update the SVHT
	public void addRecipient(String ID, Recipient r){
		if(!SVHT.containsKey(ID)){
			//System.out.println(ID);
			//System.out.println("well");
			//System.exit(0);
		}
		StatusValue sv=SVHT.get(ID);
		if(sv.addrecp(r)){
			String id="";
			for(int i=0;i<r.getID().size();i++){
				id+=r.getID().get(i)+",";
			}
			Log.log(ID+" infected the following people: " + id +" on "+sv.getSt().getCurrentDate());
		}else{
			System.out.println("fail to add recipients");
		}
	}


	/**
	 * generateFirstStudent : pick a random student to be infected on the first day,
	 * generate her value and add to the status table 
	 * and then get the first place she is going to be on that day, and update her status
	 * before entering the loop (starting from day one)
	 * this is the function we call we call first in the simulation function
	 */
	public boolean generateFirstStudent(){
		if(!Constants.setFirstInKey){
			//first we pick the first student to be infected
			int r=prob.myRandn(0,sID.size()-1);
			boolean run=true;
			while(run){
				firstInKey=sID.get(r);
				if(!Constants.vaccineID.containsKey(firstInKey)){
					run=false;
				}
			}
		}else{
			firstInKey=Constants.firstInKey;
		}
		//generate the first student incubation startT, data, etc

		Time t1=new Time("Mon",0000);
		Status s1=new Status(t1,week);

		//source="0" represent she is the source
		StatusValue firsv=new StatusValue("0",s1);
		//push the first value generated into the status value hash table
		SVHT.put(firstInKey,firsv);
		statusKey.add(firstInKey);

		Log.log(firstInKey+" first get infected, enter incubation period");

		return true;
	}

	/**
	 * loop through the key in the status table and get all the places these students going to be 
	 * on day j, and update these students' status on the place hash table
	 * 
	 */

	public ArrayList<String> generatePlace(){
		ArrayList<String> place=new ArrayList<String>();
		String currentDate="";

		for(int i=0;i<statusKey.size();i++){
			String key=statusKey.get(i);
			Status currentStatus=SVHT.get(key).getSt();
			//debug statement
			if(currentStatus.CEndTimeExist()){
				System.out.println("WrapperStatusV5.generatePlace(): check statuskey");
				System.exit(0);
			}

			//generate current date
			//notice for day j, all students should have the same currentDate
			if(currentDate.equals("")){
				currentDate=currentStatus.getCurrentDate();
				System.out.println("current date is: "+currentDate);
			}else{
				if (!currentDate.equals(currentStatus.getCurrentDate())){
					System.out.println("WrapperStatusV5.Simulation loop:"
							+ " wrong current date: simulation error"+
							"key="+key+"currentDate="+currentDate
							+",currentStatus.getCurrentDate()="+currentStatus.getCurrentDate());
					System.exit(0);
				}
			}

			/**
			 * generate the place list to iterate through for day j from(student i=key)
			 * and change healthyID, contagiousID list of the place according to her status
			 */
			ArrayList<StudentTimeEntry> localSTE=sht.get(key).getSTE();
			for(int index=0;index<localSTE.size();index++){
				Time localTime=localSTE.get(index).getTime();
				if(!localTime.getDate().equals(currentDate)){
					continue;
				}
				String localPlace=localSTE.get(index).getPlace();

				//first we should update those who are in remission now: move them
				//from the contagious list

				//update the all student status of the place;
				updateAll(localPlace,currentDate);


				//place is not suppose to be a long list now, so contains function
				//should be fine
				if(!place.contains(localPlace)){
					place.add(localPlace);
					//System.out.println(localPlace);
				}

			}

		}
		//add currentDate to the end of the list 
		place.add(currentDate);
		return place;
	}


	public void updatePlaceHashTableGenerateInfections(String myplace,String currentDate){
		PlaceValue mypv=pht.get(myplace);
		ArrayList<PlaceTimeEntry> currentList=mypv.getPlaceEntry();

		for(int entryindex=mypv.getFirstIndexOfDates(currentDate);
				entryindex<mypv.getLastIndexOfDates(currentDate)+1;entryindex++){
			PlaceTimeEntry myPTE=currentList.get(entryindex);
			//find the entries with the currentDate

			if(!myPTE.getTime().getDate().equals(currentDate)){
				System.out.println("WrapperStatusV5.updatePlaceHashTableGenerateInfectious: "
						+ "wrong for loop");
				System.exit(0);
			}
			if(Constants.quarantine){
				//System.out.println("quarantine");
				if(!Constants.quarantineHouse){
					if(!Character.isDigit(myplace.toCharArray()[0])){ // we use this line to differentiate
						//between regular classrooms(is String in letter and number format, but always
						//starts with letter) and houses(is a number in String format)
						if(myPTE.stdNum()>=Constants.quarantineSize){
							continue;
						}
					}
				}else{
					if(myPTE.stdNum()>=Constants.quarantineSize){
						continue;
					}
				}
			}
			//find the entries have contagious students
			ArrayList<String> myConID=myPTE.getContagiousID();
			ArrayList<String> myHealthyID=myPTE.getHealthyID();
			ArrayList<String> myHvaccineID=myPTE.getHvaccineID();
			//System.out.println(myConID.size());
			//System.out.println(myHealthyID.size());
			//System.out.println(myHvaccineID.size());
			Time mytime=myPTE.getTime();
			// if everyone in the place is already infected, we are not interested in
			//iterating through that place anymore
			updateAll(myplace,currentDate);
			if(myHealthyID.isEmpty()){
				if(myHvaccineID.isEmpty()){
					continue;
				}
			}else{

				if(myConID.isEmpty()){
					continue;
				}

				ArrayList<ArrayList<String>> result=prob.assignRecipients(myHealthyID,myHvaccineID, myConID);
				if(!result.isEmpty()){
					for(int resultIndex=0;resultIndex<result.size();resultIndex++){
						ArrayList<String> recp=result.get(resultIndex);
						String mysource=recp.remove(recp.size()-1);
						for(int recpIndex=0;recpIndex<recp.size();recpIndex++){ 
							//the last index is the source
							Time myincubation=new Time(currentDate,mytime.getStartT());
							Status mystatus=new Status(myincubation,week);
							StatusValue mysv=new StatusValue(mysource,mystatus);
							SVHT.put(recp.get(recpIndex), mysv);
							statusKey.add(recp.get(recpIndex));
							//System.out.println(SVHT.get(recp.get(recpIndex)).getSt().checkContagious());
							//System.out.println(statusKey.size());
							//System.out.println("recipient:"+recp.get(recpIndex)+";currentDate="+currentDate);
						}
						Recipient myr=new Recipient(myplace, week,mytime,recp);
						//System.out.println(recp.size());
						//System.out.println(mysource);
						addRecipient(mysource,myr);

					}

				}
			}
		}
	}


	public void simulate(){
		generateFirstStudent();

		for(int j=0;j<Constants.iterationPeriod;j++){
			//System.out.println(PrintArrayList(statusKey));
			//iterate through all the existing key in the status hash table
			ArrayList<String> place=generatePlace();
			String currentDate=place.get(place.size()-1);//the last element of the place

			Log.log("current daycount: "+daycount+"current week: "+week+"Current date: "+currentDate);

			/**
			 *now we want to generate the people infected in each place and update the tables
			 *looping through the place list to simulate the virus spread
			 *probability of getting infected if (contact==True) =1
			 */
			for(int placeindex=0;placeindex<place.size()-1;placeindex++){
				String myplace=place.get(placeindex);
				//ArrayList<PlaceTimeEntry> currentList=pht.get(myplace).getPlaceEntry();
				updatePlaceHashTableGenerateInfections(myplace, currentDate);
			}

			//increment daycount in the end
			incrementdaycount();


			//need to increment week and daycount here
			daycount+=1;
			if(daycount>7){
				week+=1;
				daycount=daycount%7;
			}
			if(statusKey.isEmpty()){
				break;
			}
		}
	}

	public void incrementdaycount(){
		//increment daycount in the end
		for (Iterator<String> it=statusKey.iterator();it.hasNext();){
			String key=it.next();
			Status currentStatus=SVHT.get(key).getSt();
			//System.out.println(key+" "+currentStatus.checkContagious());
			if(currentStatus.checkContagious()){
				//increment the daycount for contagious
				Status s=SVHT.get(key).getSt();
				s.IncreaseContagiousDaycount();
				//System.out.println(s.getCurrentDate());
				if(s.CEndTimeExist()){
					it.remove();
					Log.log(key+" recovered, enter remission period on "+s.getCurrentDate());
					contagiousKey.remove(key);
					RemissionHT.put(key, SVHT.get(key));
					SVHT.remove(key);
				}
			}else{
				Status s=SVHT.get(key).getSt();
				s.IncreaseIncubationDaycount();
				if(s.checkContagious()){
					Log.log(key+" become contagious, enter contagious period on "+s.getCurrentDate());
					contagiousKey.add(key);
				}		

			}
		}

	}


	public String toStringRemissionHT(){
		String hashstring="";
		for(Entry<String,StatusValue> entry : RemissionHT.entrySet()){
			hashstring += entry.getKey() + "=" +newline
					+entry.getValue().toString();
		}
		return hashstring;  
	}

	public String toStringRemissionHTV2(){
		String hashstring="";
		for(Entry<String,StatusValue> entry : RemissionHT.entrySet()){
			hashstring += entry.getKey() + "=" +newline
					+entry.getValue().toStringV2();
		}
		return hashstring;  
	}

	public String toCSVRemissionHT(){
		String csv="";
		for(Entry<String,StatusValue> entry : RemissionHT.entrySet()){
			csv += entry.getKey() + "," 
					+entry.getValue().toCSV()+newline;
		}
		return csv;
	}

	public String toCSVRemissionHTV2(){
		String csv="";
		for(Entry<String,StatusValue> entry : RemissionHT.entrySet()){
			csv += entry.getKey() + "," 
					+entry.getValue().toCSVV2()+newline;
		}
		return csv;
	}

	public String toCSVRemissionHTV3(){
		String csv=percentageStudentInfected()+","+newline;
		for(Entry<String,StatusValue> entry : RemissionHT.entrySet()){
			csv += entry.getKey() + "," 
					+entry.getValue().toCSVV3();
			if(Constants.vaccineID.containsKey(entry.getKey())){
				csv+="1";
			}else{
				csv+="0";
			}
			csv+=","+newline;
		}
		return csv;
	}

	/**
	 * this version gives ID, source,recipient size, week of infection, incubation, contagious, recipients(place, week, time, ID)
	 */
	public void saveCSVRemissionHT(){
		try (PrintWriter out =new PrintWriter(Constants.saveFileAs+"V1.csv")){
			out.println(toCSVRemissionHT());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * this version gives ID, source, week of infection, incubation, contagious, recipients(place, day of the semester, startT, ID)
	 */
	public void saveCSVRemissionHTV2(){
		try (PrintWriter out =new PrintWriter(Constants.saveFileAs+"V2.csv")){
			out.println(toCSVRemissionHTV2());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * this version gives ID, source, recipients size, day of the semester when infected, whether vaccinated (0-no,1-yes)
	 */
	public void saveCSVRemissionHTV3(){
		try (PrintWriter out =new PrintWriter(Constants.saveFileAs+"V3.csv")){
			out.println(toCSVRemissionHTV3());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * this function test confirms the source and the recipient have contacts according 
	 * to their class schedules 
	 * 
	 */
	public boolean testRecipientContact(String key){
		ArrayList<Recipient> recptskey=RemissionHT.get(key).getStRecpt();
		if(recptskey.isEmpty()){
			return true;
		}else{
			for(int i=0;i<recptskey.size();i++){	
				Recipient r=recptskey.get(i);
				ArrayList<String> ID=r.getID();
				Time time=r.getTime();
				String date=time.getDate();
				String place=r.getPlace();
				PlaceValue mypv=pht.get(place);
				for(int placeindex=mypv.getFirstIndexOfDates(date);
						placeindex<mypv.getLastIndexOfDates(date);placeindex++){
					PlaceTimeEntry pte=mypv.getPlaceEntry().get(placeindex);
					if(pte.getTime().timeOrder()==time.timeOrder()){
						if(!pte.getStudentID().containsAll(ID)){
							return false;
						}
						break;
					}
				}
			}
			return true;
		}
	}

	/**
	 * this is the default toDot() function built in the WrapperStatus class 
	 * @return the content of the dot file 
	 */
	public String toDot(){
		// partition the whole population into two groups
		//the list who have recipients, and the one who don't
		//and we use invisibleNodes to keep track of the length of the branch
		ArrayList<String> source=new ArrayList<String>();
		ArrayList<String> invisibleNodes=new ArrayList<String>();
		//initialize invisible nodes list
		for(Entry<String,StatusValue> entry: RemissionHT.entrySet()){
			if(!entry.getValue().getSource().equals("0")){
				int currentday=entry.getValue().getSt().getinfectionDay();
				int sourceday=RemissionHT.get(entry.getValue().getSource()).getSt().getinfectionDay();
				if(currentday-sourceday>1){
					int steps=(int) ((currentday-sourceday-1)/Constants.edgeDiscountFactor);
					for(int i=0;i<steps;i++){
						invisibleNodes.add("m"+invisibleNodes.size());	
					}
				}
			}
		}

		String dot="digraph spread {"+newline+"rankdir=LR;"+newline+"root="+firstInKey+";"
				+newline+"ranksep=3.0;"
				+newline+"nodesep=2.0;"+newline+"orientation=\"landscape\";"+newline+
				firstInKey+newline;
		//first iterate through the sources
		//the size of the node reflect the number of recipient: log(1+#of recipient*0.2)
		for(Entry<String,StatusValue> entry: RemissionHT.entrySet()){
			String mysource=entry.getValue().getSource();
			if(!source.contains(mysource)){
				if(mysource.equals("0")){
					dot+=entry.getKey()+" [fillcolor=";
					if(!Constants.vaccineID.containsKey(entry.getKey())){
						dot+="coral1";
					}else{
						dot+="limegreen";
					}
					dot+=",shape=doublecircle,"+"width="+
							entry.getValue().getRecipientID().size()*0.2+
							",style=filled,"+ "fontsize=12];"+newline;
					source.add(entry.getKey());
				}
				else{
					dot+=mysource+" [fillcolor=\"";
					if(Constants.vaccineID.contains(mysource)){
						dot+="limegreen\"";
					}else{
						dot+="goldenrod1\"";
					}
					dot+=",shape=circle,"+"width="+
							//Math.log(1+RemissionHT.get(mysource).getRecipientID().size()*0.2)+
							RemissionHT.get(mysource).getRecipientID().size()*0.2+
							",style=filled,"+ "fontsize=12];"+newline;
					source.add(mysource);
				}
			}
		}
		//initialize invisible nodes
		dot+="{node[shape=point,style=invis] ";
		for(int i=0;i<invisibleNodes.size();i++){
			dot+=invisibleNodes.get(i)+" ";
		}
		dot+="}"+newline;

		//then we iterate through the keys and add edges
		for(Entry<String,StatusValue> entry: RemissionHT.entrySet()){
			String mykey=entry.getKey();
			if(!source.contains(mykey)){
				dot+=mykey+" [shape=point,fillcolor=\"";
				if(Constants.vaccineID.containsKey(mykey)){
					dot+="limegreen";
				}else{
					dot+="blueviolet";
				}
				dot+="\",width=0.2,style=filled,"
						+ "fontsize=12];"+newline;
			}
		}
		Iterator<String> it=invisibleNodes.iterator();
		for(Entry<String,StatusValue> entry: RemissionHT.entrySet()){
			String mykey=entry.getKey();
			String mysource=entry.getValue().getSource();
			if(!mysource.equals("0")){
				dot+=mysource;
				int currentday=entry.getValue().getSt().getinfectionDay();
				int sourceday=RemissionHT.get(entry.getValue().getSource()).getSt().getinfectionDay();
				int steps=(int) (currentday/Constants.edgeDiscountFactor)
						-(int) (sourceday/Constants.edgeDiscountFactor)-1;
				for(int i=0;i<steps;i++){
					dot+="->"+it.next();
				}
				dot+="->"+mykey+"[arrowsize=0.4, penwidth=1.2,color="
						+ "\"dimgray\"]"+";"+newline;
			}
		}

		dot+="}";
		return dot;
	}

	//this function writes the dot file for plotting the recipient source relationship and
	//the edge is stamped by the day of the semester
	public void saveRHTtoDotFile(){
		try (PrintWriter out =new PrintWriter(Constants.saveFileAs+"V2.dot")){
			out.println(toDot());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	public String getFirstInKey(){
		return firstInKey;
	}

	public static void main(String[] args){
		Log.setEnable(Constants.setLog);
		WrapperStatusV5 ws=new WrapperStatusV5();
		ws.saveCSVRemissionHTV3();
		System.out.println(Constants.vaccineID.size());
		System.out.println(Constants.vaccineID.containsKey("2571"));
		System.out.println(ws.getFirstInKey());
		System.out.println(ws.getSVHT().size());
		System.out.println(ws.getRemissionHT().size());
		System.out.println(ws.getsht().size());
		System.out.println(ws.getpht().size());
		
	}



}


WrapperStatusV5Test.java


/**
 * @author kyragan
 * @version 4/2/2016
 * This class is served as the main function for WrapperStatusV4 at current stage
 */
import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Map.Entry;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class WrapperStatusV5Test {

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	
	@Test
	public void testMain() {
		Log.setEnable(Constants.setLog);
		WrapperStatusV5 ws=new WrapperStatusV5();
		//ws.saveRHTtoDotFile();
		ws.saveCSVRemissionHTV3();
		System.out.println(Constants.vaccineID.size());
		System.out.println(Constants.vaccineID.containsKey("2571"));
		//System.out.println(ws.pht.toString());
		//System.out.println(ws.toStringRemissionHT());
		//System.out.println(ws.toCSVRemissionHT());
		//System.out.println(ws.toStringRemissionHTV2());
		//System.out.println(ws.toCSVRemissionHTV2());
		
		for(Entry<String,StatusValue> entry: ws.getRemissionHT().entrySet()){
			assertTrue(ws.testRecipientContact(entry.getKey()));
		}
		
	}

}


WrapperStatusV4.java


package mostRecent;


import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

/**
 * @version 3/27/2016
 * @author kyragan
 * This is a lower version (developing version) of WrapperStatusV5 that does not contain Recipient structure.
 * One should run WrapperStatusV5 instead.
 * This file runs the virus spread simulation and generates the status hash table
 */
public class WrapperStatusV4 {
	/**
	 * call WrapperSP to generate the student schedules
	 * use get method to get the fields in WrapperSP:
	 * sht: the student schedule hash table generated in WrapperSP
	 * pht: the place hash table generated in WrapperSP
	 * sID: all the keys of sht: is used to generated the first infected student.
	 */
	WrapperSP wrapper=null;
	Hashtable<String,StudentValue> sht=null;
	Hashtable<String,PlaceValue> pht=null;
	ArrayList<String> sID=null; 

	/**
	 * call probability class to get access to the methods inside
	 */
	Probability prob=null;

	/**
	 * statusKey keeps track of all students under incubation and contagious periods
	 * contagiousKey keeps track of all students under contagious period.
	 */
	ArrayList<String> statusKey=null; 
	ArrayList<String> contagiousKey=null; 

	/**
	 * SVHT: status value hash table: store all the students who are under incubation and 
	 *       contagious periods with hashvalue: StatusValue: fields: status st, 
	 *       String source, ArrayList<Recipient> stRecpt,ArrayList<String> RecipientID
	 * RemissionHT: once a student enter the remission period, we are going to remove her
	 * 		 from the SVHT and add to ReimissionHT: this is the table we are going to at 
	 * 		 the end of the day.
	 */
	Hashtable<String,StatusValueV2> SVHT=null;
	Hashtable<String,StatusValueV2> RemissionHT=null;


	List<String> DDate=Arrays.asList("Mon","Tu","Wed","Th","Fri","Sa","Su"); 

	public WrapperStatusV4(){
		prob=new Probability();
		wrapper=new WrapperSP(Constants.file);
		sht=wrapper.getSHT();
		pht=wrapper.getPHT();
		sID=wrapper.getSID();
		statusKey=new ArrayList<String>();
		contagiousKey=new ArrayList<String>();
		SVHT=new Hashtable<String,StatusValueV2>();
		RemissionHT=new Hashtable<String,StatusValueV2>();
		simulate();
	}

	public Hashtable<String,StatusValueV2> getSVHT(){
		return SVHT;
	}

	public Hashtable<String,StatusValueV2> getRemissionHT(){
		return RemissionHT;
	}

	public ArrayList<String> getContagiousKey(){
		return contagiousKey;
	}


	//given a student ID, remove her from the healty ID of her place at a given time
	public boolean removeHealthyID(String ID, String place1, Time time1){

		//first we find her in the place entries
		PlaceValue mypv=pht.get(place1);
		ArrayList<PlaceTimeEntry> pe= mypv.getPlaceEntry();
		String mydate=time1.getDate();
		//we are going to directly jump into the current time in time1 in the pe
		for(int i=mypv.getFirstIndexOfDates(mydate);i<mypv.getLastIndexOfDates(mydate)+1;i++){
			PlaceTimeEntry pte=pe.get(i);
			if(pte.getTime().equals(time1)){
				//Log.log("pte.getTime()="+pte.getTime().toString());	
				if(pte.removeHID(ID)){
					return true;
				}
			}
		}
		return false;
	}

	//same logic as above, we need to write a method to addConID
	public void addConID(String ID, String place1, Time time1){

		//first we find her in the place entries
		PlaceValue mypv=pht.get(place1);
		ArrayList<PlaceTimeEntry> pe= mypv.getPlaceEntry();
		String mydate=time1.getDate();
		//this should be efficient since this is the first infected student, the 
		//entry contains her should be close to the beginning
		for(int i=mypv.getFirstIndexOfDates(mydate);i<mypv.getLastIndexOfDates(mydate)+1;i++){
			PlaceTimeEntry pte=pe.get(i);
			if(pte.getTime().equals(time1)){
				if(pte.addConID(ID)){    //the only difference between the methods
					break;
				}else{
					break;
				}
			}
		}
	}


	//same logic as above, we need to write a method to addConID
	public void removeHaddConID(String ID, String place1, Time time1){

		//first we find her in the place entries
		PlaceValue mypv=pht.get(place1);
		ArrayList<PlaceTimeEntry> pe= mypv.getPlaceEntry();
		String mydate=time1.getDate();
		//this should be efficient since this is the first infected student, the 
		//entry contains her should be close to the beginning
		for(int i=mypv.getFirstIndexOfDates(mydate);i<mypv.getLastIndexOfDates(mydate)+1;i++){
			PlaceTimeEntry pte=pe.get(i);
			if(pte.getTime().equals(time1)){
				pte.removeHID(ID);
				pte.addConID(ID);    //the only difference between the methods
				break;
			}
		}
	}


	//same logic as above, we need to write a method to removeConID
	public boolean removeConID(String ID, String place1, Time time1){
		//Log.log(String.format("WrapperStatusV2.removeConID(%s,%s,%s)",ID,place1,time1.toString()));
		//first we find her in the place entries
		PlaceValue mypv=pht.get(place1);
		ArrayList<PlaceTimeEntry> pe= mypv.getPlaceEntry();
		String mydate=time1.getDate();
		//this should be efficient since this is the first infected student, the 
		//entry contains her should be close to the beginning
		for(int i=mypv.getFirstIndexOfDates(mydate);i<mypv.getLastIndexOfDates(mydate)+1;i++){
			PlaceTimeEntry pte=pe.get(i);
			if(pte.getTime().equals(time1)){
				if(pte.removeConID(ID)){    //the only difference between the methods
					return true;
				}else{
					Log.log("pte="+pe.toString());
				}
			}
		}
		return false;
	}


	int week=0;
	int daycount=1;
	String firstInKey;
	//this function returns the current day of the semester
	public int getCurrentDaycount(){
		return week*7+daycount;
	}

	/**
	 * generateFirstStudent : pick a random student to be infected on the first day,
	 * generate her value and add to the status table 
	 * and then get the first place she is going to be on that day, and update her status
	 * before entering the loop (starting from day one)
	 * this is the function we call we call first in the simulation function
	 */
	public boolean generateFirstStudent(){

		//first we pick the first student to be infected
		int r=prob.randn(0,sID.size()-1);
		firstInKey=sID.get(r);
		//generate the first student incubation startT, data, etc

		Time t1=new Time("Mon",0000);
		String myplace=sht.get(firstInKey).getSTE().get(0).getPlace();
		StatusV2 s1=new StatusV2(t1,daycount,myplace);

		//source="-1" represent she is the source
		StatusValueV2 firsv=new StatusValueV2("0",s1);
		//push the first value generated into the status value hash table
		SVHT.put(firstInKey,firsv);
		statusKey.add(firstInKey);

		Log.log(firstInKey+" first get infected, enter incubation period");

		return true;
	}

	/**
	 * loop through the key in the status table and get all the places these students going to be 
	 * on day j, and update these students' status on the place hash table
	 * 
	 */

	public ArrayList<String> generatePlace(){
		ArrayList<String> place=new ArrayList<String>();
		String currentDate="";

		for(int i=0;i<statusKey.size();i++){
			String key=statusKey.get(i);
			StatusV2 currentStatus=SVHT.get(key).getSt();

			//generate current date
			//notice for day j, all students should have the same currentDate
			if(currentDate.equals("")){
				currentDate=currentStatus.getCurrentDate();
				System.out.println("current date is: "+currentDate);
			}else{
				if (!currentDate.equals(currentStatus.getCurrentDate())){
					System.out.println("WrapperStatusV3.Simulation loop:"
							+ " wrong current date: simulation error");
					System.exit(0);
				}
			}

			/**
			 * generate the place list to iterate through for day j from(student i=key)
			 * and change healthyID, contagiousID list of the place according to her status
			 */
			ArrayList<StudentTimeEntry> localSTE=sht.get(key).getSTE();
			for(int index=0;index<localSTE.size();index++){
				Time localTime=localSTE.get(index).getTime();
				if(!localTime.getDate().equals(currentDate)){
					continue;
				}
				String localPlace=localSTE.get(index).getPlace();
				//first we should update those who are in remission now: move them
				//from the contagious list


				if(!currentStatus.checkContagious()){

					removeHealthyID(key,localPlace,localTime);
					continue;

				}
				//move the student ID of the current day to contagious ID

				if(currentStatus.getContagious().getDaycount()<(7-Constants.incubationLimit)){
					removeHaddConID(key,localPlace,localTime);
				}else{
					addConID(key,localPlace,localTime);
				}
				//addConId is going to check whether the student is already in contagious
				//list

				//place is not suppose to be a long list now, so contains function
				//should be fine
				if(!place.contains(localPlace)){
					place.add(localPlace);
				}

			}

		}
		//add currentDate to the end of the list 
		place.add(currentDate);
		return place;
	}


	public void updatePlaceHashTableGenerateInfections(String myplace,String currentDate){
		PlaceValue mypv=pht.get(myplace);
		ArrayList<PlaceTimeEntry> currentList=mypv.getPlaceEntry();

		for(int entryindex=mypv.getFirstIndexOfDates(currentDate);
				entryindex<mypv.getLastIndexOfDates(currentDate)+1;entryindex++){
			PlaceTimeEntry myPTE=currentList.get(entryindex);
			//find the entries with the currentDate

			if(!myPTE.getTime().getDate().equals(currentDate)){
				System.out.println("WrapperStatusV3.updatePlaceHashTableGenerateInfectious: "
						+ "wrong for loop");
				System.exit(0);
			}
			//find the entries have contagious students
			ArrayList<String> myConID=myPTE.getContagiousID();
			ArrayList<String> myHealthyID=myPTE.getHealthyID();
			Time mytime=myPTE.getTime();
			// if everyone in the place is already infected, we are not interested in
			//iterating through that place anymore

			if(myHealthyID.isEmpty()){
				continue;
			}else{

				if(myConID.isEmpty()){
					continue;
				}
				//need to check first that these ID whether has recovered or not
				for(Iterator<String> it=myConID.iterator();it.hasNext();){
					String mynext=it.next();
					if(!SVHT.containsKey(mynext)){
						it.remove();
					}
				}
				//need to check it again

				if(myConID.isEmpty()){
					continue;
				}


				ArrayList<String> healthy=myPTE.getHealthyID();

				//since all students are going to be infected, we use removeHealthyID
				//function to update the placeValue for all students
				for(Iterator<String> it=healthy.iterator();it.hasNext();){

					//we want to keep the loop here instead of adding a arraylist of id
					//here because it would be easier to modify when p!=1
					String mystudent=it.next();

					if(statusKey.contains(mystudent)){
						it.remove();
					}
				}
				ArrayList<ArrayList<String>> result=prob.assignRecipients(healthy, myConID);
				if(!result.isEmpty()){
					for(int resultIndex=0;resultIndex<result.size();resultIndex++){
						ArrayList<String> recp=result.get(resultIndex);
						String mysource=recp.remove(recp.size()-1);
						for(int recpIndex=0;recpIndex<recp.size();recpIndex++){ 
							//the last index is the source
							Time myincubation=new Time(currentDate,mytime.getStartT());
							StatusV2 mystatus=new StatusV2(myincubation,getCurrentDaycount(),myplace);
							StatusValueV2 mysv=new StatusValueV2(mysource,mystatus);
							SVHT.put(recp.get(recpIndex), mysv);
							statusKey.add(recp.get(recpIndex));
						}
					}
				}
			}
		}
	}


	public void simulate(){
		generateFirstStudent();

		for(int j=0;j<Constants.iterationPeriod;j++){

			//System.out.println(PrintArrayList(statusKey));
			//iterate through all the existing key in the status hash table
			ArrayList<String> place=generatePlace();
			String currentDate=place.get(place.size()-1);//the last element of the place

			Log.log("current daycount: "+daycount+"current week: "+week+"Current date: "+currentDate);

			/**
			 *now we want to generate the people infected in each place and update the tables
			 *looping through the place list to simulate the virus spread
			 *probability of getting infected if (contact==True) =1
			 */
			for(int placeindex=0;placeindex<place.size()-1;placeindex++){
				String myplace=place.get(placeindex);
				//ArrayList<PlaceTimeEntry> currentList=pht.get(myplace).getPlaceEntry();
				updatePlaceHashTableGenerateInfections(myplace, currentDate);
			}

			//increment daycount in the end
			incrementdaycount();


			//need to increment week and daycount here
			daycount+=1;
			if(daycount>7){
				week+=1;
				daycount=daycount%7;
			}
			if(statusKey.isEmpty()){
				break;
			}
		}
	}

	public void incrementdaycount(){
		//increment daycount in the end
		for (Iterator<String> it=statusKey.iterator();it.hasNext();){
			String key=it.next();
			StatusV2 currentStatus=SVHT.get(key).getSt();
			if(currentStatus.checkContagious()){
				//increment the daycount for contagious
				StatusV2 s=SVHT.get(key).getSt();
				s.IncreaseContagiousDaycount();
				StatusValueV2 sv=new StatusValueV2(SVHT.get(key).getSource(),s);
				if(s.CEndTimeExist()){
					it.remove();
					Log.log(key+" recovered, enter remission period on "+s.getCurrentDate());
					contagiousKey.remove(key);
					SVHT.remove(key);
					RemissionHT.put(key, sv);
				}else{
					SVHT.put(key, sv);
				}
			}else{
				StatusV2 s=SVHT.get(key).getSt();
				s.IncreaseIncubationDaycount();
				if(s.checkContagious()){
					Log.log(key+" become contagious, enter contagious period on "+s.getCurrentDate());
					contagiousKey.add(key);
				}		
				StatusValueV2 sv=new StatusValueV2(SVHT.get(key).getSource(),s);
				SVHT.put(key, sv);

			}
		}

	}

	public String PrintArrayList(ArrayList<String> as){
		String myarr="";
		for(int i=0;i<as.size();i++){
			myarr+=as.get(i)+"|";
		}
		return myarr;
	}

	String newline = System.getProperty("line.separator");
	public String toStringRemissionHT(){
		String hashstring="";
		for(Entry<String,StatusValueV2> entry : RemissionHT.entrySet()){
			hashstring += entry.getKey() + "=" +newline
					+entry.getValue().toString();
		}
		return hashstring;  
	}

	public String toCSVRemissionHT(){
		String csv="";
		csv+="ID,source,daycount,place,incubDate,incubStartT,incubEndT,"
				+ "incubDaycount,contagDate,contagStartT,contagEndT,"
				+ "contagDaycount"+newline;
		for(Entry<String,StatusValueV2> entry : RemissionHT.entrySet()){
			csv += entry.getKey() + "," 
					+entry.getValue().toCSV()+newline;
		}
		return csv;
	}


	public void saveCSVRemissionHT(){
		try (PrintWriter out =new PrintWriter("remissionHTV2.csv")){
			out.println(toCSVRemissionHT());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


	public String toDot(){
		// partition the whole population into two groups
		//the list who have recipients, and the one who don't
		ArrayList<String> source=new ArrayList<String>();
		String dot="digraph spread {"+newline+"rankdir=LR;"+newline+"root="+firstInKey+";"
				+newline+"ranksep=3.0;"
				+newline+"nodesep=2.0;"+newline+"orientation=\"landscape\";"+newline+
				firstInKey+newline;
		//first iterate through the sources
		for(Entry<String,StatusValueV2> entry: RemissionHT.entrySet()){
			String mysource=entry.getValue().getSource();
			if(!source.contains(mysource)){
				if(mysource.equals("0")){
					dot+=entry.getKey()+" [fillcolor=\"goldenrod1\",shape=doublecircle,style=filled,"
							+ "fontsize=12];"+newline;
					source.add(entry.getKey());
				}
				else{
					dot+=mysource+" [fillcolor=\"coral1\",shape=circle,style=filled,"
							+ "fontsize=12];"+newline;
					source.add(mysource);
				}
			}
		}
		//then we iterate through the keys and add edges
		for(Entry<String,StatusValueV2> entry: RemissionHT.entrySet()){
			String mykey=entry.getKey();
			if(!source.contains(mykey)){
				dot+=mykey+" [shape=point,fillcolor=\"blueviolet\",width=0.2,style=filled,"
						+ "fontsize=12];"+newline;
			}
		}
		for(Entry<String,StatusValueV2> entry: RemissionHT.entrySet()){
			String mykey=entry.getKey();
			String mysource=entry.getValue().getSource();
			if(!mysource.equals("0")){
				dot+=mysource+"->"+mykey+"[arrowshape=none, penwidth=1.2,color="
						+ "\"dimgray\"]"+";"+newline;
			}
		}
		dot+="}";
		return dot;
	}

	//this function writes the dot file for plotting the recipient source relationship and
	//the edge is stamped by the day of the semester
	public void saveRHTtoDotFile(){
		try (PrintWriter out =new PrintWriter("remissionHTV2.dot")){
			out.println(toDot());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}


}


WrapperStatusV4Test.java


package mostRecent;

/**
 * @author kyragan
 * @version 3/27/2016
 * This class is served as the main function for WrapperStatusV4 at current stage
 */
import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.Hashtable;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class WrapperStatusV4Test {

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	
	@Test
	public void testMain() {
		Log.setEnable(Constants.setLog);
		WrapperStatusV4 ws=new WrapperStatusV4();
		//ws.saveCSVRemissionHT();
		//System.out.println(ws.toStringRemissionHT());
		System.out.println(ws.toCSVRemissionHT());

	}

}


Go back to: Visualizing the Transit Map of the Spread of an Infectious Disease