commit 9e458e87098ae3098876e299781b30871ca5faa4 Author: Matthew Jensen Date: Fri Dec 13 13:52:23 2019 -0800 add calendar assignment from WCC CS 141 Winter 2019. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f0929b --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + diff --git a/README.md b/README.md new file mode 100644 index 0000000..8f6cfd3 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# Topics: +File I/o (input / output), Arrays + +## Learning Outcomes: + +- Practice Reading in files to java and processing file text content +- Become comfortable with using arrays to store and retrieve data +- Design and develop programs in accepted style +- Develop further the ability to enhance a program to increase functionality +- Execute the proper steps to write out desired content to a file diff --git a/calendar/Assignment3.java b/calendar/Assignment3.java new file mode 100644 index 0000000..82282ac --- /dev/null +++ b/calendar/Assignment3.java @@ -0,0 +1,495 @@ +/** +* +* Matt Jensen +* 3/20/19 +* +* Draws a basic calendar to the console. +* Calendar is scalable with a class constant. +* = and | characters are used for the boundary of the calendar. +* +*/ + +import java.util.*; // uses scanner +import java.io.*; // uses file + +public class Assignment3 { + + public static final String[][] EVENTS = new String[12][]; + public static final String[] OPTIONS = {"e", "t", "n", "p", "q", "ev", "fp"}; + public static final String[] OPTION_DESC = { + "to enter a date and display the corresponding calendar", + "to get todays date and display the today's calendar", + "to display the next month", + "to display the previous month", + "to quit the program", + "event mode", + "file print mode", + }; + + /** + * + * The width of a single cell of the calendar. + * + */ + public static final int CELL_WIDTH = 10; + + /** + * + * Prompts user for a date input on the console. + * Parses input of the form "mm/dd". + * Displays month in the top of output. + * Displays mm and dd separately at the bottom. + * Displays the month associated with input. + * Displays current month in same format below. + * + */ + public static void main(String [] args) { + Scanner console = new Scanner(System.in); + int month, day = 1; + int currentYear, newYear = 0; + Calendar date = Calendar.getInstance(); + setEventYear(date.get(Calendar.YEAR)); + currentYear = date.get(Calendar.YEAR); + + String option = promptForOption(console); + while( ! option.equals("q") ) { + //"to enter a date and display the corresponding calendar", + //"to display the previous month", + if( option.equals("ev") ) { + String eventLine = promptForEvent(console); + addEvent(eventFromLine(eventLine)); + } + else if(option.equals("fp") ) { + File file = promptForFile(console); + try{ + PrintStream out = new PrintStream(file); + String dateLine = promptForDateLine(console); + month = monthFromLine(dateLine); + day = dayFromLine(dateLine); + date.set(Calendar.getInstance().get(Calendar.YEAR), month, day); + drawCalendar(date, out); // draw the month + out.close(); + } + catch(FileNotFoundException error) { + continue; + } + } + else { + if(option.equals("e") ) { + String dateLine = promptForDateLine(console); + // input + month = monthFromLine(dateLine); + day = dayFromLine(dateLine); + date.set(Calendar.getInstance().get(Calendar.YEAR), month, day); + } + //"to get todays date and display the today's calendar", + if( option.equals("t") ) { + // current + date = Calendar.getInstance(); + } + //"to display the next month", + if( option.equals("n") ) { + date.add(Calendar.MONTH, 1); + } + //"to display the previous month", + if(option.equals("p") ) { + date.add(Calendar.MONTH, -1); + } + newYear = date.get(Calendar.YEAR); + if(newYear != currentYear) { + setEventYear(newYear); + } + + drawCalendar(date, System.out); // draw the month + } + option = promptForOption(console); + } + } + + // read in a file of events if they exists + public static void loadEventsFile() { + File eventFile = new File("calendarEvents.txt"); + if( ! eventFile.exists()) { + return; + } + try { + Scanner fileScanner = new Scanner(eventFile); + while( fileScanner.hasNextLine() ) { + String eventLine = fileScanner.nextLine(); + addEvent(eventFromLine(eventLine)); + } + } + catch(FileNotFoundException notFound){ + return; + } + } + + // prompt loop for file name of file to print to + public static File promptForFile(Scanner console){ + System.out.println("What filename? (example.txt)"); + System.out.println(); + String input = console.next(); + File file = new File(input); + return file; + } + + // prompt loop for a (mm/dd) date input + public static String promptForDateLine(Scanner console){ + System.out.println("What date would you like displayed? (mm/dd)"); + System.out.println(); + String input = console.next(); + while( ! validDateInput(input) ) { + System.out.println("Try again."); + System.out.println("What date would you like displayed? (mm/dd)"); + input = console.next(); + } + return input; + } + + // event name of given calendar date + public static String getEventForDate(Calendar date) { + int month = date.get(Calendar.MONTH); + int day = date.get(Calendar.DAY_OF_MONTH) - 1; + String eventName = EVENTS[month][day]; + if(eventName == null) { + return ""; + } + return eventName; + } + /** + * + * extract an event name from line + * + * @param eventLine mm/dd event_name parsing. + * @return month day substring of the given date. + * + */ + public static String[] eventFromLine(String line) { + Scanner scanner = new Scanner(line); + String month = Integer.toString(monthFromLine(line)); + String day = Integer.toString(dayFromLine(line)); + String rawDate = scanner.next(); + String name = scanner.next(); + String[] event = {month, day, name}; + return event; + } + + // add event name to multi dem. class array of events + public static void addEvent(String[] event) { + int month = Integer.parseInt(event[0]); + int day = Integer.parseInt(event[1]) - 1; + String name = event[2]; + EVENTS[month][day] = name; + } + + // is the event line valid? + public static boolean validEventInput(String input) { + if( ! validDateInput(input) ) { + System.out.println("Error: Bad date."); + return false; + } + Scanner scanner = new Scanner(input); + String rawDate = scanner.next(); + if( ! scanner.hasNext() ) { + System.out.println("Error: No event."); + return false; + } + return true; + } + + // regenerate EVENTS with new day quantities. + // reloads events file automatically. + public static void setEventYear(int year){ + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, year); + cal.set(Calendar.MONTH, 1); + cal.set(Calendar.DAY_OF_MONTH, 1); + String[][] clone = EVENTS.clone(); + //TODO: copy events to new year + for(int i = 0; i < 12; i++) { + EVENTS[i] = new String[cal.getMaximum(Calendar.DAY_OF_MONTH)]; + } + loadEventsFile(); + } + + // prompt loop for events + public static String promptForEvent(Scanner console) { + System.out.println("Please type an event (mm/dd event_name)"); + System.out.println(); + + String input = console.next() + " " + console.next(); + while( ! validEventInput(input) ) { + System.out.println("Try again."); + System.out.println("Please type an event (mm/dd event_name)"); + input = console.next() + " " + console.next(); + } + return input; + } + + // prompt loop for options + public static String promptForOption(Scanner console) { + System.out.println("Please type a command"); + printOptions(); + String input = console.next(); + while( ! validInput(input) ) { + System.out.println("Please enter a valid command"); + System.out.println("Please type a command"); + printOptions(); + input = console.next(); + System.out.println(); + } + return input.toLowerCase(); + } + + // valid date line input? + public static boolean validDateInput(String input) { + Scanner scanner = new Scanner(input); + + if( ! scanner.hasNext() ) { + System.out.println("Error: No Date Detected"); + return false; + } + String rawDate = scanner.next(); + scanner = new Scanner(rawDate.replace('/', ' ')); + if( ! scanner.hasNextInt() ) { + System.out.println("Error: No Month"); + return false; + } + int month = scanner.nextInt(); + + if( ! scanner.hasNextInt() ) { + System.out.println("Error: No Day"); + return false; + } + int day = scanner.nextInt(); + + if(month > 12 || month < 1 || day < 1 || day > 31) { + System.out.println("Error: Date out of bounds"); + return false; + } + return true; + } + + // prints the available options array + public static void printOptions() { + for(int i = 0; i < OPTIONS.length; i++) { + System.out.println("\"" + OPTIONS[i] + "\" " + OPTION_DESC[i]); + } + } + + // valid option input? + public static boolean validInput(String input) { + String option = input.toLowerCase(); + String regex = "(" + String.join("|", OPTIONS) + ").*"; + //System.out.println(regex); + if( option.matches(regex) ) { + return true; + } + return false; + } + + + /** + * + * draws a given month + * + * @param date which date + * @param out where to print + * @return void + * + */ + public static void drawCalendar(Calendar date, PrintStream out) { + + out.println(); + out.printf("Month: %-" + (calendarWidth() - 8) + "s\n", date.get(Calendar.MONTH) + 1); + + // rows + drawDivider('=', out); + drawHeader(out); + drawDivider('=', out); + Calendar firstDay = (Calendar) date.clone(); + firstDay.set(Calendar.WEEK_OF_MONTH, 1); + firstDay.set(Calendar.DAY_OF_WEEK, 1); + for(int weekNumber = 0; weekNumber < date.getActualMaximum(Calendar.WEEK_OF_MONTH); weekNumber++) { + drawWeekStartingOn(firstDay, date, out); + drawDivider('-', out); + firstDay.add(Calendar.DAY_OF_MONTH, 7); + } + + out.println(); + int month = date.get(Calendar.MONTH); + int day = date.get(Calendar.DAY_OF_MONTH); + drawDate(month, day, out); // display date + } + + // calculated the total width of the calendar. + public static int calendarWidth() { + int totalWidth = CELL_WIDTH * 7; + return totalWidth; + } + + /** + * + * draws a single row of the calenday to console. + * + * @param row the row number to print. + * @return void + * + */ + public static void drawWeekStartingOn(Calendar firstDayOfWeek, Calendar date, PrintStream out) { + Calendar currentDate = (Calendar) firstDayOfWeek.clone(); + Calendar lastDayOfWeek = (Calendar) firstDayOfWeek.clone(); + lastDayOfWeek.add(Calendar.DAY_OF_MONTH, 6); + while(! currentDate.after(lastDayOfWeek)) { + int day = currentDate.get(Calendar.DAY_OF_MONTH); + String content = ""; + if( currentDate.get(Calendar.MONTH) == date.get(Calendar.MONTH)) { // valid dates only + if(currentDate.equals(date)) { + content += "*"; + } + content += day; + } + out.print("|"); + out.printf("%" + (CELL_WIDTH - 1) + "s", content); + currentDate.add(Calendar.DAY_OF_MONTH, 1); + } + out.println("|"); + + for(int i = 0; i < CELL_WIDTH / 2; i++) { + currentDate = (Calendar) firstDayOfWeek.clone(); + while(! currentDate.after(lastDayOfWeek)) { + String content = ""; + if(i == 0) { + String eventName = getEventForDate(currentDate); + content += eventName; + if (content.length() > CELL_WIDTH) { + content = content.substring(0, CELL_WIDTH - 4) + "..."; + } + } + out.print("|"); + out.printf("%" + (CELL_WIDTH - 1) + "s", content); + currentDate.add(Calendar.DAY_OF_MONTH, 1); + } + out.println("|"); + } + } + + + // draws divider with given char + public static void drawDivider(char character, PrintStream out) { + out.print(' '); + for(int i = 0; i < calendarWidth() - 1; i++) { + out.print(character); + } + out.println(); + } + + // draws day names + public static void drawHeader(PrintStream out) { + String[] strDays = new String[] { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" }; + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); + while(cal.get(Calendar.DAY_OF_WEEK) < 7) { + out.printf("| %-" + (CELL_WIDTH - 2) + "s", strDays[cal.get(Calendar.DAY_OF_WEEK) - 1 ]); + cal.add(Calendar.DAY_OF_WEEK, 1); + } + out.printf("| %-" + (CELL_WIDTH - 2) + "s|\n", strDays[cal.get(Calendar.DAY_OF_WEEK) - 1 ]); + + } + + /** + * + * prints the month and date on two separate lines. + * + * @param month month for printing. + * @param day day for printing. + * @return void + * + */ + public static void drawDate(int month, int day, PrintStream out) { + out.printf("Month: %" + CELL_WIDTH +"s\n", month + 1); + out.printf("Day: %" + CELL_WIDTH +"s\n", day); + } + + /** + * + * extract an integer value for the month from a given string. + * + * @param date date string of the form mm/dd. + * @return month month substring of the given date. + * + */ + public static int monthFromLine(String line) { + Scanner scanner = new Scanner(line.replace('/', ' ')); + int month = scanner.nextInt(); + return month - 1; + } + + /** + * + * extract an integer value for the day from a given string. + * + * @param date date string of the form mm/dd. + * @return month day substring of the given date. + * + */ + public static int dayFromLine(String line) { + Scanner scanner = new Scanner(line.replace('/', ' ')); + int month = scanner.nextInt(); + int day = scanner.nextInt(); + return day; + } + + + /** + * + * draws ASCII art preamble of the calendar + * + * @return void + * + */ + public static void drawArt() { + int calHeight = 7 * CELL_WIDTH; + //top + printChar('_', calHeight); + + //sun + System.out.println(); + System.out.print(" "); + printChar('_', calHeight/4); + System.out.println(" "); + for(int i = 0; i < calHeight/10; i++) { + System.out.print("|"); + printChar(' ', calHeight/4); + System.out.println("|"); + } + System.out.print("|"); + printChar('_', calHeight/4); + System.out.println("|"); + + + //beam + System.out.println(); + for(int line = 0; line < calHeight/ 3; line++) { + printChar(' ', line / 2); + System.out.print("\\"); + printChar('\\', line / 2); + printChar(' ', line / 2); + System.out.println(); + } + + //windows + printChar('_', calHeight); + System.out.println(); + System.out.println(); + + //banner + //wheels + } + + public static void printChar(char character, int count) { + for(int i = 0; i < count; i++) { + System.out.print(character); + } + } +} diff --git a/calendar/calendarEvents.txt b/calendar/calendarEvents.txt new file mode 100644 index 0000000..bec0d5c --- /dev/null +++ b/calendar/calendarEvents.txt @@ -0,0 +1,10 @@ +01/01 New_Year's_Day +01/15 Martin_Luther_King,_Jr._Day +02/19 President's_Day +05/28 Memorial_Day +07/04 Independence_Day +09/03 Labor_Day +10/08 Columbus_Day +11/12 Veterans_Day +11/22 Thanksgiving_Day +12/25 Christmas_Day diff --git a/calendar/specification.pdf b/calendar/specification.pdf new file mode 100644 index 0000000..f737e5a Binary files /dev/null and b/calendar/specification.pdf differ