Java classes for FileFestivalPlanner project. Download all source files to same directory, compile and run from FestivalMain class.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package src.main.java; | |
import java.util.Collections; | |
import java.util.List; | |
/** | |
* Created by nwhit8 on 11/1/15. | |
*/ | |
public class Day { | |
String name = ""; | |
List<Film> populatedTrack; | |
public Day(String name, List<Film> completedTrackSchedule) { | |
this.name = name; | |
this.populatedTrack = completedTrackSchedule; | |
} | |
public Film getFilmFromTrack( String FilmTitle, Integer FilmDuration) { | |
Film searchTerm = new Film( FilmTitle, FilmDuration ); | |
if (!this.populatedTrack.contains( searchTerm)) { | |
return null; | |
} else { | |
int foundIndex = this.populatedTrack.indexOf( searchTerm); | |
return this.populatedTrack.get( foundIndex); | |
} | |
} | |
public int calculateTrackDuration() { | |
Integer result = 0; | |
for ( Film t : populatedTrack ) { | |
result = result + (Integer) t.getDuration(); | |
} | |
return result; | |
} | |
public void printTrack() { | |
Collections.sort( this.populatedTrack ); | |
System.out.println( this.name ); | |
for (Film t : populatedTrack ) { | |
System.out.println( t.toString() ); | |
} | |
} | |
public List<Film> getScheduledListOfFilms() { | |
return this.populatedTrack; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package src.main.java; | |
import java.util.ArrayList; | |
import java.util.List; | |
/** | |
* Created by nwhit8 on 11/1/15. | |
*/ | |
public class FestivalMain { | |
public static void main( String[] args ) { | |
String FILE = "src/main/java/input.txt"; | |
Utility utility = new Utility( FILE); | |
List<Day> dayCollection = new ArrayList<Day>(); | |
Session session = new Session (utility.getListOfFilms()); | |
Day results; | |
int trackCounter = 1; | |
while( session.getOriginalListOfFilms().size() > 0) { | |
results = session.assignStartTimes( trackCounter); | |
dayCollection.add( results); | |
trackCounter++; | |
} | |
for ( Day tr : dayCollection) { | |
tr.printTrack(); | |
System.out.println("\n"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package src.main.java; | |
/** | |
* Created by nwhit8 on 10/28/15. | |
* Data object | |
*/ | |
public class Film<L,R> implements Comparable<Film> { | |
private final L title; | |
private final R duration; | |
// one mutable field | |
private int startTime=0; | |
private int finishTime =0; | |
private int trackAssignment = 0; | |
public Film(L title, R duration) { | |
this.title = title; | |
this.duration = duration; | |
} | |
public L getTitle() { return title;} | |
public R getDuration() { return duration; } | |
public void setStartTime(int value) { | |
this.startTime = value; | |
} | |
public void setFinishTime( int value) { | |
this.finishTime = value; | |
} | |
public void setTrackAssignment( int value ) { | |
this.trackAssignment = value; | |
} | |
public int getFinishTime() { | |
return this.finishTime; | |
} | |
public int getStartTime() { | |
return this.startTime; | |
} | |
public int getTrackAssignment() { return this.trackAssignment; } | |
@Override | |
public int hashCode() { return title.hashCode() ^ duration.hashCode();} | |
@Override | |
public boolean equals( Object o ) { | |
if (!(o instanceof Film)) return false; | |
Film pairO = (Film) o; | |
return this.title.equals(( pairO.getTitle())) && | |
this.duration.equals( pairO.getDuration()); | |
} | |
public int compareTo( Film compareFilmFinishTimes) { | |
int compareFinishTime = ((Film) compareFilmFinishTimes).getFinishTime(); | |
return this.finishTime - compareFinishTime; | |
} | |
@Override | |
public String toString() { | |
String timeLabel = ""; | |
String durationAsString = ""; | |
String title = (String) getTitle(); | |
Integer duration = (Integer) getDuration(); | |
if (title.contains("Lunch") || title.contains("Networking")) { | |
durationAsString = ""; | |
} else if ( duration == 5) { | |
durationAsString = "lightning"; | |
} else { | |
durationAsString = duration + "min"; | |
} | |
int startTimeMinutes = getStartTime(); | |
String formattedStartTime =""; | |
formattedStartTime = convertMinutesToHoursMinutes(startTimeMinutes); | |
String track = formattedStartTime + " " + title + " " + durationAsString; | |
return track; | |
} | |
private String convertMinutesToHoursMinutes(int timeInMinutes) { | |
String conversion=""; | |
String timeLabel = ""; | |
int hours = timeInMinutes / 60; | |
int minutes = timeInMinutes % 60; | |
if (hours < Session.END_AM) { | |
timeLabel = "AM"; | |
} else { | |
timeLabel = "PM"; | |
hours = hours - 12; | |
} | |
/// zero pad both | |
String prettyHours = String.format( "%02d", hours); | |
String prettyMinutes = String.format( "%02d", minutes); | |
conversion = prettyHours + ":" + prettyMinutes; | |
return conversion; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Red State 120min | |
Precious 100min | |
Mayor of Beijeng 75min | |
Documentary TBA 80min | |
The Stranger 90min | |
Short Film lightning | |
Panel Discussion 60min | |
World Premeire 90min | |
Music Cafe 75min | |
Volunteer Appreciation Party 90min | |
Award Ceremony 45min | |
Volunteer Screening 100min | |
Animated Shorts 110min | |
New Frontier Artist Presentation 30min | |
Panel Discussion with Robert Redford 45min | |
Blair Witch Project 80min | |
Napoleon Dynamite 79min | |
Bowliing for Columbine 30min | |
Reagan 30min | |
Good Hair 70min | |
Kinky Boots 75min | |
Being Evel 60min | |
Saw 100min |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.List; | |
/** | |
* Session represents a full day of programming for a Festival attendee | |
* It has AM, Lunch, PM & NETWORKING. | |
* | |
*/ | |
public class Session implements Comparable<Session>{ | |
// refactor: Add EVENING segment to the day to cover special events or more films | |
int sessionStartTime = 0; | |
int trackAssignment = 0; | |
private static List<Film> INPUT; | |
public static List<Film> OUTPUT; | |
// duration of an AM or PM session. PM can also last up to 240min | |
public static int STANDARD_SESSION = 180; | |
// milestone for start of conference | |
public static int FESTIVAL_DAY_START = 9 * 60; | |
// milestone for lunch | |
public static int FESTIVAL_DAY_LUNCH = 12 * 60; | |
public static int FESTIVAL_DAY_RESUME = 13 * 60; | |
// milestone for networking event | |
public static int FESTIVAL_DAY_NETWORKING = 17 * 60; | |
public static int FESTIVAL_DAY_FINISH = 18 * 60; | |
// full day of programming. When reached, it is time to start a new trackAssignment | |
public static int FULL_TRACK = (18-9) * 60; | |
public Session(List<Film> choices) { | |
this.INPUT = choices; | |
} | |
public List<Film> getOriginalListOfFilms() { | |
return this.INPUT; | |
} | |
public List<Film> getScheduledSession() { | |
return this.OUTPUT; | |
} | |
/** | |
* Uses hashcode of title + duration to find a Film from a given List | |
* @param title | |
* @param duration | |
* @return | |
*/ | |
public Film getFilmFromSchedule(String title, Integer duration) { | |
Film searchTerm = new Film(title, duration); | |
if (!this.OUTPUT.contains(searchTerm)) { | |
return null; | |
} else { | |
int foundIndex = this.OUTPUT.indexOf( searchTerm); | |
return this.OUTPUT.get( foundIndex); | |
} | |
} | |
/** | |
* Gets all unscheduled Films that havea a certain duration | |
* @param searchTerm duration sought by user | |
* @return list of Films | |
*/ | |
public List<Film> searchInputByDuration(int searchTerm) { | |
ArrayList<Film> foundMatches = new ArrayList<Film>(); | |
String result =""; | |
if(FilmIsFound(this.INPUT)) { | |
for (Film t : INPUT) { | |
Integer duration = (Integer) t.getDuration(); | |
if (duration == searchTerm) { | |
foundMatches.add(t); | |
} | |
} | |
} | |
return foundMatches; | |
} | |
/** | |
* Creates a full track of programming (AM Session, Lunch, PM session, Networking) | |
* @return Track | |
* @param trackNumber identifies the track being created | |
*/ | |
public Day assignStartTimes(int trackNumber) { | |
Day completedDay; | |
this.trackAssignment = trackNumber; | |
List<Film> lightningFilms = searchInputByDuration(5); | |
int availableMinutes = INPUT.size() * 60; | |
int startNext = FESTIVAL_DAY_START; | |
Integer cumulativeFilmTime = 0; | |
int firstElement = 0; | |
int startFilm; | |
Integer currDuration; | |
this.OUTPUT = new ArrayList<Film>(); | |
// while (startNext <= FESTIVAL_DAY_NETWORKING && FilmIsFound( this.INPUT) ) { | |
while (startNext < FESTIVAL_DAY_NETWORKING && FilmIsFound( this.INPUT) ) { | |
/// assign Film to a time slot | |
Film s = INPUT.get(firstElement); | |
currDuration = (Integer) s.getDuration(); | |
startFilm = startNext; | |
s.setStartTime(startFilm); | |
s.setTrackAssignment(this.trackAssignment); | |
s.setFinishTime(startFilm + currDuration); | |
/// todo: add helper method to group events by duration so as to avoid overrunning lunch | |
this.OUTPUT.add(s); | |
availableMinutes = availableMinutes - currDuration; | |
startNext = s.getFinishTime(); | |
this.INPUT.remove(firstElement); | |
if (startNext == FESTIVAL_DAY_LUNCH || Math.abs(FESTIVAL_DAY_LUNCH - startNext) < 30) { | |
if (FilmIsFound(lightningFilms)) { | |
Film t = lightningFilms.get(firstElement); | |
startFilm = startNext; | |
currDuration = (Integer) t.getDuration(); | |
t.setStartTime(startFilm); | |
t.setFinishTime(startFilm + currDuration); | |
availableMinutes = availableMinutes - currDuration; | |
t.setTrackAssignment(this.trackAssignment); | |
startNext = t.getFinishTime(); | |
this.OUTPUT.add(t); | |
lightningFilms.remove(t); | |
this.INPUT.remove(t); | |
assignLunch(); | |
startNext = FESTIVAL_DAY_RESUME; | |
} else { | |
assignLunch(); | |
startNext = FESTIVAL_DAY_RESUME; | |
} | |
} | |
} | |
/// finish track with networking and lightning Film (if available) | |
if( FilmIsFound(lightningFilms)) { | |
Film t = lightningFilms.get(firstElement); | |
startFilm = startNext; | |
currDuration = (Integer) t.getDuration(); | |
t.setStartTime(startFilm); | |
t.setFinishTime( startFilm + currDuration); | |
availableMinutes = availableMinutes - currDuration; | |
t.setTrackAssignment(this.trackAssignment); | |
startNext = t.getFinishTime(); | |
this.OUTPUT.add(t); | |
lightningFilms.remove(t); | |
this.INPUT.remove(t); | |
assignNetworking(); | |
startNext = FESTIVAL_DAY_FINISH + 5; | |
} else { | |
//// assign networking only | |
assignNetworking(); | |
startNext = FESTIVAL_DAY_FINISH + 5; | |
} | |
//// FINISH TRACK | |
String trackName = "Track " + this.trackAssignment; | |
completedDay = new Day(trackName, this.OUTPUT); | |
return completedDay; | |
} | |
private boolean FilmIsFound(List<Film> listBeingSearched) { | |
return listBeingSearched.size() > 0; | |
} | |
private void assignLunch() { | |
Film lunch = new Film("Lunch", 60); | |
/// assign lunch | |
lunch.setStartTime(FESTIVAL_DAY_LUNCH); | |
lunch.setFinishTime( FESTIVAL_DAY_RESUME ); | |
this.OUTPUT.add(lunch); | |
this.INPUT.remove( lunch ); | |
} | |
private void assignNetworking() { | |
Film nw = new Film("Networking", 60); | |
/// assign lunch | |
nw.setStartTime(FESTIVAL_DAY_NETWORKING); | |
nw.setFinishTime( FESTIVAL_DAY_FINISH ); | |
this.OUTPUT.add(nw); | |
this.INPUT.remove( nw ); | |
} | |
public void printSchedule(List<Film> listOfFilms) { | |
Collections.sort( listOfFilms ); | |
for (Film s : listOfFilms) { | |
System.out.println( s.toString() ); | |
} | |
} | |
@Override | |
public int compareTo(Session compareTracks) { | |
int comparison = ((Session) compareTracks).getTrackAssignment(); | |
return this.trackAssignment; | |
} | |
public int getTrackAssignment() { | |
return trackAssignment; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package src.main.java; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.List; | |
/** | |
* Session is a collection of Films. It has two parts - AM and PM | |
* | |
*/ | |
public class Session implements Comparable<Session>{ | |
int sessionStartTime = 0; | |
int programmedDay = 0; | |
int totalProgramTime = 0; | |
private static List<Film> INPUT; | |
public static List<Film> OUTPUT; | |
public static int STANDARD_SESSION = 180; | |
public static int START_AM = 9 * 60; | |
public static int END_AM = 12 * 60; | |
public static int START_PM = 13 * 60; | |
public static int END_PM = 17 * 60; | |
public static int START_EVENING = 18 * 60; | |
public static int END_EVENING = 23 * 60 + 59; | |
// cumulative programmed time for a FESTIVAL DAY. When reached, start new Day of programming | |
public static int DAY_TRACK = (24- START_AM) * 60; | |
public Session(List<Film> choices) { | |
this.INPUT = choices; | |
} | |
public List<Film> getOriginalListOfFilms() { | |
return this.INPUT; | |
} | |
public List<Film> getScheduledSession() { | |
return this.OUTPUT; | |
} | |
/** | |
* Uses hashcode of title + duration to find a Film from a given List | |
* @param title | |
* @param duration | |
* @return | |
*/ | |
public Film getFilmFromSchedule(String title, Integer duration) { | |
Film searchTerm = new Film(title, duration); | |
if (!this.OUTPUT.contains(searchTerm)) { | |
return null; | |
} else { | |
int foundIndex = this.OUTPUT.indexOf( searchTerm); | |
return this.OUTPUT.get( foundIndex); | |
} | |
} | |
/** | |
* Gets all unscheduled Films that havea a certain duration | |
* @param searchTerm duration sought by user | |
* @return list of Films | |
*/ | |
public List<Film> searchInputByDuration(int searchTerm) { | |
ArrayList<Film> foundMatches = new ArrayList<Film>(); | |
String result =""; | |
if(FilmIsFound(this.INPUT)) { | |
for (Film t : INPUT) { | |
Integer duration = (Integer) t.getDuration(); | |
if (duration == searchTerm) { | |
foundMatches.add(t); | |
} | |
} | |
} | |
return foundMatches; | |
} | |
/** | |
* Creates a full track of programming (AM Session, Lunch, PM session, Networking, Evening) | |
* @return Possible Day Schedule (DAY TRACK) | |
* @param trackNumber Identifier for Day Schedule | |
*/ | |
public Day assignStartTimes(int trackNumber) { | |
Day completedDay; | |
boolean closestBreakIsLunch = true; | |
this.programmedDay = trackNumber; | |
List<Film> shortFilms = searchInputByDuration(5); | |
int availableMinutes = INPUT.size() * 60; | |
int startNext = START_AM; | |
Integer cumulativeFilmTime = 0; | |
int firstElement = 0; | |
int startFilm; | |
Integer currDuration; | |
this.OUTPUT = new ArrayList<Film>(); | |
// extend Day from 6 pm to 11:59 pm | |
while (startNext <= END_EVENING && FilmIsFound( this.INPUT) ) { | |
// determine if lunch or networking break is applicable | |
closestBreakIsLunch = startNext <= END_AM; | |
// if 60 min of an official break, try to schedule a short film | |
if ( FilmIsFound(shortFilms) &&( startNext == END_AM | |
|| Math.abs(END_AM - startNext) < 30 || startNext == END_PM | |
|| Math.abs( END_PM - startNext) < 30) ) { | |
Film t = shortFilms.get(firstElement); | |
startFilm = startNext; | |
currDuration = (Integer) t.getDuration(); | |
t.setStartTime(startFilm); | |
t.setFinishTime(startFilm + currDuration); | |
availableMinutes = availableMinutes - currDuration; | |
t.setTrackAssignment(this.programmedDay); | |
startNext = t.getFinishTime(); | |
this.OUTPUT.add(t); | |
shortFilms.remove(t); | |
this.INPUT.remove(t); | |
if ( closestBreakIsLunch ) { | |
assignLunch(); | |
startNext = START_PM; | |
} else { | |
assignNetworking(); | |
startNext = START_EVENING; | |
} | |
} else { | |
/// schedule regular Films | |
Film s = INPUT.get(firstElement); | |
currDuration = (Integer) s.getDuration(); | |
startFilm = startNext; | |
s.setStartTime(startFilm); | |
s.setTrackAssignment(this.programmedDay); | |
s.setFinishTime(startFilm + currDuration); | |
this.OUTPUT.add(s); | |
availableMinutes = availableMinutes - currDuration; | |
startNext = s.getFinishTime(); | |
this.INPUT.remove(firstElement); | |
} | |
} /// end the overarching while loop | |
String trackName = "Day - Schedule # " + this.programmedDay; | |
completedDay = new Day(trackName, this.OUTPUT); | |
return completedDay; | |
} | |
private boolean FilmIsFound(List<Film> listBeingSearched) { | |
return listBeingSearched.size() > 0; | |
} | |
private void assignLunch() { | |
Film lunch = new Film("Lunch", 60); | |
/// assign lunch | |
lunch.setStartTime(END_AM); | |
lunch.setFinishTime(START_PM); | |
this.OUTPUT.add(lunch); | |
this.INPUT.remove( lunch ); | |
} | |
private void assignNetworking() { | |
Film nw = new Film("Networking", 60); | |
/// assign lunch | |
nw.setStartTime(END_PM); | |
nw.setFinishTime(START_EVENING); | |
this.OUTPUT.add(nw); | |
this.INPUT.remove( nw ); | |
} | |
public void printSchedule(List<Film> listOfFilms) { | |
Collections.sort( listOfFilms ); | |
for (Film s : listOfFilms) { | |
System.out.println( s.toString() ); | |
} | |
} | |
@Override | |
public int compareTo(Session compareTracks) { | |
int comparison = ((Session) compareTracks).getProgrammedDay(); | |
return this.programmedDay; | |
} | |
public int getProgrammedDay() { | |
return programmedDay; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package src.main.java; | |
import java.io.File; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Scanner; | |
/** | |
* Created by nwhit8 on 10/25/15. | |
*/ | |
public class Utility { | |
/// represents full list of topics offered (180m max for AM + 240min max in PM) | |
private int count = 0; | |
private String[] linesFromFile; | |
private ArrayList<Film> sessionPool; | |
private ArrayList<Session> finalResults; | |
private String current; | |
public Utility(String fileName) { | |
this.current = fileName; | |
init(); | |
} | |
private void init() { | |
String textFromFile = ingestFile( this.current ); | |
String[] dividedText = textFromFile.split("\n"); | |
this.linesFromFile = dividedText.clone(); | |
} | |
public String ingestFile(String fileName) { | |
StringBuilder result = new StringBuilder(""); | |
ClassLoader cLoader = getClass().getClassLoader(); | |
File file = new File( cLoader.getResource( fileName).getFile() ); | |
try (Scanner scanner = new Scanner( file )) { | |
while (scanner.hasNextLine()) { | |
String nextLine = scanner.nextLine(); | |
result.append( nextLine).append("\n"); | |
} | |
scanner.close(); | |
} catch (IOException e ) { | |
e.printStackTrace(); | |
} | |
return result.toString(); | |
} | |
public List<Film> getListOfFilms() { | |
List<Film> topicList = new ArrayList<>(); | |
for (int i=0; i < linesFromFile.length; i++ ) { | |
String temp = linesFromFile[i].toString(); | |
String[] tokenArray = temp.split(" "); | |
int lastIndex = tokenArray.length - 1; | |
String durationToken = tokenArray[ lastIndex ].toString().toLowerCase(); | |
Integer duration; | |
if( durationToken.contains("lightning")) { duration = 5;} else { | |
duration = extractDurationFromString(durationToken); | |
} | |
String title = temp.replace( durationToken, ""); | |
Film topic = new Film(title,duration); | |
topicList.add( topic); | |
} | |
return topicList; | |
} | |
private Integer extractDurationFromString(String durationStr) { | |
/// default find | |
Integer foundValue = 5; | |
if( durationStr.contains("min")) { | |
String temp = durationStr.replace("min", ""); | |
foundValue = Integer.parseInt( temp); | |
} | |
return foundValue; | |
} | |
public Integer calcProgrammingTime( List<Film> inputList ) { | |
Integer programInMinutes = 0; | |
for ( Film f : inputList ) { | |
programInMinutes = programInMinutes + (Integer)f.getDuration(); | |
} | |
return programInMinutes; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Session.java class has been extended to allow scheduling up till 11:59 pm.