Programming Assignment 1
CS 33600
Network Programming
Spring, 2025
This assignment makes use of the files contained in this zip file.
This assignment is due Wednesday, January 29.
In this assignment you will use the command-line, command-line arguments, standard I/O streams, piping, environment variables, and a configuration (properties) file.
In this assignment you will write a Java filter program that formats a jumbled stream of input numbers into nicely organized columns. To determine the parameters for the output formatting your program will make use of command-line arguments, environment variables, and a configuration file. To test your program you will use the Windows command-line.
Write a Java program called Filter.java
that reads from standard input and writes to standard output. The input to your program will be a sequence of positive integers separated by random amounts of white space. The output of your program will be the input integers grouped and formatted into columns.
Here is an example of a stream of input integers (with at most seven decimal places each).
193511 87 275 62 82754 141467
8612 539 2314 8671515 134 4084420
5 72040 796329 2663250 5236 3959931
4850 722044 56 73 299 5443348
20009 79 3488428 27 51528 78401
70761 1 166520 40743 29525 4
7 338 573586 255119 442298 876
7838 145950 624561 756 55790 68
8816157 3234 4802 1838538 389 71
34 19636 6573222 27 1 6
82 408577 22055 4909020 1807 1
145345 41318 6 611 5266397 3
14 3 26 789 118 3726251
24 75271 72 4113528 4 7943
52302 374188 72 54 209 2225
Here are those integers grouped into a single group, then formatted into six columns, and printed with nine spaces between the ones places of adjacent columns.
193,511 87 275 62 82,754 141,467
8,612 539 2,314 8,671,515 134 4,084,420
5 72,040 796,329 2,663,250 5,236 3,959,931
4,850 722,044 56 73 299 5,443,348
20,009 79 3,488,428 27 51,528 78,401
70,761 1 166,520 40,743 29,525 4
7 338 573,586 255,119 442,298 876
7,838 145,950 624,561 756 55,790 68
8,816,157 3,234 4,802 1,838,538 389 71
34 19,636 6,573,222 27 1 6
82 408,577 22,055 4,909,020 1,807 1
145,345 41,318 6 611 5,266,397 3
14 3 26 789 118 3,726,251
24 75,271 72 4,113,528 4 7,943
52,302 374,188 72 54 209 2,225
On the other hand, here are those same integers grouped into groups of 12, then formatted into five columns, printed with 14 spaces between the ones places of adjacent columns, and with one blank line between two groups of integers.
193,511 87 275 62 82,754
141,467 8,612 539 2,314 8,671,515
134 4,084,420
5 72,040 796,329 2,663,250 5,236
3,959,931 4,850 722,044 56 73
299 5,443,348
20,009 79 3,488,428 27 51,528
78,401 70,761 1 166,520 40,743
29,525 4
7 338 573,586 255,119 442,298
876 7,838 145,950 624,561 756
55,790 68
8,816,157 3,234 4,802 1,838,538 389
71 34 19,636 6,573,222 27
1 6
82 408,577 22,055 4,909,020 1,807
1 145,345 41,318 6 611
5,266,397 3
14 3 26 789 118
3,726,251 24 75,271 72 4,113,528
4 7,943
52,302 374,188 72 54 209
2,225
The input integers should be "right justified" in each output column, which means that all the integers in a column will line up vertically at their ones place. Each group of integers will be separated by one blank line.
The Filter.java
program requires three parameters. One parameter determines the number of output columns. Another parameter determines the number of character spaces between the ones places of adjacent columns. And another parameter determines how many input integers get grouped together.
The next several paragraphs specify how the Filter.java
program finds a value for each of these three parameters using command-line arguments, environment variables, and a configuration file.
In Filter.java
, the default number of output columns should be three. If the properties file filter.properties
exits in the current directory, and if that properties file contains a key with the name "columns"
, and if the value of that key parses to a positive integer value, then the value of the "columns"
key overrides the default number of output columns. If there is an environment variable called CS336_COLUMNS
, and if the value of that variable parses to a positive integer value, then the value of that environment variable overrides the default number of columns and the number of columns set by the properties file (if it exits). If there is a first command-line argument, and if the value of that argument parses to a positive integer value, then that command-line argument overrides the environment variable (if there is one), the properties file (if it exits), and the default number of columns.
In Filter.java
, the default number of character spaces between the ones places of adjacent columns is 10 spaces. If the properties file filter.properties
exits in the current directory, and if that properties file contains a key with the name "spacing"
, and if the value of that key parses to a positive integer value, then the value of the "spacing"
key overrides the default spacing. If there is an environment variable called CS336_SPACING
, and if the value of that variable parses to a positive integer value, then the value of that environment variable overrides the default spacing and the spacing set by the properties file (if it exits). If there is a second command-line parameter, and if the value of that parameter parses to a positive integer value, then that command-line parameter overrides the environment variable (if there is one), the properties file (if it exits), and the default value of spacing.
The input integers should be combined into groups with the members of each group being formatted into the appropriate number of columns and with one blank line separating each group. In Filter.java
the default length of a group should be 0, which means that all the input numbers should be placed in a single group. If the properties file filter.properties
exits in the current directory, and if that properties file contains a key with the name "groups"
, and if the value of that key parses to a positive integer value, then the value of the "groups"
key overrides the default length for groups. If there is an environment variable called CS336_GROUPS
, and if the value of that variable parses to a positive integer value, then the value of that variable overrides the default group length and the group length set by the property file (if it exits). If there is a third command-line parameter, and if the value of that parameter parses to a positive integer value, then that command-line parameter overrides the environment variable (if there is one), the property file (if it exits), and the default length for groups.
To retrieve property values from the filter.properties
file (if it exists) your Filter.java
program first needs to create a Properties object. Then your program should create a File object (for the file filter.properties
) and a FileInputStream object (from the File
object) and use it to load the properties from the properties file. After the properties have been loaded into the Properties object, you use the getProperty method to see if a particular key has a value. The properties file is a text file, so the "integer" values in it are actually strings. Use the parseInt() method to convert them to int
values. If the load() method throws a FileNotFoundException, that means that the filter.properties
file does not exist, so you can go on to looking for the environment variables.
Your program should use the getenv()
method to see if there are environment variables named CS336_COLUMNS
or CS336_SPACING
or CS336_GROUPS
. If any of these environment variables exists, then its string value should be converted to an integer value by using the parseInt()
method.
Your program should get its command-line arguments by using the args
parameter to your program's main()
method. Command-line arguments, like environment variables, are always strings. So you need to use parseInt()
to convert a command-line argument into an int
value.
Your program should read the sequence of input integers from standard input by using the Scanner class methods hasNextLong()
and nextLong()
.
Your program should write formatted numbers to standard output by using the printf()
method and its associated formatting strings.
In the zip file for this assignment you will find a program called Source.java
that you can use to test your program. The program Source.java
writes to standard output a stream of random long
integers. The integers are separated by random amounts of white space and there are a random number of random integers on each line of output. You can test your Filter.java
program by piping the standard output of Source
into the standard input of your Filter
. For example,
> java Source | java Filter
The Source
program takes three optional command-line arguments. The first determines the maximum number of digits in each random integer. The second determines how many lines of output there are. The third determines how many random integers there are on each line of output. For example, the following command-line will write to standard output a stream of 1, 2, or 3 digit random integers.
> java Filter 3
Without any command-line arguments, Source
will produce a random number of output lines (up to 100) and each output line will contain a random number of integers (up to 10) and each random integer will have at most six digits.
The Source
program outputs long integers, so the maximum number of digits allowed by Source
is 19.
You can give the Filter
program command-line arguments. The following command-line will output groups of 50 integers in 8 columns with 10 spaces between the ones places.
> java Source | java Filter 8 10 50
You can set an environment variable by using the following shell command.
> set CS336_GROUPS=20
> java Source | java Filter 8 10
The previous commands used a pipe (the character '|'
). Using a pipe is equivalent to the following two commands that use I/O redirection.
> java Source > temp
> java Filter 8 10 50 < temp
The first command redirects the standard output from Source
into a temporary file called temp
and then the second command redirects the contents of temp
into the standard input of Filter
. (How would you save the resulting output from Filter
in a file called data.txt
?) The piped version of the command has the advantage of not needing a temporary file. But the redirected version of the commands have the advantage that you can reuse the same data file in multiple Filter
trials.
For example, the following command-line will produce (up to) 4 digit random integers on 5 lines with 6 integers per line.
> java Source 4 5 6
The following command-line pipes the randomly generated data directly into the Filter
process.
> java Source 4 5 6 | java Filter
The following command-line will save the randomly generated data in a file for possible use in testing the Filter
program.
> java Source 4 5 6 > myData.txt
The following command-line redirects the saved data file into the Filter
process.
> java Filter 2 6 20 < myData.txt
In the zip file for this assignment you will find an executable jar file demo program, called filter_demo.jar
, that you can use to demo this assignment. You can pipe the output from Source
into the demo program with this command-line.
> java Source 4 5 6 | java -jar filter_demo.jar 2 6 20
In the zip file for this assignment you will also find a sample properties file, filter.properties
.
In the zip file there are files data.txt
, test_filter.cmd
, and test_filter_results_correct.txt
that help you test your completed version of Filter.java
. Once you have Filter.java
written and compiled, you can double click on the file test_filter.cmd
which will run your Filter
program several times with the data from data.txt
as stdin
and gather all the results into a file called test_filter_results.txt
which you can then compare with test_filter_results_correct.txt
. Your test_filter_results.txt
file should be exactly the same as test_filter_results_correct.txt
.
In the zip file there is another test script, test_filter2.cmd
, that contains several example command-lines that your Filter
program should be able to handle properly.
Do not try to write Filter.java
all at once! Write it in stages. Break the problem down into sub-problems and solve them one at a time. For example, here is an outline of how you might go about attacking this program.
- First, get your filter to print all of the input integers in a single column with the ones places lined up in column 11 (so that there are 10 character spaces between the ones place and the left edge of the console).
- Second, create three columns of output with 10 character spaces between the ones places in each column. Be sure to take into consideration that the last row need not have three columns.
- Third, have a command-line argument determine the number of columns (still with 10 character spaces between the ones places in each column).
- Fourth, have a command-line argument determine the number of character spaces between the ones places in each column.
- Fifth, have a command-line argument determine the length of a group of numbers.
- Sixth, let environment variables determine the program's parameters.
- Last, check for the properties file (before checking for the environment variables and the command-line arguments) and, if it exits and has the correct keys, then have its values override the default values.
Make sure you test your program under a wide variety of conditions. With and without a configuration file, with and without environment variables, with and without command-line arguments.
When you want to set an environment variable from the command-line, be careful not to use a command like the following, with extra spaces around the =
.
> set CS336_COLUMNS = 7
This creates an environment variable called "CS336_COLUMNS "
(with a trailing space) and gives it the value " 7"
(with a leading space).
When you set an environment variable, it only exits in the command window where you created it. So, for example, you cannot create an environment variable in one command prompt window and then run your program from an IDE or an editor or another command prompt window.
In the zip file there are sub-folders Command-line_arguments
, Environment_variables
, and Properties_file
, with sample code that demonstrates, respectively, using command-line arguments, environment variables, and a properties file.
Here is a list of some classes and methods that you can use.
Turn in a zip file called CS336Hw1Surname.zip
(where Surname
is your last name) containing your version of Filter.java
.
This assignment is due Wednesday, January 29.