Corning Community College CSCS1730 UNIX/Linux Fundamentals ~~TOC~~ ======Project: SCRIPTING FOR FUN AND PROFIT (sfp0)====== =====Errata===== Typos and bug fixes: * (DATESTAMP) =====Objective===== Use your UNIX skills and tools at hand to enable you to solve a problem in the realm calculation (could lead to automation) =====Background===== The standard CCC fall and spring semesters are 14 weeks, with an additional week for finals, and two break weeks interspersed. A timespan of approximately 17 weeks when all is said and done. But, the break weeks do not contribute toward this 14 week total, yet could gum up the works if instructing the computer to do something during a given week of the semester. Your task for this project is to come up with a script to determine the current week of a semester, when given the following information: * name of the semester * starting date of the semester * ending date of the semester * list of days when classes do not meet (including weekends when associated with a break week) * day to check for the semester week This **calcweek** script should operate as follows: * if given no arguments, assume the current date and display the appropriate week of the semester (you may hardcode it to assume the current semester) * alternatively, I would aware bonus points to logic trying to auto detect the semester. * if given one argument, assume it is a semester, and assume the current date and display the appropriate week of that semester * if given two arguments, assume the first is a semester, and the second is a specific date, and display the appropriate week of that semester * if the date precedes the semester, output a week of 0 * if the date exceeds the semester, output a week of 16 * any date provided should be assumed relative to the same year as the semester being evaluated * the script should reference the appropriate configuration file for the semester it is processing (config files provided in **sfp0/** subdirectory of UNIX Public Directory) * the configuration files contain the pertinent days (in bash variable assignment form) of the given semester. * using the **source** command, you can "load" these variables right into your script * note that these config files are the same ones used by my **gn** script; as such, for your purposes there is likely to be a lot of superfluous information you will not need to pay attention to (but you are welcome to use whatever variables are provided to assist you). * if the day you are checking falls in a break week, you may choose how to react. Typically, you'd want one of: * display "break week" * display the number of the previous week (break weeks do not "exist" in this sense) * display the number of the next week (similar, just from the opposite end) * also, a break week is defined as a range of 5 or more days. Single days off do not constitute breaks, and do not impact the week calculation. * this is so that holidays (labor day) and snow days do not muck up the works =====semester configuration files===== I have given you copies of configuration files for the following semesters, all located in the **sfp0/** subdirectory of the UNIX Public Directory: * spring2015.conf * summer2015.conf * fall2015.conf * spring2016.conf ====fall2015==== As an example, the fall2015 configuration file will appear as follows: SEMESTER=fall2015 SEMESTER_START=236 # absolute day of year (1-365) that semester starts SEMESTER_END=353 # absolute day of year (1-365) that semester ends EARLY_ALERTS=256 WARNING_GRADES=284 DROP_DATE=305 STARTWEEK=34 ENDWEEK=50 BREAK[0]=250 # start day when classes do not meet (absolute day) -- labor day BREAK[1]=250 # end day when classes do not meet (absolute day) -- labor day BREAK[2]=284 # start day when classes do not meet -- october break BREAK[3]=291 # end day when classes do not meet -- october break BREAK[4]=326 # start day when classes do not meet -- november break BREAK[4]=333 # end day when classes do not meet -- november break BREAKLIST="250 250 284 291 326 333" BREAKDAYS="250 284 285 286 287 288 289 290 291 326 327 328 329 330 331 332 333 " You'll see some of that information repeated in other places.. if you find one form more preferable than another, feel free to make use of it (that's why I provided all the information I use when doing similar operations). =====Hints===== The process this script implements is not a difficult one, although if you're not careful you can become mired in unnecessary complexity. First order of business: * make sure you can do this by hand * try a few examples, write out the steps you take to figure out the appropriate week * if you cannot do it manually, it'll be rather difficult to tell the computer how to do it Once you can work it out: * work it out, step by step, on the command line * focus on the steps being taken, how does one command (and its results) lead to the next? * the script will likely make use of variables, so keep that in mind ====absolute days==== I use absolute days in my date calculations, because dates are so computationally awkward in their usual for (11/03/2015, 20151031). For example... if we had a datestring like: 20151019 and we wanted to advance it to the next day... we could increment it by one: 20151019+1 = 20151020 and this process works from the first of the month through the 31st: 20151020+1 = 20151021 20151021+1 = 20151022 20151022+1 = 20151023 20151023+1 = 20151024 20151024+1 = 20151025 20151025+1 = 20151026 20151026+1 = 20151027 20151027+1 = 20151028 20151028+1 = 20151029 20151029+1 = 20151030 20151030+1 = 20151031 20151031+1 = 20151032 But, you'll see something undesirable occur when we try to get the 'next day' after october 31st. 20151032 is not a valid day. Put simply, our notion of dates encoded in years, months, days is not very computationally friendly. So what do you do when faced with such things? Find a better way to encode it! And that's why I'm using absolute days (day 1-365)... it conveniently ignores things like months and days of months, allowing for a seamless sequence of days in a given year. You may want to utilize absolute days in your processing to facilitate things. ===get absolute day=== So, how do we get the absolute day? We can use the **date**(**1**) command. First, get the current day: lab46:~$ date Tue Nov 3 03:16:27 EST 2015 lab46:~$ Now, see its absolute day equivalent: lab46:~$ date +%j 307 lab46:~$ That should make sense... it is the beginning of November... we've got this month and all of next month to go (Dec 31st is day 365)... so quick confirming math: * 30-3 = 27 days to go in November * 31 days in December * 27+31 = 58 days left in the year * 365-58 = 307 And what if we wanted to get the absolute day of a day that isn't today? lab46:~$ date -d '10/26/2015' +%j 299 lab46:~$ ====command-line arguments==== What about these command-line arguments being used? bash assigns arguments to the following variables: * $0 - name of the script * $1 - first argument * $2 - second argument * $3 - third argument (goes through 9) * $* - all arguments * $# - number of arguments You can check for arguments and react accordingly in **if** statements. An example script to visualize command-line arguments and their use: #!/bin/bash echo "This script (${0}) was called with ${#} arguments." echo "They are: ${*}" echo "Broken apart they are:" echo " \$0: ${0}" count=1 while [ ! -z "${1}" ]; do echo " \$${count}: ${1}" shift let count=${count}+1 done exit 0 NOTE: That is a #1 (one) in the braces. Not to be confused with 'i' (eye). Run the above script with arguments, it should output like this: lab46:~/src/unix/sfp0$ ./myargs a bc def "taco cat" This script (unix/cli) was called with 4 arguments. They are: a bc def taco cat Broken apart they are: $0: ./myargs $1: a $2: bc $3: def $4: taco cat lab46:~/src/unix/sfp0$ =====Useful tools===== There are many tools which you could find useful in performing this project. Some off the top of my head include: * **date**(**1**) - especially the '**%j**', '**%W**' format specifiers, and **-d** argument * **cal**(**1**) - if only for visualizing things as you work through the logic * **cut**(**1**) * **grep**(**1**) =====Submission===== Successful completion will result in the following criteria being met: * script completed and submitted by the deadline (25% late penalty per day afterwards) * script is appropriately shabanged (bash) * script is adequately commented * some attempt at readability, organization, indentation is made * script operates according to specifications above ====Submit==== Please submit as follows: lab46:~/src/unix/sfp0$ submit unix sfp0 calcweek.sh Submitting unix project "sfp0": -> calcweek.sh(OK) SUCCESSFULLY SUBMITTED lab46:~/src/unix/sfp0$